E2 Laboratory 08


Overview of this week's lab.

The purpose of this lab is to practivce your programming skills, and to gain familiarity with the neopixel. Hook up the Neopixel ring to your board by attaching the wires in the following order:

  1. Attach the black (ground) wire to GND.
  2. Attach the red (power) wire to 5V
  3. Attach the yellow (data in) wire to digital pin 6.

 

Code 1: Some preliminaries

Load the following code onto your arduino and run it. You should be able to explain the behavior. The code can be found in Code 1.ino.

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define NUMPIXEL 24

short int brt[] = {0, 1, 2, 3, 5, 9, 16, 28, 48, 84, 147, 255};
#define NBRT 12

// You needn't comment the next line.
Adafruit_NeoPixel myNeo = Adafruit_NeoPixel(NUMPIXEL, PIN, NEO_GRB + NEO_KHZ800);
int i;

void setup() {
      myNeo.begin();  
//      myNeo.setBrightness(25);  // Reduce brightness of ring.
}

void loop() {
  for (i=0; i<NUMPIXEL; i++) {
    myNeo.setPixelColor(i,random(0,256),random(0,256),random(0,256));
//    myNeo.setPixelColor(i,brt[random(0,NBRT)],brt[random(0,NBRT)],brt[random(0,NBRT)]);
  }
  myNeo.show();
  delay(250);
}

Note that the LED's seem, generally, quite bright. Now move the comment marks s so that the the two lines in the loop look like the following. Rerun the code and explain the difference in appearance of the LED's.

//    myNeo.setPixelColor(i,random(0,256),random(0,256),random(0,256)); 
   myNeo.setPixelColor(i,brt[random(0,NBRT)],brt[random(0,NBRT)],brt[random(0,NBRT)]);

Now move the "myNeo.show()" and "delay(250)" lines into the for loop, rerun the code and explain the change in behavior. Now remove the comment from the start of the line with the "setBrightness" command, and rerun.

Note: you have to comment this code for the lab report, so make sure you understand how it works. (See end of this page for information about what to include in the report).


Code 2: Color wheel vs RGB

Load the following code onto your arduino and run it. The code uses a function you haven't seen before called "Wheel(x)". You give it an input argument from 0 to 255 and it uses this to calculate a color on the color wheel. If x=0, the color is green. As you increase x the color gets less green than more red.. then goes through blue, ... and back to green as x=255. Run it and observe. You don't need to understand how the "Wheel()" function works. You haven't seen the data type called uint32_t, don't worry about what it is right now - it is a type of integer we will talk about in class on Friday. The code can be found in Code_2.ino.

#include 

#define PIN 6
#define NUMPIXEL 12

short int brt[] = {0, 1, 2, 3, 5, 9, 16, 28, 48, 84, 147, 255};
#define NBRT 12

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXEL, PIN, NEO_GRB + NEO_KHZ800);
int i=0;

uint32_t rgbEquiv;

void setup() {
  strip.begin();
  strip.setBrightness(25);  // Lower brightness and save eyeballs!
  strip.show(); // Initialize all pixels to 'off'}
}

