Pages: [1]   Go Down
Author Topic: Help needed for 7 Segment LED and 74hc595 shift register countdown project  (Read 2082 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm new to electronics and Arduino and trying to learn by doing.  So I'm attempting a 7 segment LED and 74hc595 shift register countdown project from this site:  http://www.geeetech.com/forum/viewtopic.php?p=2510&sid=599a5294b4867515cd71e2d1952d193c using the code below.   I'm using a 4 digit 7 segment display (http://www.mouser.com/Search/ProductDetail.aspx?R=HDSP-B03Evirtualkey63050000virtualkey630-HDSP-B03E) but I think I messed up the pin connections from the shift registers to the LED.  Instead of a countdown I get two dashes, then two E's, and then a succession of other nonsense.    According to the LED datasheet pin 1 is for E, 2 for D, 3 for DP, 4 for C, 5 for G, 7 for B, 10 for F, and 11 for A.  I can provide more info if needed.  Any help troubleshooting this would be greatly appreciated. 

Code:
/*
Using 2 7-segment displays with the 74HC595 shift registers
CC by-sa-nc 3.0
http://tronixstuff.wordpress.com
*/
int latchpin = 8; // connect to pin 12 on the '595
int clockpin = 12; // connect to pin 11 on the '595
int datapin = 11; // connect to pin 14 on the '595
float b = 0;
int c = 0;
float d = 0;
int e = 0;
int speed = 300; // used to control speed of counting
int segdisp[10] = {
3,159,37,13,153,73,65,27,1,9 };
void setup()
{
pinMode(latchpin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(datapin, OUTPUT);
}
void loop()
{
//  Count up
for (int z=0; z<100; z++)
{
   digitalWrite(latchpin, LOW);
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the right display
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the left display
   digitalWrite(latchpin, HIGH);
   if (z<10)
   {
     digitalWrite(latchpin, LOW);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[z]); // sends the digit down the serial path
     shiftOut(datapin, clockpin, LSBFIRST, 255); // sends a blank down the serial path to push the digit to the right
     digitalWrite(latchpin, HIGH);
   }
   else if (z>=10)
   {
     d=z%10; // find the remainder of dividing z by 10, this will be the right-hand digit
     c=int(d); // make it an integer, c is the right hand digit
     b=z/10; // divide z by 10 - the whole number value will be the left-hand digit
     e = int(b); // e is the left hand digit
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[c]);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[e]);
     digitalWrite(latchpin, HIGH);
   }
   delay(speed);
}
delay(2000);
//  Count down
for (int z=99; z>=0; z--)
{
   digitalWrite(latchpin, LOW);
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the right display
   shiftOut(datapin, clockpin, LSBFIRST, 0); // clears the left display
   digitalWrite(latchpin, HIGH);
   if (z<10)
   {
     digitalWrite(latchpin, LOW);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[z]); // sends the digit down the serial path
     shiftOut(datapin, clockpin, LSBFIRST, 255); // sends a blank down the serial path to push the digit to the right
     digitalWrite(latchpin, HIGH);
   }
   else if (z>=10)
   {
     d=z%10; // find the remainder of dividing z by 10, this will be the right-hand digit
     c=int(d); // make it an integer, c is the right hand digit
     b=z/10; // divide z by 10 - the whole number value will be the left-hand digit
     e = int(b); // e is the left hand digit
     digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[c]);
     shiftOut(datapin, clockpin, LSBFIRST, segdisp[e]);
     digitalWrite(latchpin, HIGH);
   }
   delay(speed);
}

   delay(2000);
}
Logged

Grand Blanc, MI, USA
Online Online
Faraday Member
**
Karma: 71
Posts: 3537
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The circuit and code are designed to drive two individual single digit 7-segment displays. The 4-digit display linked from Mouser must be multiplexed. Do you understand the difference?
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

"The circuit and code are designed to drive two individual single digit 7-segment displays. The 4-digit display linked from Mouser must be multiplexed. Do you understand the difference?" -- Obviously not. 

Oh well.  At least I got the displays to do something which is a moral victory at this point.  I'll look around for 4 digit display projects to cut my teeth on.
Thanks.
Logged

Grand Blanc, MI, USA
Online Online
Faraday Member
**
Karma: 71
Posts: 3537
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, well as ever, GIYF, but here's the deal. If each digit is driven directly, eight connections (seven segments plus decimal point) are needed to each digit. To make a four-digit display, 32 individual connections must be made. In a multiplexed display, the corresponding segments (a-g, dp) are all connected together, but only one digit is illuminated at a time by individually controlling the common pin for each digit in addition to the segment pins. This only requires 12 connections (8 segments plus 4 digits). Each digit is illuminated in turn, very rapidly (hundreds of times per second) and persistence of vision makes it appear that all are lit. Adding more digits only requires one more connection per digit.

A multiple-digit multiplexed display can be built from several single-digit parts, but a multiplexed display like the one you have cannot be driven directly as all the corresponding segments are connected together internally. Note on the datasheet for the four-digit display, there is only one set of segment pins A-G, where in the circuit you linked there are two sets of A-G connections.

It's important to control the current when powering an LED. The simplest way to do this is with a resistor. Each individual LED needs a resistor. So in the direct-drive situation, a four-digit display would require 32 resistors (8 per digit), where a multiplexed display requires only 8, regardless of the number of digits.

The circuit you linked is a poor example in that it tries to take a shortcut to reduce the number of resistors by putting them in the common line for each digit instead of the segment lines. This will result in uneven brightness, i.e. the individual segments will be brighter for digits like "1" where fewer segments are illuminated than for digits like "8". Here is a better schematic showing how to connect direct-drive vs. multiplexed displays with proper resistors.

You'll also want to understand the difference between common-cathode and common-anode displays.

Hope this helps. Pick up a couple single-digit units to work with that circuit. Once you've conquered that, give multiplexing a try. There are several ways to do it. It can be done directly from an Arduino, through shift registers, or with a dedicated multiplexing chip like the MAX7219 or MAX7221.
« Last Edit: November 07, 2012, 07:22:23 am by Jack Christensen » Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your explanation clears up a lot.  Especially the uneven brightness of the display. 

I was obviously trying to crowbar code and a schematic into the parts I have on hand.  But at least I know more now than I did a day ago.

I'm ultimately trying to create a timer using my 4 digit LED display.  Would the Max muliplexing chips be a better route rather than using my handful of shift registers? 
Thanks again.
Logged

Grand Blanc, MI, USA
Online Online
Faraday Member
**
Karma: 71
Posts: 3537
CODE is a mass noun and should not be used in the plural or with an indefinite article.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sure, you bet!

Somewhat similar thread here, but it's about an LED matrix, not 7-segment displays, which really isn't different electrically:
http://arduino.cc/forum/index.php/topic,127499.0.html

But search around the forum here, there are bound to be others.

There are various possibilities. An Arduino is perfectly capable of driving the four-digit display directly, although at the cost of programming complexity -- you'd need to program the multiplexing process. Also, I'd use some transistors for digit drivers so as not to exceed the I/O pins' current limit. It could be driven with one shift register (for the segments) and transistors for digit drivers, or with two shift registers of proper current capacity (the Arduino would still need to control the multiplexing). Last but not least, the MAX72xx is a great chip, and there are libraries available to ease the interfacing.

So lots of opportunities to experiment, hope you have fun! smiley
Logged

MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Pages: [1]   Go Up
Jump to: