Coding examples and challenges

official

#21

Awesome! I was thinking of doing something similar, but you beat me to it :slight_smile:


#22

Here’s one called explosion. The colors radiate out from center of each face, then the color intensity increases till the cube "explodes.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

const uint8_t numFaces = 6;
const uint8_t numRows = 4;
const uint8_t numCols = 4;

// these variables are not required, just added to reduce computations
const uint8_t numPixelsPerFace = numRows * numCols;
const uint16_t numPixels = numFaces * numPixelsPerFace;

uint8_t wait(1000);
uint8_t shortWait(100);
const uint16_t maxIntensity(255);
const uint16_t startIntensity(25);

// pixel positions for pattern
const uint8_t numPixelsPerOuter(12);
const uint8_t numPixelsPerInner(4);
uint8_t outerPixels[] = {0,1,2,3,4,7,8,11,12,13,14,15};
uint8_t innerPixels[] = {5,6,9,10};

Adafruit_NeoPixel thimbleCube = Adafruit_NeoPixel(numPixels, PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  thimbleCube.begin();
  thimbleCube.show(); // Initialize all pixels to 'off'
  randomSeed(analogRead(0));
}

void loop()
{
  uint16_t intensity(startIntensity);
  uint16_t pixelOffset(0);
  uint16_t redIntensity(random(0, intensity));
  uint16_t greenIntensity(random(0, intensity));
  uint16_t blueIntensity(random(0, intensity));
  uint32_t currentColor = thimbleCube.Color(redIntensity, greenIntensity, blueIntensity);
  for (uint8_t face = 0; face < numFaces; ++face)
  {
    pixelOffset = face * numPixelsPerFace;
    for (uint8_t inner = 0; inner < numPixelsPerInner; ++inner)
    {
      thimbleCube.setPixelColor(pixelOffset + innerPixels[inner], currentColor);
    }
  }
  thimbleCube.show();
  delay(wait);
  for (uint8_t face = 0; face < numFaces; ++face)
  {
    pixelOffset = face * numPixelsPerFace;
    for (uint8_t outer = 0; outer < numPixelsPerOuter; ++outer)
    {
      thimbleCube.setPixelColor(pixelOffset + outerPixels[outer], currentColor);        
    }
  }
  thimbleCube.show();
  delay(wait);   
  
  while (redIntensity < maxIntensity && greenIntensity < maxIntensity && blueIntensity < maxIntensity)
  {
    redIntensity *= 1.2;
    greenIntensity *= 1.2;
    blueIntensity *= 1.2;
    currentColor = thimbleCube.Color(redIntensity, greenIntensity, blueIntensity);
    paintCube(currentColor);
    delay(shortWait);
    paintCube(0);
  }
  delay(shortWait);

  intensity = maxIntensity;
  paintCube(thimbleCube.Color(intensity,intensity,intensity));
  delay(shortWait);
  paintCube(0);
  delay(shortWait);
  intensity /= 3;
  paintCube(thimbleCube.Color(intensity,intensity,intensity));
  delay(shortWait);
  paintCube(0);
  delay(shortWait);
  intensity /= 3;
  paintCube(thimbleCube.Color(intensity,intensity,intensity));
  delay(shortWait);

  // now twinkle
  uint32_t color = thimbleCube.Color(2,2,2);
  paintCube(0);
  delay(shortWait);
  paintCube(color);
  delay(shortWait);
  paintCube(0);
  delay(shortWait);
  paintCube(color);
  delay(shortWait);
  paintCube(0);
  delay(wait * 4);
}

void paintCube(uint32_t color)
{
  for (uint8_t pixel = 0; pixel < numPixels; ++pixel)
  {
    thimbleCube.setPixelColor(pixel, color);
  }
  thimbleCube.show();
}

#23

Really cool!


#24

@Grandpa This can get stuck if any of the red/green/blueIntensity variables randomly start at 0. The *=1.2 will not increase it, so that while loop while never exhaust.


#25

Good catch. I just noticed that my cube was stuck after many cycles. I just changed the initial color settings to be between 1 and intensity.

  uint16_t redIntensity(random(1, intensity));
  uint16_t greenIntensity(random(1, intensity));
  uint16_t blueIntensity(random(1, intensity));

#26

Another problem is using ints (uint16_t) for the intensity variables and multiplying by 1.2 to increase. If the intensities randomize to start at 1, they’ll never change from 1, right?


#27

That’s what caused the hangups - I noticed the intensity was very low when my cube hung. It wasn’t the while statement conditional - the “&&” operator is the short circuit AND. It exits the loop on the first of any of the three conditionals being false.

I added code to handle any of the RGB intensities being less than 5, since 5 * 1.2 = 6.0, but 4 * 1.2 = 4.8 which trunc to 4.