void loop() {
    i++;;  // incremente i
    rgbEquiv = Wheel((i % NUMPIXEL) * 255/ NUMPIXEL);
//    rgbEquiv = Wheel((i % (NUMPIXEL+1)) * 255/ (NUMPIXEL+1));
    strip.setPixelColor(i % NUMPIXEL, rgbEquiv);
    strip.show();
    delay(50);
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  //  return strip.Color(128,0,128);
  if (WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

Now move the comment marks so that the the two lines in the loop look like the following. Rerun the code and explain the difference in appearance of the LED's.

//    rgbEquiv = Wheel((i % NUMPIXEL) * 255/ NUMPIXEL);
    rgbEquiv = Wheel((i % (NUMPIXEL+1)) * 255/ (NUMPIXEL+1));

Code 3: Big Program

Load the following code onto your arduino and run it. You will be responsible for commenting all of the code (except for the time from 50 to 70 seconds). The lab report is due next Thursday. On Wednesday we will go over the code in class, and you will be responsible for explaining one section of code to the rest of the class. If you are having trouble understanding your section please come see me before Wednesday (i.e., Monday or Tuesday). The code can be found in Code_3.ino.

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define NUMPIXEL 12
#define WAIT 100          // mS
#define MODETIME 10       // Seconds

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXEL, PIN, NEO_GRB + NEO_KHZ800);

int i = 0, j = 0, k = 0, incr = 1;
int wHead = 0, wLen = 0, tailGrows = 0;

unsigned long timeBegin, timeNow, timeElapsed;

// Define the rainbow.
byte rLED[] = {  0,  64, 128, 192, 255, 192, 128,  64,   0,   0,   0,   0};
byte gLED[] = {255, 192, 129,  64,   0,   0,   0,   0,   0,  64, 128, 192};
byte bLED[] = {  0,  0,    0,   0,   0,  64, 128, 192, 255, 192, 129,  63};


void setup() {
  strip.begin();
  strip.setBrightness(33); //adjust brightness here
  strip.show(); // Initialize all pixels to 'off'
  timeBegin = millis();
}

void loop() {
  // Some example procedures showing how to display to the pixels:
  timeNow = millis();
  timeElapsed = timeNow - timeBegin;
  if ((timeElapsed / 1000) < MODETIME) {
    showRainbow();
  }

  else if  ((timeElapsed / 1000) < 2 * MODETIME) {
    i = (i + 1) % NUMPIXEL;
    fillColor(rLED[i], gLED[i], bLED[i]);
  }

  else  if ((timeElapsed / 1000) < 3 * MODETIME) {
    fade(k);
    if (k <= 0) {
      incr = 1;
    } else if (k >= 16) {
      incr = -1;
    }
    k = k + incr;;
  }

  else  if ((timeElapsed / 1000) < 4 * MODETIME) {
    showWithOffset(j);
    j++;
  }

  else  if ((timeElapsed / 1000) < 5 * MODETIME) {
    showWithOffset(j);
    j--;
  }
  
  // You needn't comment the following block.
  else  if ((timeElapsed / 1000) < 6 * MODETIME) {
    // For times greater between 50 and 60 seconds, show a comet.
    span(i, 5);
    i = (i + 1) % NUMPIXEL;
  }

  // You needn't comment the following block.
  else  if ((timeElapsed / 1000) < 7 * MODETIME) {
    // For times greater between 60 and 70 seconds, emulate the Chrome "Delay wheel"
    wHead = (wHead + 1) % NUMPIXEL;  // Move head of wheel
    if (tailGrows) {            // Tail grows at same speed as head moves.
      wLen++;                   // Make tail longer
      if (wLen >= NUMPIXEL) {   // If tail is the whole circle, start decreasing it.
        tailGrows = 0;
      }
    }
    else {
      wLen--;                 // Tail gets shorter
      if (wLen <= 2) {        // If tail is very short, start making longer.
        tailGrows = 1;
      }
    }
    span(wHead, wLen);
  }

  else {
    timeBegin = timeNow;  // restart
  }
}

void showRainbow() {
  int i;
  for (i = 0; i < NUMPIXEL; i++) {
    strip.setPixelColor(i, rLED[i], gLED[i], bLED[i]);
    strip.show();
    delay(WAIT);
  }
}

void showWithOffset(int offset) {
  int i;
  for (i = 0; i < NUMPIXEL; i++) {
    strip.setPixelColor((i + offset) % NUMPIXEL, rLED[i], gLED[i], bLED[i]);
  }
  strip.show();
  delay(WAIT);
}

void fillColor(int r, int g, int b) {
  for (int i = 0; i < NUMPIXEL; i++) {
    strip.setPixelColor(i, r, g, b);
  }
  strip.show();
  delay(WAIT);

}

void fade(int j) {
  int fadeLevel = pow(1.414, j);
  for (i = 0; i < NUMPIXEL; i++) {
    strip.setPixelColor(i, rLED[i] / fadeLevel, gLED[i] / fadeLevel, bLED[i] / fadeLevel);
  }
  strip.show();
  delay(WAIT);
}

// You needn't comment the following function.
void span(int begLED, int numLED) {
  for (int i = 0; i < NUMPIXEL; i++) {
    strip.setPixelColor(i, 0, 0, 0);
  }
  for (int i = 0; i < numLED; i++) {
    strip.setPixelColor(circMod(begLED - i, NUMPIXEL), 0, 0, 255 / pow(1.2, i));
  }
  strip.show();
  delay(WAIT);
}


/*
   I wanted a function that would give a cyclical iteration of numbers from 0 to (n-1)
   (like the "%" operator, but I wanted it to continue the cycle even for negative numbers.
   The examples below show the result of "x%n" (where n=3), which can give negative values
   for negative values of x.
   Also shown is the result of the circMod(x,n) function that always gives positive
   results, and whose cycles from 0 to n-1
   -5 % 3 = -2                 circMod(-5,3) = 1
   -4 % 3 = -1                 circMod(-4,3) = 2
   -3 % 3 =  0                 circMod(-3,3) = 0
   -2 % 3 =  0                 circMod(-2,3) = 0
   -1 % 3 = -1                 circMod(-1,3) = 2
    0 % 3 =  0                 circMod(0,3) = 0
    1 % 3 =  1                 circMod(1,3) = 1
    2 % 3 =  2                 circMod(2,3) = 2
    3 % 3 =  0                 circMod(3,3) = 0
    4 % 3 =  1                 circMod(4,3) = 1
    4 % 5 =  2                 circMod(5,3) = 2
*/
int circMod(int x, int m) {
  return ((x % m + m) % m); // If the result of x%m is negative, make it positive.
}

To turn in:

Code 1:

Code 2:

Code 3: