7-Segment LED counter using arrays and for statements

Hi all,

Just got one of these and learning programming and trying to use a 7-segment LED to count from 1 to 8. I can do it fine without using arrays or for statements but it’s incredibly long and inefficient code so I found the array and for commands and figured they can do the job. My issue is that it’s not counting correctly. If I limit the code to only display one of the numbers individually, it displays it correctly, however if I try a sequence it gives me jumbled rubbish.

One thing I’ve noticed is that the digits it does give appear to be a combination of the previous and current number of the sequence. I feel I’m missing something silly.

Imgur

//This code will light up the 7 segment LED from A to G 1 by 1

const int timer=5000; //Sets the delay time
int LED1[2]= {7,6};
int LED2[5]= {8,7,2,4,5};                
int LED3[5]= {8,7,2,6,5};                
int LED4[4]= {7,6,2,3};                
int LED5[5]= {8,3,2,6,5};                
int LED6[5]= {6,5,4,3,2};                
int LED7[3]= {8,7,6};                
int LED8[7]= {8,7,6,5,4,3,2};                                   

void setup(){
  for(int Pin=0;Pin<=8;Pin++)
  pinMode(Pin,OUTPUT);
}

void loop(){

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED1],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED1],LOW);

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED2],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED2],LOW);

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED3],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED3],LOW);

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED4],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED4],LOW);

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED5],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED5],LOW);

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED6],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED6],LOW);

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED7],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED7],LOW);

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED8],HIGH);
  delay(timer);
  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED8],LOW);
  }

LED_7Seg_Count.ino (1.63 KB)

You do read data that is not within your array(s) bounds. Example:

for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED1],HIGH);

Array LED1 has 2 elements (0 and 1). You try to read elements 0 to 7.
So as you read “strange” data you may expect “strange” behaviour. :slight_smile:

  for(int Pin=0;Pin<=8;Pin++)
  pinMode(Pin,OUTPUT);

This will set pins 0 and 1 to be outputs. You should not be doing that. Those pins are for sketch upload and communicating with serial monitor. I don’t think that was your intention anyway. You meant pins 2 to 8, not 0 to 8.

  for(int Pin=0; Pin<=8;Pin++)
  digitalWrite(Pin[LED1],HIGH);

You have things very confused here. “LED1” is the array and “Pin” is the index into the array. Not the other way around. And, as already pointed out, LED1 has only 2 indexes.

Using arrays and for loops is the right way to go because, as you say, your code will get very long without them. But you have not yet understood how to use arrays. And your code is still going to be very long. Here is a clue. When you find yourself making many variables with “1”, “2”, “3” etc at the end of the variable’s names, that is a sign that you should be using an array. In your code, the variables who’s names end “1”, “2”, “3” are themselves arrays. So you need to use an array of arrays, otherwise called a “2-dimensional” array.

You have array name and index backwards

uxomm:
You do read data that is not within your array(s) bounds. Example:

for(int Pin=0; Pin<=8;Pin++)

digitalWrite(Pin[LED1],HIGH);




Array LED1 has 2 elements (0 and 1). You try to read elements 0 to 7.
So as you read "strange" data you may expect "strange" behaviour. :)

Thank you, I really didn’t have a proper understanding of how they work and was trying to use one like the for loop example I was fiddling with earlier.

PaulRB:

  for(int Pin=0;Pin<=8;Pin++)

pinMode(Pin,OUTPUT);



This will set pins 0 and 1 to be outputs. You should not be doing that. Those pins are for sketch upload and communicating with serial monitor. I don't think that was your intention anyway. You meant pins 2 to 8, not 0 to 8.



for(int Pin=0; Pin<=8;Pin++)
 digitalWrite(Pin[LED1],HIGH);



You have things very confused here. "LED1" is the array and "Pin" is the index into the array. Not the other way around. And, as already pointed out, LED1 has only 2 indexes.

Using arrays and for loops is the right way to go because, as you say, your code will get very long without them. But you have not yet understood how to use arrays. And your code is still going to be very long. Here is a clue. When you find yourself making many variables with "1", "2", "3" etc at the end of the variable's names, that is a sign that you should be using an array. In your code, the variables who's names end "1", "2", "3" are themselves arrays. So you need to use an array of arrays, otherwise called a "2-dimensional" array.

Thanks for the tips, I still have a lot to learn!

INTP:
You have array name and index backwards

I sure do, a durr moment for me.

I have it working well now and able to manipulate it as I want, so thanks for all the help.

//This code will light up the 7 segment LED from A to G 1 by 1

const int timer=1000; //Sets the delay time
int LED1[2]= {7,6};
int LED2[5]= {8,7,2,4,5};              
int LED3[5]= {8,7,2,6,5};               
int LED4[4]= {7,6,2,3};                
int LED5[5]= {8,3,2,6,5};                
int LED6[5]= {5,6,4,3,2};                
int LED7[3]= {7,8,6};                
int LED8[7]= {8,7,6,5,4,3,2};                                   

void setup(){
  for(int Pin=2;Pin<=8;Pin++)
  pinMode(Pin,OUTPUT);
}

