help: alternative to display in seven segment

Greetings, i'm having trouble in finding a way to minimize my code on displaying in seven segment, I am using 2 BCD decoder and 2 seven segment

here's my setup.

Uploaded with ImageShack.us

and here's a part of my code used in displaying decimal values to the seven segment. i'm trying to minimize this code without changing the setup.

void out_segment() {
  switch (out_counter){
  case 99:
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(1, HIGH);
    break;
  case 98:
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(1, LOW);
    break;
  case 97:
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(1, HIGH);
    break;
  case 96:
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(1, LOW);
    break;
  case 95:
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(1, HIGH);
    break;
  case 94:
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(1, LOW);
    break;
  case 93:
    digitalWrite(10, HIGH);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, HIGH);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(1, HIGH);
    break;
.
.
.
  case 9:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(1, HIGH);
    break;
  case 8:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, HIGH);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(1, LOW);
    break;
  case 7:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(1, HIGH);
    break;
  case 6:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(1, LOW);
    break;
  case 5:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(1, HIGH);
    break;
  case 4:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(1, LOW);
    break;
  case 3:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(1, HIGH);
    break;
  case 2:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, HIGH);
    digitalWrite(1, LOW);
    break;
  case 1:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(1, HIGH);
    break;
  case 0:
    digitalWrite(10, LOW);
    digitalWrite(9, LOW);
    digitalWrite(8, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
    digitalWrite(1, LOW);
}

A function to convert BCD to outputs would be the simplest approach - a switch/case is crazy and a debug nightmare.

You need to make an array representing the High/Lows for digits 0-9. Then just call the array for the data to send out.

For example:

displayArray [ ] = {B00000000, // 0
B00000001, // 1
B00000010, // 2
B00000011, // 3
B00000100, // 4
B00000101, // 5
B00000110, // 6
B00000111, // 7
B00001000, // 8
B00001001 // 9
}

then just call it twice, for example using shiftout to a 74HC595 in front of the BCD decoder:

shiftout(dataPin, clockPin, MSBFIRST, displayArray(tens_counter) ); // tens digit shiftout(dataPin, clockPin, MSBFIRST, displayArray(ones_counter) ); // ones digit

Or change the data to represent the segments directly, ditch the decode chip altogether, and drive the display direct from the shift register.

Apart from the code, here is a question for you: are there any resistors in your hookup to limit current through the display? I can't see the part number of your decoder so hopefully it has something to protect itself from excess current otherwise you're killing them over time.

Here is some code for a int to seven segment BCD with 7447 chips I used. It requires your pins for the 4 digits to be in an array (in this case, I used ssdPins) This is for an individual seven segment display, but you can see that by using a for loop, you can cut down a significant amount of code. If you just adjust some of the numbers, the code should be able to handle your two digits. For eight bits, just change the ‘3’ to a ‘7’ (remember that computers start counting at zero) and make sure you change the ‘15’ to ‘255’.

Also, make sure you are using a 270 or 330 ohm resistor with each segment. Leaving them without resistance will ruin them.

void writeDigit(int x){
  
  //first, we have to make sure our value is under 15
  if(x > 15 || x < 0){
    //do nothing - invalid parameters!
  } else {
    //run the loop code
    
    //this will be the loop
    for(int i = 3; i > -1; i--){
      
      int b = bit(i);
    
      //if statement to set the pin
      if(x >= b){
        
        digitalWrite(ssdPins[i], HIGH);
        x = x - b;
        
      } else {
        
        digitalWrite(ssdPins[i], LOW);
        
      }//end if/else statement
    }//end for loop
    
    
  }//end else/if statemnt
  
}//end writeDigit()

Personally, I would only use one driver chip to write BCD to and wire the two seven segment displays together. By tying the anode to a pin, you can control whether the digit displays and multiplex. In this way, you can add many seven segment displays to the code in the future. (this is more difficult than what you are doing, but in the long run you can get bigger displays with less pins)

CrossRoads: You need to make an array representing the High/Lows for digits 0-9. Then just call the array for the data to send out.

For example:

displayArray [ ] = {B00000000, // 0
B00000001, // 1
B00000010, // 2
B00000011, // 3
B00000100, // 4
B00000101, // 5
B00000110, // 6
B00000111, // 7
B00001000, // 8
B00001001 // 9
}

then just call it twice, for example using shiftout to a 74HC595 in front of the BCD decoder:

shiftout(dataPin, clockPin, MSBFIRST, displayArray(tens_counter) ); // tens digit shiftout(dataPin, clockPin, MSBFIRST, displayArray(ones_counter) ); // ones digit

Or change the data to represent the segments directly, ditch the decode chip altogether, and drive the display direct from the shift register.

i tried studying what you have told me...but with my little knowledge of programming i didn't able to cope with you... the shiftout you were telling me as for a 74HC595 right? not sure how will i convert that to my 74LS248P, which doesn't have a clock..

sir if you can provide me an example for a 0-9 single segment display,using the 74LS248 with shiftout...i might able to study it, sorry for my newbieness, and thx alot..

kupo:
Here is some code for a int to seven segment BCD with 7447 chips I used. It requires your pins for the 4 digits to be in an array (in this case, I used ssdPins) This is for an individual seven segment display, but you can see that by using a for loop, you can cut down a significant amount of code. If you just adjust some of the numbers, the code should be able to handle your two digits. For eight bits, just change the ‘3’ to a ‘7’ (remember that computers start counting at zero) and make sure you change the ‘15’ to ‘255’.

Also, make sure you are using a 270 or 330 ohm resistor with each segment. Leaving them without resistance will ruin them.

void writeDigit(int x){

//first, we have to make sure our value is under 15
 if(x > 15 || x < 0){
   //do nothing - invalid parameters!
 } else {
   //run the loop code
   
   //this will be the loop
   for(int i = 3; i > -1; i–){
     
     int b = bit(i);
   
     //if statement to set the pin
     if(x >= b){
       
       digitalWrite(ssdPins[i], HIGH);
       x = x - b;
       
     } else {
       
       digitalWrite(ssdPins[i], LOW);
       
     }//end if/else statement
   }//end for loop
   
   
 }//end else/if statemnt
 
}//end writeDigit()




Personally, I would only use one driver chip to write BCD to and wire the two seven segment displays together. By tying the anode to a pin, you can control whether the digit displays and multiplex. In this way, you can add many seven segment displays to the code in the future. (this is more difficult than what you are doing, but in the long run you can get bigger displays with less pins)

I’m starting to understand this part…but i tried searching for the ssdPins in arduino reference, and it doesn’t show up…can you enlighten me with this?

“writeDigit(int x)” what’s the use of the int x here?

The ssdPins is just an array. (http://arduino.cc/en/Reference/Array)

you could name the array anything, but you just declare it above. For instance, here is how I would declare the array for this code:

/* this goes at the very top of the program - NOT inside setup or loop */
int ssdPins[] = {2, 3, 4, 5};

//put this in your 'setup' to set those pins as outputs
  //set up pinmodes for select and BCD outputs
  for(int i = 0; i < 4; i++){
  pinMode(ssdPins[i], OUTPUT);
  }//end for loop

Arrays can be very powerful when used with Loops. You can access a lot of information with just a few lines of code. Each time through this for loop, the i variable is replaced with the number of the loop. So, the first time through, i is at 0 which makes ssdPins = ssdPins[0]. The next time it counts up by 1, so i = 1 and ssdPins = ssdPins[1] and so on.
If you put your eight output pins into the ssdPins[] array and change the ‘4’ to an ‘8’, you should be able to set up all eight of your pins with just the code above.
The (int x) explained:
The code I gave you above is a function. It would go outside of the loop() or setup() (I usually put my functions below the loop() ). You can then pass an integer into that function and it will set the outputs for your pins. Example:
```
*void loop() {
writeDigit(7);
}

//this is where the function would go
void writeDigit(int x){ // ------ not going to copy everything over, but this is the code from above }
_
```*_
This will take the integer ‘7’ and convert it to HIGH / LOW outputs on whatever pins you have set up to go to your BCD decoders.