Go Down

Topic: Help Controlling every single LED in a LED Matrix with Shift Register(74HC595) (Read 228 times) previous topic - next topic

pradoartz

Hello,
I am working in a badminton scoreboard project, i have hand-coded some coding to suit my need. I am using a counter program to counts the score's up and down.
I designed my own counter theory for the scoreboard.
Basically the counter starts with 0000 [first two 00 for home scores and last two 00 for away score]
When we counts the score for home team the counter increases the counter value with 100. So now the value of the counter changes to 0100. [01 for home team and 00 for away team].
If i count the score of the away team then the counter values will be increased by 1. So now the value will be like 0101 [ first 01 will be the score of the home team and last 01 is the score of the away team] Respectively it increases from 0000 to 2121. Using "% and /" I am separating the four digits value from the  counter to 4 single digits and store it in to 4 variables a,b,c,d.
eg: If the value of the counter is 1320.. i splits and save it as a=1;b=3;c=2;d=0; respectively.

The code is below, haven't completed it totally, but its working perfectly in serial monitor.
Code: [Select]
//Initialize the push buttons pins, push buttons states, and the counter
unsigned int counter     = 0;
int switchUpPin1         = A0;
int switchDownPin1       = A1;
int switchUpPin2         = A2;
int switchDownPin2       = A3;
int switchReset          = A4;
int buttonUpState1       = 0;
int lastButtonUpState1   = 0;
int buttonDownState1     = 0;
int lastButtonDownState1 = 0;
int buttonUpState2       = 0;
int lastButtonUpState2   = 0;
int buttonDownState2     = 0;
int lastButtonDownState2 = 0;
int buttonReset          = 0;
int lastButtonReset      = 0;
int a  = 0;
int b  = 0;
int c  = 0;
int d  = 0;
int e  = 0;
int f  = 0;
//Relay Pin for last segment//
int r1 = 2;
int r2 = 3;
int r3 = 4;
int r4 = 5;
int r5 = 6;
int r6 = 7;
int r7 = 8;

void setup()
{
Serial.begin(9600);
pinMode(r1, OUTPUT);
pinMode(r2, OUTPUT);
pinMode(r3, OUTPUT);
pinMode(r4, OUTPUT);
pinMode(r5, OUTPUT);
pinMode(r6, OUTPUT);
pinMode(r7, OUTPUT);
}

void loop()
{
buttonUpState1   = digitalRead(switchUpPin1);
buttonDownState1 = digitalRead(switchDownPin1);
buttonUpState2   = digitalRead(switchUpPin2);
buttonDownState2 = digitalRead(switchDownPin2);
buttonReset      = digitalRead(switchReset);

//Do this for the button (A0) - increases the counter by 1
if (buttonUpState1 != lastButtonUpState1)
{
if (buttonUpState1 == HIGH)
{
if(counter == 21 || counter ==  121 || counter == 221 || counter == 321 || counter == 421 || counter == 521 || counter ==  621 || counter == 721 || counter == 821 || counter ==  921 || counter == 1021 || counter == 1121 || counter == 1221 || counter == 1321 || counter == 1421 || counter == 1521 || counter == 1621 || counter == 1721 || counter == 1821 || counter == 1921 || counter == 2021 || counter == 2121)
{
counter = counter;
}
else
{
counter++;
}
changeNumber(counter);
delay(250);
}
else
{
Serial.println("OFF");
}
delay(250);
}

//Do this for the button (A1) - decreases the counter by 1
if (buttonDownState1 != lastButtonDownState1)
{
if (buttonDownState1 == HIGH)
{
if(counter == 0 ||counter == 100 || counter ==  200 || counter == 300 || counter == 400 || counter == 500 || counter == 600 || counter ==  700 || counter == 800 || counter == 900 || counter ==  1000 || counter == 1100 || counter == 1200 || counter == 1300 || counter == 1400 || counter == 1500 || counter == 1600 || counter == 1700 || counter == 1800 || counter == 1900 || counter == 2000 || counter == 2100)
{
counter = counter;
}
else
{
counter--;
}
changeNumber(counter);
delay(250);
}
else
{
Serial.println("OFF");
}
delay(250);
}

//Do this for the button (A2) - increases the counter by 100
if (buttonUpState2 != lastButtonUpState2)
{
if (buttonUpState2 == HIGH)
{
if(counter == 2100 || counter ==  2101 || counter == 2102 || counter == 2103 || counter == 2104 || counter == 2105 || counter ==  2106 || counter == 2107 || counter == 2108 || counter ==  2109 || counter == 2110 || counter == 2111 || counter == 2112 || counter == 2113 || counter == 2114 || counter == 2115 || counter == 2116 || counter == 2117 || counter == 2118 || counter == 2119 || counter == 2120|| counter == 2121)
{
counter = counter;
}
else
{
counter=counter+100;
}
changeNumber(counter);
delay(250);
}
else
{
Serial.println("OFF");
}
delay(250);
}

//Do this for the button (A3) - decreases the counter by 100
if (buttonDownState2 != lastButtonDownState2)
{
if (buttonDownState2 == HIGH)
{
if(counter == 0 ||counter == 1 || counter ==  2 || counter == 3 || counter == 4 || counter == 5 || counter == 6 || counter ==  7 || counter == 8 || counter == 9 || counter ==  10 || counter == 11 || counter == 12 || counter == 13 || counter == 14 || counter == 15 || counter == 16 || counter == 17 || counter == 18 || counter == 19 || counter == 20 || counter == 21)
{
counter = counter;
}
else
{
counter=counter-100;
}
changeNumber(counter);
delay(250);
}
else
{
Serial.println("OFF");
}
delay(250);
}

//Do this for the button (A4) - Reset Counter Values to Zero
if (buttonReset != lastButtonReset)
{
if (buttonReset == HIGH)
{
counter=0;
changeNumber(counter);
delay(250);
}
else
{
Serial.println("OFF");
}
delay(250);
}
changeNumber(counter);
}