void loop(){

  for(int Pin=0; Pin<2;Pin++)
  digitalWrite(LED1[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<2;Pin++)
  digitalWrite(LED1[Pin],LOW);

  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED2[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED2[Pin],LOW);

  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED3[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED3[Pin],LOW);

  for(int Pin=0; Pin<4;Pin++)
  digitalWrite(LED4[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<4;Pin++)
  digitalWrite(LED4[Pin],LOW);

  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED5[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED5[Pin],LOW);

  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED6[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<5;Pin++)
  digitalWrite(LED6[Pin],LOW);

  for(int Pin=0; Pin<3;Pin++)
  digitalWrite(LED7[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<3;Pin++)
  digitalWrite(LED7[Pin],LOW);

  for(int Pin=0; Pin<7;Pin++)
  digitalWrite(LED8[Pin],HIGH);
  delay(timer);
  for(int Pin=0; Pin<7;Pin++)
  digitalWrite(LED8[Pin],LOW);
  }

A more general code for a single seven segment:

/* Seven segment
  Segments:             Pins:
          a a a              8 8 8
        f       b          3       7
        f       b          3       7
        f       b          3       7
          g g g              2 2 2
        e       c          4       6
        e       c          4       6
        e       c          4       6
          d d d              5 5 5
*/

//                   a  b  c  d  e  f  g
const byte pins[] = {8, 7, 6, 5, 4, 3, 2};
const byte digits[] = {
  //gfedcba
  0b0111111,  // 0
  0b0000110,  // 1
  0b1011011,  // 2
  0b1001111,  // 3
  0b1100110,  // 4
  0b1101101,  // 5
  0b1111101,  // 6
  0b0100111,  // 7
  0b1111111,  // 8
  0b1101111   // 9
};

void displayNumber(byte number) {
  number = number % 10;   // hold the number within array bounds
  byte d = digits[number];
  for (byte i = 0; i < sizeof(pins); i++) {
    digitalWrite(pins[i], bitRead(d, i));  // turn segments on or off
  }
}

void setup() {
  for (byte j = 0; j < sizeof(pins); j++) {
    pinMode(pins[j], OUTPUT);
  }
}

void loop() {
  // test: display 0 ... 9
  for (byte k = 0; k < 10; k++) {
    displayNumber(k);
    delay(1000);
  }
}

uxomm:
A more general code for a single seven segment:

/* Seven segment

Segments:            Pins:
          a a a              8 8 8
        f      b          3      7
        f      b          3      7
        f      b          3      7
          g g g              2 2 2
        e      c          4      6
        e      c          4      6
        e      c          4      6
          d d d              5 5 5
*/

//                  a  b  c  d  e  f  g
const byte pins = {8, 7, 6, 5, 4, 3, 2};
const byte digits = {
  //gfedcba
  0b0111111,  // 0
  0b0000110,  // 1
  0b1011011,  // 2
  0b1001111,  // 3
  0b1100110,  // 4
  0b1101101,  // 5
  0b1111101,  // 6
  0b0100111,  // 7
  0b1111111,  // 8
  0b1101111  // 9
};

void displayNumber(byte number) {
  number = number % 10;  // hold the number within array bounds
  byte d = digits[number];
  for (byte i = 0; i < sizeof(pins); i++) {
    digitalWrite(pins[i], bitRead(d, i));  // turn segments on or off
  }
}

void setup() {
  for (byte j = 0; j < sizeof(pins); j++) {
    pinMode(pins[j], OUTPUT);
  }
}

void loop() {
  // test: display 0 … 9
  for (byte k = 0; k < 10; k++) {
    displayNumber(k);
    delay(1000);
  }
}

Oh you’ve thrown me for a loop now! I think I have a lot of learning to do to reach this stage but thanks for giving me some direction to learn. Cheers.

netbrowser:
Oh you've thrown me for a loop now!

Thrown you for a loop, or shown you a for loop (actually, two for loops)?

odometer:
Thrown you for a loop, or shown you a for loop (actually, two for loops)?

Oh you guys

I could find in the Internet… So How can I wire and progam to control 2 displays (0-99 count) ? (Arduino UNO) Thanks in advance.

uxomm:
A more general code for a single seven segment:

/* Seven segment

Segments:            Pins:
          a a a              8 8 8
        f      b          3      7
        f      b          3      7
        f      b          3      7
          g g g              2 2 2
        e      c          4      6
        e      c          4      6
        e      c          4      6
          d d d              5 5 5
*/

//                  a  b  c  d  e  f  g
const byte pins = {8, 7, 6, 5, 4, 3, 2};
const byte digits = {
  //gfedcba
  0b0111111,  // 0
  0b0000110,  // 1
  0b1011011,  // 2
  0b1001111,  // 3
  0b1100110,  // 4
  0b1101101,  // 5
  0b1111101,  // 6
  0b0100111,  // 7
  0b1111111,  // 8
  0b1101111  // 9
};

void displayNumber(byte number) {
  number = number % 10;  // hold the number within array bounds
  byte d = digits[number];
  for (byte i = 0; i < sizeof(pins); i++) {
    digitalWrite(pins[i], bitRead(d, i));  // turn segments on or off
  }
}

void setup() {
  for (byte j = 0; j < sizeof(pins); j++) {
    pinMode(pins[j], OUTPUT);
  }
}

void loop() {
  // test: display 0 … 9
  for (byte k = 0; k < 10; k++) {
    displayNumber(k);
    delay(1000);
  }
}

Douglas713:
I could find in the Internet... So How can I wire and progam to control 2 displays (0-99 count) ? (Arduino UNO) Thanks in advance.

what have you tried so far ?

can you wire and program a display of 7 LEDs ?

Soon, you’re going to run out of pins...

You’ll need to consider multiplexing and/or shift-registers to support the number of digits & segments.

Or a custom LED driver chip like the MAX7219 and others.