Go Down

Topic: 10x10 LED Matrix with an 11th row to keep count (Read 385 times) previous topic - next topic

beebs730

Sep 01, 2019, 10:00 pm Last Edit: Sep 01, 2019, 10:51 pm by beebs730
Hi all,
I'm new to Arduino programming, and am trying to make a 10x10 matrix of LEDs with an 11th row of 10 LEDs that counts once the first 100 LEDs have been cycled through. This project is meant to serve the purpose of a visual timer to check the timing of a video's frame speed, so it has to be quite precise.

I've modified some code that I found on the forum to create a cycle for the first ten rows which seems to work, but for whatever reason my 11th row (which should have one LED light up once the first 100 LEDs have been cycled through) does not light up at the timing I've input; instead it's lighting up in time with the first 100 LEDs. I'm not sure where in the code I've gone wrong. Here's my code so far (sorry, it's super not elegant).

Could someone help me get the 11th LED strip (on Pin 12) light up at the right rate?

Thanks!
Code: [Select]

// Timer with 10 LED strips of 10 LEDs per strip, and an 11th strip to count each time the first 10 rows
// completes a cycle.

#include <Adafruit_NeoPixel.h>

#define PIN2  2 //First strip of LEDs
#define PIN3  3 //Second strip of LEDs
#define PIN4  4 //Third strip of LEDs
#define PIN5  5 //Fourth strip of LEDs
#define PIN6  6 //Fifth strip of LEDs
#define PIN7  7 //Sixth strip of LEDs
#define PIN8  8 //Seventh strip of LEDs
#define PIN9  9 //Eight strip of LEDs
#define PIN10  10 //Ninth strip of LEDs
#define PIN11  11 //Tenth strip of LEDs
#define PIN12  12 // Eleventh strip of LEDs - the counter strip

#define N_LEDS 10 //Number of LEDs per strip

int timing = 1000; //Blinking rate of the first ten strips

Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(N_LEDS, PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(N_LEDS, PIN3, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip4 = Adafruit_NeoPixel(N_LEDS, PIN4, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip5 = Adafruit_NeoPixel(N_LEDS, PIN5, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip6 = Adafruit_NeoPixel(N_LEDS, PIN6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip7 = Adafruit_NeoPixel(N_LEDS, PIN7, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip8 = Adafruit_NeoPixel(N_LEDS, PIN8, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip9 = Adafruit_NeoPixel(N_LEDS, PIN9, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip10 = Adafruit_NeoPixel(N_LEDS, PIN10, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip11 = Adafruit_NeoPixel(N_LEDS, PIN11, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip12 = Adafruit_NeoPixel(N_LEDS, PIN12, NEO_GRB + NEO_KHZ800);



void setup() {
 strip2.begin();
 strip3.begin();
 strip4.begin();
 strip5.begin();
 strip6.begin();
 strip7.begin();
 strip8.begin();
 strip9.begin();
 strip10.begin();
 strip11.begin();
 strip12.begin();
}

void loop() {
 chase2(strip2.Color(255, 0, 0)); // Red
 chase3(strip3.Color(255, 0, 0)); // Red
 chase4(strip4.Color(255, 0, 0)); // Red
 chase5(strip5.Color(255, 0, 0)); // Red
 chase6(strip6.Color(255, 0, 0)); // Red
 chase7(strip7.Color(255, 0, 0)); // Red
 chase8(strip8.Color(255, 0, 0)); // Red
 chase9(strip9.Color(255, 0, 0)); // Red
 chase10(strip10.Color(255, 0, 0)); // Red
 chase11(strip11.Color(255, 0, 0)); // Red
 chase12(strip12.Color(255, 0, 0)); //Red
}

static void chase2(uint32_t c) {
 for (uint16_t i = 0; i < strip2.numPixels() + 1; i++) {
   strip2.setPixelColor(i  , c); // Draw new pixel
   strip2.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip2.show();
   delayMicroseconds(timing);
 }
}

static void chase3(uint32_t c) {
 for (uint16_t i = 0; i < strip3.numPixels() + 1; i++) {
   strip3.setPixelColor(i  , c); // Draw new pixel
   strip3.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip3.show();
   delayMicroseconds(timing);
 }
}

static void chase4(uint32_t c) {
 for (uint16_t i = 0; i < strip4.numPixels() + 1; i++) {
   strip4.setPixelColor(i  , c); // Draw new pixel
   strip4.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip4.show();
   delayMicroseconds(timing);
 }
}

static void chase5(uint32_t c) {
 for (uint16_t i = 0; i < strip5.numPixels() + 1; i++) {
   strip5.setPixelColor(i  , c); // Draw new pixel
   strip5.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip5.show();
   delayMicroseconds(timing);
 }
}

static void chase6(uint32_t c) {
 for (uint16_t i = 0; i < strip6.numPixels() + 1; i++) {
   strip6.setPixelColor(i  , c); // Draw new pixel
   strip6.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip6.show();
   delayMicroseconds(timing);
 }
}

static void chase7(uint32_t c) {
 for (uint16_t i = 0; i < strip7.numPixels() + 1; i++) {
   strip7.setPixelColor(i  , c); // Draw new pixel
   strip7.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip7.show();
   delayMicroseconds(timing);
 }
}

static void chase8(uint32_t c) {
 for (uint16_t i = 0; i < strip8.numPixels() + 1; i++) {
   strip8.setPixelColor(i  , c); // Draw new pixel
   strip8.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip8.show();
   delayMicroseconds(timing);
 }
}

static void chase9(uint32_t c) {
 for (uint16_t i = 0; i < strip9.numPixels() + 1; i++) {
   strip9.setPixelColor(i  , c); // Draw new pixel
   strip9.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip9.show();
   delayMicroseconds(timing);
 }
}

static void chase10(uint32_t c) {
 for (uint16_t i = 0; i < strip10.numPixels() + 1; i++) {
   strip10.setPixelColor(i  , c); // Draw new pixel
   strip10.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip10.show();
   delayMicroseconds(timing);
 }
}

static void chase11(uint32_t c) {
 for (uint16_t i = 0; i < strip11.numPixels() + 1; i++) {
   strip11.setPixelColor(i  , c); // Draw new pixel
   strip11.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip11.show();
   delayMicroseconds(timing);
 }
}


static void chase12(uint32_t c) {
 for (uint16_t i = 0; i < strip12.numPixels() + 1; i++) {
   strip12.setPixelColor(i  , c); // Draw new pixel
   strip12.setPixelColor(i - 1, 0); // Erase pixel a few steps back
   strip12.show();
   delayMicroseconds(timing*100);
 }

PerryBebbington

Hello beebs730,
Welcome to the forum.

You are more likely to get friendly, helpful answers if you follow the forum instructions. Please read 'how to use this forum - please read' (there's a clue in the title), then go back and modify your post in line with the instructions, especially item #7.

Thank you.

beebs730

Thanks! I fixed it!  Sorry about that! I did check the instructions, but I clearly somehow missed that very important one.

I also modified the code slightly in the loop() and it works somewhat better now, but now I'm missing a counter LED every 10th run-through (i.e. there's a run-through of the top 10 rows where none of the LEDs on the bottom row are lit up):

Code: [Select]
void loop() {

 for (uint16_t i = 0; i < strip12.numPixels() + 1; i++) {
  chase2(strip2.Color(255, 0, 0)); // Red
  chase3(strip3.Color(255, 0, 0)); // Red
  chase4(strip4.Color(255, 0, 0)); // Red
  chase5(strip5.Color(255, 0, 0)); // Red
  chase6(strip6.Color(255, 0, 0)); // Red
  chase7(strip7.Color(255, 0, 0)); // Red
  chase8(strip8.Color(255, 0, 0)); // Red
  chase9(strip9.Color(255, 0, 0)); // Red
  chase10(strip10.Color(255, 0, 0)); // Red
  chase11(strip11.Color(255, 0, 0)); // Red
    strip12.setPixelColor(i, (strip12.Color(255, 0, 0))); // Draw new pixel
    strip12.setPixelColor(i - 1, 0);
    strip12.show();
}
}

david_2018

All of your chase functions have a problem - as an example:

Code: [Select]

static void chase2(uint32_t c) {
  for (uint16_t i = 0; i < strip2.numPixels() + 1; i++) {
    strip2.setPixelColor(i  , c); // Draw new pixel
    strip2.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip2.show();
    delayMicroseconds(timing);
  }
}


When i = 0, where exactly do you think pixel (i - 1) is?
In the for statement, you are testing for i < strip.numPixels() + 1, when i = strip.numPixels() that will put pixel(i) past the end of the LED strip (and most likely at the first pixel of the next strip).

beebs730

#4
Sep 02, 2019, 11:49 pm Last Edit: Sep 02, 2019, 11:50 pm by beebs730
Okay, thank you! Is this better? I think my code got uglier, but what do you think? It seems to be doing what I want it to.

Code: [Select]
// Timer with 10 LED strips of 10 LEDs per strip, and an 11th strip to count each time the first 10 rows
// completes a cycle.

#include <Adafruit_NeoPixel.h>

#define PIN2  2 //First strip of LEDs
#define PIN3  3 //Second strip of LEDs
#define PIN4  4 //Third strip of LEDs
#define PIN5  5 //Fourth strip of LEDs
#define PIN6  6 //Fifth strip of LEDs
#define PIN7  7 //Sixth strip of LEDs
#define PIN8  8 //Seventh strip of LEDs
#define PIN9  9 //Eight strip of LEDs
#define PIN10  10 //Ninth strip of LEDs
#define PIN11  11 //Tenth strip of LEDs
#define PIN13  13 // Eleventh strip of LEDs - the counter strip

#define N_LEDS 10 //Number of LEDs per strip

unsigned long timing = 100; //Blinking rate of the first ten strips

Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(N_LEDS, PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(N_LEDS, PIN3, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip4 = Adafruit_NeoPixel(N_LEDS, PIN4, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip5 = Adafruit_NeoPixel(N_LEDS, PIN5, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip6 = Adafruit_NeoPixel(N_LEDS, PIN6, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip7 = Adafruit_NeoPixel(N_LEDS, PIN7, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip8 = Adafruit_NeoPixel(N_LEDS, PIN8, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip9 = Adafruit_NeoPixel(N_LEDS, PIN9, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip10 = Adafruit_NeoPixel(N_LEDS, PIN10, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip11 = Adafruit_NeoPixel(N_LEDS, PIN11, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip13 = Adafruit_NeoPixel(N_LEDS, PIN13, NEO_GRB + NEO_KHZ800);



void setup() {
  strip2.begin();
  strip3.begin();
  strip4.begin();
  strip5.begin();
  strip6.begin();
  strip7.begin();
  strip8.begin();
  strip9.begin();
  strip10.begin();
  strip11.begin();
  strip13.begin();
}

void loop() {
strip13.setPixelColor(0, 0);
strip13.setPixelColor(1, 0);
strip13.setPixelColor(2, 0);
strip13.setPixelColor(3, 0);
strip13.setPixelColor(4, 0);
strip13.setPixelColor(5, 0);
strip13.setPixelColor(6, 0);
strip13.setPixelColor(7, 0);
strip13.setPixelColor(8, 0);
strip13.setPixelColor(9, 0);
 for (uint16_t i = 0; i < strip2.numPixels(); i++) {
  chase2(strip2.Color(255, 0, 0)); // Red
  chase3(strip3.Color(255, 0, 0)); // Red
  chase4(strip4.Color(255, 0, 0)); // Red
  chase5(strip5.Color(255, 0, 0)); // Red
  chase6(strip6.Color(255, 0, 0)); // Red
  chase7(strip7.Color(255, 0, 0)); // Red
  chase8(strip8.Color(255, 0, 0)); // Red
  chase9(strip9.Color(255, 0, 0)); // Red
  chase10(strip10.Color(255, 0, 0)); // Red
  chase11(strip11.Color(255, 0, 0)); // Red
    strip13.setPixelColor(i, (strip13.Color(255, 0, 0))); // Draw new pixel
    strip13.show();
}
}

static void chase2(uint32_t c) {
  for (uint16_t i = 0; i < strip2.numPixels() + 1; i++) {
    strip2.setPixelColor(i  , c); // Draw new pixel
    strip2.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip2.show();
    delayMicroseconds(timing);
  }
}

static void chase3(uint32_t c) {
  for (uint16_t i = 0; i < strip3.numPixels() + 1; i++) {
    strip3.setPixelColor(i  , c); // Draw new pixel
    strip3.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip3.show();
    delayMicroseconds(timing);
  }
}

static void chase4(uint32_t c) {
  for (uint16_t i = 0; i < strip4.numPixels() + 1; i++) {
    strip4.setPixelColor(i  , c); // Draw new pixel
    strip4.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip4.show();
    delayMicroseconds(timing);
  }
}

static void chase5(uint32_t c) {
  for (uint16_t i = 0; i < strip5.numPixels() + 1; i++) {
    strip5.setPixelColor(i  , c); // Draw new pixel
    strip5.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip5.show();
    delayMicroseconds(timing);
  }
}

static void chase6(uint32_t c) {
  for (uint16_t i = 0; i < strip6.numPixels() + 1; i++) {
    strip6.setPixelColor(i  , c); // Draw new pixel
    strip6.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip6.show();
    delayMicroseconds(timing);
  }
}

static void chase7(uint32_t c) {
  for (uint16_t i = 0; i < strip7.numPixels() + 1; i++) {
    strip7.setPixelColor(i  , c); // Draw new pixel
    strip7.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip7.show();
    delayMicroseconds(timing);
  }
}

static void chase8(uint32_t c) {
  for (uint16_t i = 0; i < strip8.numPixels() + 1; i++) {
    strip8.setPixelColor(i  , c); // Draw new pixel
    strip8.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip8.show();
    delayMicroseconds(timing);
  }
}

static void chase9(uint32_t c) {
  for (uint16_t i = 0; i < strip9.numPixels() + 1; i++) {
    strip9.setPixelColor(i  , c); // Draw new pixel
    strip9.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip9.show();
    delayMicroseconds(timing);
  }
}

static void chase10(uint32_t c) {
  for (uint16_t i = 0; i < strip10.numPixels() + 1; i++) {
    strip10.setPixelColor(i  , c); // Draw new pixel
    strip10.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip10.show();
    delayMicroseconds(timing);
  }
}

static void chase11(uint32_t c) {
  for (uint16_t i = 0; i < strip11.numPixels() + 1; i++) {
    strip11.setPixelColor(i  , c); // Draw new pixel
    strip11.setPixelColor(i - 1, 0); // Erase pixel a few steps back
    strip11.show();
    delayMicroseconds(timing);
  }
}


I didn't take away the stripX.numPixels()+1 in my chase() method though, because when I do that the last pixel at the end of each strip doesn't turn off. Is there anyway to fix that?

Thanks very much!

marco_c

#5
Sep 03, 2019, 07:34 am Last Edit: Sep 03, 2019, 11:40 pm by marco_c
Not sure why no-one has pointed this out, but when you start having repeated identical variables with consecutive numbers in the variable name, it usually means that you will simplify your code by changing to array notation.

You should also let loop() do the looping and not create a problems for yourself with complex loops inside of loop().

I have re-written the code using arrays and also tried to overcome some of the problem boundary conditions that you mentioned. The code compiles but I am unable to test it as I don't have the hardware. Use it if you feel like it, but at least read it to understand how to use arrays. You will notice it is a lot shorter and (hopefully) does the same thing.

Code: [Select]
// Timer with 10 LED strips of 10 LEDs per strip, and an 11th strip to count each time the first 10 rows
// completes a cycle.

#include <Adafruit_NeoPixel.h>

#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

// Pin numbers for neopixel rows
// last one is the indicator row
const uint8_t PIN[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

const uint8_t N_LEDS = 10; //Number of LEDs per row
const uint8_t INDICATOR_ROW = ARRAY_SIZE(PIN)-1; // indicator row

const unsigned long timing = 100; //Blinking rate of the first ten strips

Adafruit_NeoPixel strip[ARRAY_SIZE(PIN)] =
{
  Adafruit_NeoPixel(N_LEDS, PIN[0], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[1], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[2], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[3], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[4], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[5], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[6], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[7], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[8], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[9], NEO_GRB + NEO_KHZ800),
  Adafruit_NeoPixel(N_LEDS, PIN[10], NEO_GRB + NEO_KHZ800)
};

void setup(void)
{
  for (uint8_t i=0; i<ARRAY_SIZE(strip); i++)
    strip[i].begin();
}

void loop(void)
{
  static uint16_t activeCount = 0;
  static uint8_t indLed = 0;
  static uint8_t rowPrev = ARRAY_SIZE(strip) - 1;
  static uint8_t colPrev = N_LEDS-1;
  uint8_t row, col;

  // Clear the display when its counter is zero
  if (activeCount == 0)
  {
    for (uint8_t i=0; i<ARRAY_SIZE(strip)-1; i++)
      strip[i].clear();
  }

  // Clear the indicator strip when its counter is zero
  if (indLed == 0)
    strip[INDICATOR_ROW].clear();

  // Set the current pixel
  row = activeCount / N_LEDS;
  col = activeCount % N_LEDS;

  strip[row].setPixelColor(strip[row].Color(255, 0, 0), col); // Draw new pixel
  strip[rowPrev].setPixelColor(0, colPrev); // Erase previous pixel
  strip[row].show();

  // prepare for next time through loop
  rowPrev = row;
  colPrev = col;
  activeCount++;

  // now check all the boundary conditions
  if (activeCount >= (N_LEDS * (ARRAY_SIZE(strip)-1)))
  {
    activeCount = 0;    // restart the count
   
    // this also means a page has finished
    indLed++;
    strip[INDICATOR_ROW].setPixelColor(indLed, (strip[INDICATOR_ROW].Color(255, 0, 0))); // Draw new pixel
    strip[INDICATOR_ROW].show();
   
    if (indLed >= N_LEDS) indLed = 0;
  }
   
  // now delay for a short while
  delayMicroseconds(timing);
}

UPDATED code 4 Sep as it was pasted incomplete
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

Go Up