void changeNumber(int i)
{
if((i==1)||(i<=9))
{
a=0;
b=0;
c=0;
d=i;
if(d==1)
{
digitalWrite(r1, HIGH);
digitalWrite(r2, LOW);
digitalWrite(r3, LOW);
digitalWrite(r4, HIGH);
digitalWrite(r5, HIGH);
digitalWrite(r6, HIGH);
digitalWrite(r7, HIGH);
}else
if(d==2)
{
digitalWrite(r1, LOW);
digitalWrite(r2, LOW);
digitalWrite(r3, HIGH);
digitalWrite(r4, LOW);
digitalWrite(r5, LOW);
digitalWrite(r6, HIGH);
digitalWrite(r7, LOW);
}else
{
//Deleted some code since the forum cant post, if more than 9000 Char
}
Serial.print("a=");
Serial.println(a);
Serial.print("b=");
Serial.println(b);
Serial.print("c=");
Serial.println(c);
Serial.print("d=");
Serial.println(d);

} else if((i==10)||(i<=21))
{
a=0;
b=0;
c=i/10;
d=i%10;
Serial.print("a=");
Serial.println(a);
Serial.print("b=");
Serial.println(b);
Serial.print("c=");
Serial.println(c);
Serial.print("d=");
Serial.println(d);
} else if((i==100)||(i<=921))
{
a=0;
b=i/100;
e=i/10;
c=e%10;
d=i%10;
Serial.print("a=");
Serial.println(a);
Serial.print("b=");
Serial.println(b);
Serial.print("c=");
Serial.println(c);
Serial.print("d=");
Serial.println(d);
} else if((i==1000)||(i<=2121))
{
a=i/1000;
f=i/100;
b=f%10;
e=i/10;
c=e%10;
d=i%10;
Serial.print("a=");
Serial.println(a);
Serial.print("b=");
Serial.println(b);
Serial.print("c=");
Serial.println(c);
Serial.print("d=");
Serial.println(d);
} else
{
a=0;
b=0;
c=0;
d=0;
Serial.print("a=");
Serial.println(a);
Serial.print("b=");
Serial.println(b);
Serial.print("c=");
Serial.println(c);
Serial.print("d=");
Serial.println(d);
}
}