I also noticed I was using an 8 bit integer for the wait variable - not good for more than a quarter second. Here’s the amended sketch.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN 6

const uint8_t numFaces = 6;
const uint8_t numRows = 4;
const uint8_t numCols = 4;

// these variables are not required, just added to reduce computations
const uint8_t numPixelsPerFace = numRows * numCols;
const uint16_t numPixels = numFaces * numPixelsPerFace;

uint16_t wait(500);
uint16_t shortWait(100);
const uint8_t maxIntensity(255);
const uint8_t startIntensity(25);

// pixel positions for pattern
const uint8_t numPixelsPerOuter(12);
const uint8_t numPixelsPerInner(4);
uint8_t outerPixels[] = {0,1,2,3,4,7,8,11,12,13,14,15};
uint8_t innerPixels[] = {5,6,9,10};

Adafruit_NeoPixel thimbleCube = Adafruit_NeoPixel(numPixels, PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  thimbleCube.begin();
  thimbleCube.show(); // Initialize all pixels to 'off'
  randomSeed(analogRead(0));
}

void loop()
{
  uint16_t pixelOffset(0);
  uint16_t redIntensity(random(0, startIntensity));
  uint16_t greenIntensity(random(0, startIntensity));
  uint16_t blueIntensity(random(0, startIntensity));
  while (redIntensity == 0 && greenIntensity == 0 && blueIntensity ==0)
  {
    redIntensity = random(0, startIntensity);
    greenIntensity = random(0, startIntensity);
    blueIntensity = random(0, startIntensity);
  }
  uint32_t currentColor = thimbleCube.Color(redIntensity, greenIntensity, blueIntensity);
  for (uint8_t face = 0; face < numFaces; ++face)
  {
    pixelOffset = face * numPixelsPerFace;
    for (uint8_t inner = 0; inner < numPixelsPerInner; ++inner)
    {
      thimbleCube.setPixelColor(pixelOffset + innerPixels[inner], currentColor);
    }
  }
  thimbleCube.show();
  delay(wait);
  for (uint8_t face = 0; face < numFaces; ++face)
  {
    pixelOffset = face * numPixelsPerFace;
    for (uint8_t outer = 0; outer < numPixelsPerOuter; ++outer)
    {
      thimbleCube.setPixelColor(pixelOffset + outerPixels[outer], currentColor);        
    }
  }
  thimbleCube.show();
  delay(wait);   
  
  while (redIntensity < maxIntensity && greenIntensity < maxIntensity && blueIntensity < maxIntensity)
  {
    // need to insure integer truncation after multiplying by 1.2 will still increase the intensity value.
    // e.g., 4 * 1.2 = 4.8 which truncates to 4. Whereas 5 * 1.2 = 6.0 which truncs to 6 and 7 * 1.2 = 8.4 yielding 8, etc.
    uint16_t threshold(4);
    (redIntensity > threshold) ? redIntensity *= 1.2 : redIntensity *= 2;
    if (redIntensity > maxIntensity)
    {
      redIntensity = maxIntensity;
    }
   (greenIntensity > threshold) ? greenIntensity *= 1.2 : greenIntensity *= 2;
    if (greenIntensity > maxIntensity)
    {
      greenIntensity = maxIntensity;
    }
    (blueIntensity > threshold) ? blueIntensity *= 1.2 : blueIntensity *= 2;
    if (blueIntensity > maxIntensity)
    {
      blueIntensity = maxIntensity;
    }
    currentColor = thimbleCube.Color(redIntensity, greenIntensity, blueIntensity);
    paintCube(currentColor);
    delay(shortWait);
    paintCube(0);
  }
  delay(shortWait);

  paintCube(thimbleCube.Color(maxIntensity, 0, 0));
  delay(shortWait);
  paintCube(0);
  delay(shortWait);
  paintCube(thimbleCube.Color(0, maxIntensity, 0));
  delay(shortWait);
  paintCube(0);
  delay(shortWait);
  paintCube(thimbleCube.Color(0, 0, maxIntensity));
  delay(shortWait);
  paintCube(0);
  delay(shortWait);

  // now twinkle
  uint32_t color = thimbleCube.Color(2,2,2);
  paintCube(color);
  delay(shortWait);
  paintCube(0);
  delay(shortWait);
  paintCube(color);
  delay(shortWait);
  paintCube(0);
  delay(wait * 4);
}

void paintCube(uint32_t color)
{
  for (uint8_t pixel = 0; pixel < numPixels; ++pixel)
  {
    thimbleCube.setPixelColor(pixel, color);
  }
  thimbleCube.show();
}

#28

WHOA! Ok. My 3 sided cube is cute, so I decided to try Grandpa’s random colors code… I got a memory error, and then ALL six sides started working! It may not be my hacked up solder job after all!!!

Stoked!

Susan