# 4 digit 7 segment display

hey guys!
I am actually trying to create a digital clock using the 7 segment display, since its easier to see and more appealing to the eyes. Now before jumping straight into the clock I wanted to learn working with the 4 digit 7 segment display using the 74hc595 shift register (i am using a common anode type display).

I am controlling this display using 2 shift registers. the q7 (of 1st shift register) controls the 1st digit q0 of second controls the 2nd digit q1 controls the 3rd digit and q2 controls the 4th digit.

What I am trying to achieve now is to display numbers 0-9 in a manner that it displays one number 7 segment and the next number is displayed on the next. i.e 0 in the 1st digit, 1 in the second digit, so on 3 in the 4 th digit and 4 back on the 1st digit. In this sequence number 9 ends up on the second digit. Here is where the problem starts.

I want the next zero in the 3rd digit place and move on in the same patters, instead of the going back to the 1st digit. this is the code I have made up so far.

``````int latchPin = 2; //pin 12 on the 595
int dataPin = 3; //pin 14 on the 595
int clockPin = 4; //pin 11 on the 595
int shift = 128;
void setup() {
//Serial.begin(9600);
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}

void loop() {

//0
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift + 64 );
digitalWrite(latchPin, HIGH);
delay(500);

//1
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 121);
digitalWrite(latchPin, HIGH);
delay(500);

//2
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 36);
digitalWrite(latchPin, HIGH);
//Serial.println("2 is printed");
delay(500);

//3
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 48);
digitalWrite(latchPin, HIGH);
delay(500);

//4
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift + 25);
digitalWrite(latchPin, HIGH);
delay(500);

//5
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 18);
digitalWrite(latchPin, HIGH);
Serial.println("5 is printed");
delay(500);

//6
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 2);
digitalWrite(latchPin, HIGH);
delay(500);

//7
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 120);
digitalWrite(latchPin, HIGH);
delay(500);

//8
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift + 0);
digitalWrite(latchPin, HIGH);
delay(500);

//9
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 64 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 16);
digitalWrite(latchPin, HIGH);
delay(500);
shift = shift * 4;
}
``````

I am able to display uptill 9 and the next zero and 1 in the 3rd and 4th digits but there after the numbers just shift outside the scope and nothing is displayed. since the count goes beyond 1024, like 2048, 4096, and so on, i need an idea to convert 2048 so that i can correspond it to 1st digit , similarly 4096 to second digit. and so on. I hope I have made my problem clear! any help is appreciated!

Could you please post a wiring diagram?

Possibly part of the problem might be that you are sending an integer to a library function that is expecting a byte, which cannot be over 255. I don't know if the function truncates the integer down to a byte or if it just starts using the most significant part of the integer since you specified MSBFIRST.

shift + 64 >> 8

Why do you add 64 if you shift it to the right 8 bits? The 64 doesn't do anything.

Due_unto:
Possibly part of the problem might be that you are sending an integer to a library function that is expecting a byte, which cannot be over 255. I don't know if the function truncates the integer down to a byte or if it just starts using the most significant part of the integer since you specified MSBFIRST.

He shifts his most significant byte 8 bits to the right, so that shouldn't be a problem. ShiftOut will just use the 8 least significant bits to send.

Would it not make your programming a lot easier if you use the second shift register just for digit position and the first shift register just for segment and do away with trying to split the digit position between the two shift registers? In other words, move the three connections of shift register 2 to the right by 1 and move the connection from shift register 1 q7 to shift register 2 q0.
This way on the first shift out send a 1, 2, 4, or 8 for digit position and on the second shift out just send the segment pattern.

Due_unto:
Would it not make your programming a lot easier if you use the second shift register just for digit position and the first shift register just for segment and do away with trying to split the digit position between the two shift registers? In other words, move the three connections of shift register 2 to the right by 1 and move the connection from shift register 1 q7 to shift register 2 q0.
This way on the first shift out send a 1, 2, 4, or 8 for digit position and on the second shift out just send the segment pattern.

As you say I did it. and changed the shift value to 256. but how would that make my program any simpler? I dont know how to show you the wiring diagram. Let me figure something out, but by the looks of it you seem to have understood fine.

Hey everyone!
I have kept the previous problem aside just for the time being. My new goal is to display 4 digit numbers on the 7 segment display. I will be giving the numbers in the program itself, not serially. So i came up with a code, which is of course is not optimum, but one thing very peculiar that I noticed was that whenever there is a digit 5 in the number that I give that digit displaying 5 becomes brighter than the rest. Be it in the units, or tens or hundreds or thousands. Whats worse is that when I gave 5555 the display started flickering. Nothing like this happens with any other digit and when there are any other digits, everything is evenly bright and there is no flickering. I will attach my code below. please bear with my sloppiness.

``````int latchPin = 2; //pin 12 on the 595
int dataPin = 3; //pin 14 on the 595
int clockPin = 4; //pin 11 on the 595
int shift = 256;
int number = 8444;
int units;
int tens;
int hundreds;
int thousands;
int x;
int y;
void setup()
{
Serial.begin(9600);
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}

void loop()
{

if (number > 9 && number < 100)
{
units = number % 10;
tens = number / 10;
}
else if ( number > 99 && number < 1000)
{
units = number % 10;
x = number / 10;
tens = x % 10;
hundreds = x / 10;
}
else if ( number > 999 && number < 10000)
{
units = number % 10;
x = number / 10;
tens = x % 10;
y = x / 10;
hundreds = y % 10;
thousands = y / 10;
}
else
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 64 );
digitalWrite(latchPin, HIGH);
}

switch (units)
{
case 0:
//0
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 64 );
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 1:
//1
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 121);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 2:
//2
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 36);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 3:
//3
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 48);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 4:
//4
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 25);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 5:
//5
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 18);
digitalWrite(latchPin, HIGH);
Serial.println("5 is printed");
//delay(500);
break;
case 6:
//6
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 2);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 7:
//7
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 120);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 8:
//8
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 0);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 9:
//9
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 16);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
}
delay(1);

switch (tens)
{
case 0:
//0
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 64 );
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 1:
//1
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 121);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 2:
//2
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 36);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 3:
//3
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 48);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 4:
//4
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 25);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 5:
//5
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 18);
digitalWrite(latchPin, HIGH);
Serial.println("5 is printed");
//delay(500);
break;
case 6:
//6
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 2);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 7:
//7
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4   >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 120);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 8:
//8
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 0);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
case 9:
//9
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4  >> 8 );
shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 16);
digitalWrite(latchPin, HIGH);
//delay(500);
break;
}
delay(1);
``````

I have included only the code for 2 digits but the hundreds and thousands code is also similar.