If i am using an arduino mega, it got more digital output pin, So I can call any PIN i want to be high and low according to the values stored in the variables a,b,c,d using if statement or switch case. Its easy with my current code. But my question is, it is possible to connect 28 relays(Every segment will powered using a 12v 3 watt LED) or TIP122 to an arduino uno using shift register(4 * 74HC595).. Since I am seeing videos in youtube that we can connect to 32 Output from 4 shift register with only using 4 output from Arduino Uno. And if we can do it can i access each and every output from the shift register as like the output pin from arduino mega, like controlling every output from the 4 shift register using,
Code: [Select]

//Totally for example purpose
if(a==1)
{
make pin D3,D8 from 1st 74HC595  to HIGH
make pin D2,D8 from 3rd 74HC595  to HIGH
} else if(a==2)
{
...................
...............
}


I have used the term "LED Matrix, control LED" in the topic of this post, because the logic is the same. If i can control LED then obvio i can control Relays...
 
Thanks.

vaj4088

pradoartz wrote (in part):

Quote
my question is, it is possible to connect 28 relays(Every segment will powered using a 12v 3 watt LED) or TIP122 to an arduino uno using shift register(4 * 74HC595).
For relays:
Sure, if each output of the shift registers is sufficient to drive each relay.  You will also need something (usually a diode per relay) to prevent the EMF 'kickback" from each relay coil from destroying an output of the shift registers.

For TIP122 transistors:
Sure, but you will need a resistor in series with the base of each transistor to avoid excessive current into the base.  I would guess that about 1000 ohms (also known as 1K) would be sufficient.  I have not looked at whether a heatsink would also be required.


pradoartz

pradoartz wrote (in part):

For relays:
Sure, if each output of the shift registers is sufficient to drive each relay.  You will also need something (usually a diode per relay) to prevent the EMF 'kickback" from each relay coil from destroying an output of the shift registers.

For TIP122 transistors:
Sure, but you will need a resistor in series with the base of each transistor to avoid excessive current into the base.  I would guess that about 1000 ohms (also known as 1K) would be sufficient.  I have not looked at whether a heatsink would also be required.
Please read my full question

Can i access each and every output from the shift register as like the output pin from arduino mega, like controlling every output from the 4 shift register using,
Code: [Select]

//Totally for example purpose
if(a==1)
{
make pin D3,D8 from 1st 74HC595  to HIGH
make pin D2,D8 from 3rd 74HC595  to HIGH
} else if(a==2)
{
...................
...............
}

Can anyone post a small code using two 74HC595 and it gives the output from the function compares with switch case. Example: simply declare int i=(1-10). Switch 1 case:{ pin q2 from 1st 74595 and pin q7 from 2nd 74595 to high and all other output pin from both 1st and 2 nd 74595 to low. }. Switch 2 case:{pin q1 from 1st 74595 and pin q3 from 2nd 74595 to high and all other output pin from both 1st and 2 nd 74595 to low.} switch 3 ..................,....


Thanks

PaulRB

The answer to your question is yes.

To make your display circuit easier, consider tpic6a595 instead of 74hc595. Then you will not need any transistors.

If you cannot get tpic6a595, then you can use smaller transistors such as bc337 with 1K base resistors.

For controlling the shift registers, have a look at the bitWrite() and shiftOut() Arduino functions.

To avoid writing long and repetitive code, avoid case statements in favour of arrays, for() loops and encode your digit patterns in binary format.

CrossRoads

You will have 4 shift registers, 1 for each digit, yes? (either sinking current directly, or driving a relay, or more smartly controlling a current-controlled driver for each LED so they don't overheat and do into thermal runaway and burn themselves up).

Then all you need is a simple fontArray that maps the digit to be displayed to the segments to be turned on.
Code: [Select]

byte fontArray[] = {
0b00111111, // 0  DP-g-f-e-d-c-b-a, 1 = segment on
0b00000110, // 1
//etc
0b01101111, // 9
};

   a
f     b
   g
e     c
    d       DP if used
To send the data, daisy chain the 4 shift registers:
Code: [Select]

digitalWrite (latchPin, LOW); // SRCK from SS pin (D10 on Uno)
SPI.transfer(fontArray[byte0]); // SCK to SRCLK, MOSI to 1st chip's DIN, daisy DOUT to next chip
SPI.transfer(fontArray[byte1]);
SPI.transfer(fontArray[byte2]);
SPI.transfer(fontArray[byte3]);
digitalWrite (latchPin, HIGH); // SRCK, outputs update on this rising edge


It's that simple.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up