# 10x10 LED Matrix with an 11th row to keep count

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!

``````// 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.

#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

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);
}
``````

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.

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):

``````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();
}
}
``````

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

``````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).

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.

``````// 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.

#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

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!

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.

``````// 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.

#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

{
};

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