1

I'm trying to implement a shift register(s) into my circuitry and program to control two seven segment LEDs that would count up from 00 - 99. So far I have a fairly straightforward code (at least, I think. It's my first time experimenting with creating my own void functions) that controls the 7 segs in this manner, but I end up using every single digital pin on my Uno. Here it is:

const int led1a = 13;
const int led1b = 12;
const int led1c = 11;
const int led1d = 10;
const int led1e = 9;
const int led1f = 8;
const int led1g = 7;
const int led2a = 6;
const int led2b = 5;
const int led2c = 4;
const int led2d = 3;
const int led2e = 2;
const int led2f = 1;
const int led2g = 0;

void setup() {
    pinMode(led1a, OUTPUT);
    pinMode(led1b, OUTPUT);
    pinMode(led1c, OUTPUT);
    pinMode(led1d, OUTPUT);
    pinMode(led1e, OUTPUT);
    pinMode(led1f, OUTPUT);
    pinMode(led1g, OUTPUT);
    pinMode(led2a, OUTPUT);
    pinMode(led2b, OUTPUT);
    pinMode(led2c, OUTPUT);
    pinMode(led2d, OUTPUT);
    pinMode(led2e, OUTPUT);
    pinMode(led2f, OUTPUT);
    pinMode(led2g, OUTPUT);
}

void loop () {
    led1_0();
    led2_run();
    led1_1();
    led2_run();
    led1_2();
    led2_run();
    led1_3();
    led2_run();
    led1_4();
    led2_run();
    led1_5();
    led2_run();
    led1_6();
    led2_run();
    led1_7();
    led2_run();
    led1_8();
    led2_run();
    led1_9();
    led2_run();
}

void led1_0() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, HIGH);
    digitalWrite(led1e, HIGH);
    digitalWrite(led1g, HIGH);
    digitalWrite(led1f, LOW);
}
void led1_1() {
    digitalWrite(led1a, LOW);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, LOW);
    digitalWrite(led1e, LOW);
    digitalWrite(led1f, LOW);
    digitalWrite(led1g, LOW);
}
void led1_2() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1f, HIGH);
    digitalWrite(led1e, HIGH);
    digitalWrite(led1d, HIGH);
    digitalWrite(led1c, LOW);
    digitalWrite(led1g, LOW);
}
void led1_3() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, HIGH);
    digitalWrite(led1f, HIGH);
    digitalWrite(led1e, LOW);
    digitalWrite(led1g, LOW);
}
void led1_4() {
    digitalWrite(led1a, LOW);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1f, HIGH);
    digitalWrite(led1g, HIGH);
    digitalWrite(led1e, LOW);
    digitalWrite(led1d, LOW);
}
void led1_5() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1f, HIGH);
    digitalWrite(led1g, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, HIGH);
    digitalWrite(led1b, LOW);
    digitalWrite(led1e, LOW);
}
void led1_6() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1g, HIGH);
    digitalWrite(led1f, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, HIGH);
    digitalWrite(led1e, HIGH);
    digitalWrite(led1b, LOW);
}
void led1_7() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, LOW);
    digitalWrite(led1e, LOW);
    digitalWrite(led1f, LOW);
    digitalWrite(led1g, LOW);
}
void led1_8() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, HIGH);
    digitalWrite(led1e, HIGH);
    digitalWrite(led1f, HIGH);
    digitalWrite(led1g, HIGH);
}
void led1_9() {
    digitalWrite(led1a, HIGH);
    digitalWrite(led1b, HIGH);
    digitalWrite(led1c, HIGH);
    digitalWrite(led1d, HIGH);
    digitalWrite(led1g, HIGH);
    digitalWrite(led1f, HIGH);
    digitalWrite(led1e, LOW);
}
void led2_0() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, HIGH);
    digitalWrite(led2e, HIGH);
    digitalWrite(led2g, HIGH);
    digitalWrite(led2f, LOW);
}
void led2_1() {
    digitalWrite(led2a, LOW);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, LOW);
    digitalWrite(led2e, LOW);
    digitalWrite(led2f, LOW);
    digitalWrite(led2g, LOW);
}
void led2_2() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2f, HIGH);
    digitalWrite(led2e, HIGH);
    digitalWrite(led2d, HIGH);
    digitalWrite(led2c, LOW);
    digitalWrite(led2g, LOW);
}
void led2_3() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, HIGH);
    digitalWrite(led2f, HIGH);
    digitalWrite(led2e, LOW);
    digitalWrite(led2g, LOW);
}
void led2_4() {
    digitalWrite(led2a, LOW);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2f, HIGH);
    digitalWrite(led2g, HIGH);
    digitalWrite(led2e, LOW);
    digitalWrite(led2d, LOW);
}
void led2_5() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2f, HIGH);
    digitalWrite(led2g, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, HIGH);
    digitalWrite(led2b, LOW);
    digitalWrite(led2e, LOW);
}
void led2_6() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2g, HIGH);
    digitalWrite(led2f, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, HIGH);
    digitalWrite(led2e, HIGH);
    digitalWrite(led2b, LOW);
}
void led2_7() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, LOW);
    digitalWrite(led2e, LOW);
    digitalWrite(led2f, LOW);
    digitalWrite(led2g, LOW);
}    
void led2_8() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, HIGH);
    digitalWrite(led2e, HIGH);
    digitalWrite(led2f, HIGH);
    digitalWrite(led2g, HIGH);
}
void led2_9() {
    digitalWrite(led2a, HIGH);
    digitalWrite(led2b, HIGH);
    digitalWrite(led2c, HIGH);
    digitalWrite(led2d, HIGH);
    digitalWrite(led2g, HIGH);
    digitalWrite(led2f, HIGH);
    digitalWrite(led2e, LOW);
}
void led2_run() {
    led2_0();
    delay(1000);
    led2_1();
    delay(1000);
    led2_2();
    delay(1000);
    led2_3();
    delay(1000);
    led2_4();
    delay(1000);
    led2_5();
    delay(1000);
    led2_6();
    delay(1000);
    led2_7();
    delay(1000);
    led2_8();
    delay(1000);
    led2_9();
    delay(1000);
}

So how would I reduce the amount of pins used while still keeping functionality? I have two 74HC595N shift registers at my disposal.

Thanks!

1 Answer 1

4

I have done exactly this, to great effect.

int clockPin = 4;
int dataPin  = 2;
int oePin    = 3;

// Here are the digits from 0 to 9, as bitmaps.
// You will need to work out which segments are which,
// according to your wiring, and make your own.
unsigned char digitmaps[]={0x7b,0x11,0xe3,0xb3,0x99,0xba,0xfa,0x13,0xfb,0xbb};

void setup() {
  pinMode(clockPin,OUTPUT);
  pinMode(dataPin,OUTPUT);
  pinMode(oePin,OUTPUT);
}


void sendnumber(unsigned int number, int oePin,int dataPin,int clockPin) {
   digitalWrite(oePin,LOW);
   shiftOut(dataPin,clockPin,MSBFIRST, digitmaps[(number/10)%10]);
   shiftOut(dataPin,clockPin,MSBFIRST, digitmaps[number%10]);
   digitalWrite(oePin,HIGH);
 }

void loop() {
  for (int i=0; i<100; i++) {
    sendnumber(i,oePin,dataPin,clockPin);
    delay(1000);
  }
 }

The crux of the matter is shiftOut, which shifts 8 bits out the dataPin, toggling the clockPin as it goes, high bit first (MSBFIRST), looking up the pattern in the table. dataPin goes to serial in on the FIRST shift register, clockpin to BOTH clocks, oePin to BOTH OE and another one, I think store register? Q7' or QH' (depending on your docs - it's the overflow pin) of the first goes to the serial in of the second, and +5v & GND, as per normal, and the 8 parallel out Q0-Q7 go to the pins on the 7-segment.

If there's anything unclear, or anything I've missed, let me know. My example shows 2 digits, but any number will work, up to the available power.

Things might be clearer if I convert the digitmaps to binary. The below compiles to the same thing as the one above.

unsigned char digitmaps[]={
   B01111011, // 0
   B00010001, // 1
   B11100011, // 2
   B10110011, // 3
   B10011001, // 4
   B10111010, // 5
   B11111010, // 6
   B00010011, // 7
   B11111011, // 8
   B10111011}; // 9

This is because, in my wiring, from left to right the bits represent in the 8 on my display: center,bottom left,bottom,right bottom,top left,decimal point/not used,top,right top. You can see that the digit "1" has 2 1's in it: the 4th (right bottom) and the last (right top). An 8 has all of the bits set to 1, except position 6 - because that's the decimal point. Send individual bits (e.g. B00010000) to see which segments shows up, make a map, and then combine them.

5
  • It looks like you may have a stray semicolon after your void sendnumber function, but other than that, it looks great! Thanks for this!
    – CodeRead
    Mar 18, 2015 at 14:38
  • The code had a lot of other stuff in it, because obviously something that just counts to 99 repeatedly isn't that useful. I cut & paste bits, just quickly wrote the rest. Post edited to remove stray semicolon. I write in too many languages to keep them apart without a compiler to help me :) Mar 18, 2015 at 20:16
  • Ahh, gotcha. Could you point me in the direction of a guide to learning how to express digits "as bitmaps" as you have done? I'm not finding any relevant answers online.
    – CodeRead
    Mar 18, 2015 at 20:25
  • This is the same thing you are doing in your code, with 7 digitalWrite(ledXX, LOW); statements, but do it all in one go. Try sending 1,2,4,8,16,32,64 and 128 to figure out which segment is which, then add them together - e.g. when you send a 1, it might light up the top-right segment, 16 might be the bottom right segment, so to display a 1, you can light both of these up by sending 1+16=17. So, the number shown in my bitmap as 0x11 (the second one, as the first one is 0!), should be replaced by the number 3. I used hexadecimal as I am familiar with this; 0x11 is hexidecumal for 17. Mar 18, 2015 at 20:40
  • You could also express the same number as binary - B00010001 - each 0 or 1 will represent one segment. Which segment is which depends on which pin on the chip you connect to which wire on the display. Mar 18, 2015 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.