Arduino Forum

Forum 2005-2010 (read only) => Software => Interfacing => Topic started by: guitarboy667 on Dec 06, 2010, 08:41 pm

Title: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 06, 2010, 08:41 pm
Hey everyone, I was wondering if someone could help me figure out how to wire and eventually program two 7-segment displays of 4 digits each. I'd like to learn about it as I go.

Here is the data sheet for the 7-segment displays:
http://www.us.kingbright.com/images/catalog/SPEC/SA18-11EWA.pdf

I'll be using an Arduino Mega, but I assume I'll need bit registers or something like that? Thanks for your help!
Title: Re: 7-Segment Display Wiring and Programming
Post by: BKnight760 on Dec 06, 2010, 09:43 pm
7 Segment displays are fairly easy.

You'll need 7 I/O pins for each digit if you do it without an additional components.

Otherwise, pick up a shift register from Sparkfun.  You can then drop the I/O requirements significantly.

The datasheet shows that each of the seven segments on the display are labeled as a,b,c,d,e,f,g and dp (decimal point).  Apply a voltage to pin 1 or 5, and the apply a voltage to the pin for the segment which you want to turn on.  Pretty easy.

The trickier part will be wiring up your shift registers correctly, as you'll have a mess of wires for 8 digits (8x7 = 56 wires minimum).

You'll likely need to write some code that extracts a single decimal digit from an integer and figures out which display it goes on.
Title: Re: 7-Segment Display Wiring and Programming
Post by: simon.monk on Dec 07, 2010, 03:49 pm
Hi, there is 2 digit 7-segment display example in my book.

http://www.arduinoevilgenius.com
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 08, 2010, 07:55 pm
So apply a voltage to the segment I want to light up and have it all connected to a common ground? Does the Arduino even have enough power/current for this?

How would I wire it with a shift register and which should I use?
Title: Re: 7-Segment Display Wiring and Programming
Post by: simon.monk on Dec 08, 2010, 09:43 pm
The mega has lots of pins for this, you can use a pin per segment.

It can also provide up to 40mA per output, so thats fine too as you should probably aim for about 10mA per segment.

You will need a series resistor for each segment.
Title: Re: 7-Segment Display Wiring and Programming
Post by: BKnight760 on Dec 08, 2010, 11:25 pm
Quote
How would I wire it with a shift register and which should I use?


Here's a shift register from Sparkfun... costs about $1.50
http://www.sparkfun.com/products/733

Read the datasheet on it and it will explain how to use it.

Basically, you connect it to the serial connection on your board, and then supply it with power and ground.  Each time you send a byte on the serial connection, it shifts it into the register (1 byte = 8 bits).  Until you send it another byte, those 8 bits will remain set.  So, you just send a byte representing the digital outputs you want to turn on/off.

Code: [Select]

Hex       Binary
0xFF = 11111111       This turns all 8 outputs of the shift register on.
0x00 = 00000000       This turns all 8 outputs of the shift register off.
0xAA = 10101010       This turns every-other output on.


So, now, all you have to do is connect each of the 8 shift register outputs to one of the segments on your display.  (Remember to connect the display to ground as well.)
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Dec 09, 2010, 07:02 am
The datasheet you submitted is for a common anode part.
If this was a typical 7-segment display, the way it is usually used is that the commone anode, pins 1&5, are connected to 3.3V or to 5v.
Then a current limiting resister of say 330 ohm is connected from each of the segment leads to an output pin on the arduino (or, to a shift register output pin). When the pin is low, the segmet will turn on. When the output is high, it will turn off (as both sides of the LED are now high).

However, your part has 3 LEDs per segment, so it will need a higher voltage, the spec sheet shows 6-7.5.
For that you will need a part that can withstand a higher off voltage and not be damaged, such as
a tpic6b595 open drain shift register, which can take 50V.  Or, put an NPN transistor at the bottom of each cathode, which is basically what the output of the tpic6b595 has.

There are some other open collector/open drain parts as well.

(http://www.crossroadsfencing.com/LED_shift_driver.jpg)
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 10, 2010, 08:24 pm
I'm sorry, but that last explanation went a bit over my head. I think I understand how the shift register works. I'd still have to figure out how to convert the numbers that have been calculated into signals to be sent to the shift register though.

So I won't be able to power the 7-segment displays with the Arduino no matter what? That's fine, but the diagram confused me. Is there 2 shift registers per digit or are those the digits themselves? I think I see transistors there, so that would make them seem like the digits, right? Can all 8 be hooked up off that 18 volt power supply? Idk what the D arrow things are and I'm still working on calculating the resistance there. Sorry for all the questions. I'm trying to get it.

Also I believe the Arduino mega has only 4 (or is it 3) transmitting serial pins. Is there a way around this? I know that Sparkfun has a 4 digit display hooked up to a single serial output, but I wanted larger digits.
Title: Re: 7-Segment Display Wiring and Programming
Post by: MarkT on Dec 10, 2010, 11:59 pm
Quote


Here is the data sheet for the 7-segment displays:
http://www.us.kingbright.com/images/catalog/SPEC/SA18-11EWA.pdf

Those LEDs take over 7.5V to drive - do you realise this?  The common anodes will require a driver circuit each that takes logic levels up to the appropriate supply voltage (9V would be an obvious choice).  LED displays compatible with 5V are much simpler to drive.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Dec 11, 2010, 12:48 am
Okay, I may have two posts mixed up. But not totally. I had 6 LEDs strings & 18V supply on the mind from something else.

Did you look at the internal schematic for your part? The segments all have 3 LEDs in series. 5V from an arduino will not be enough to turn them on.  You will need to apply a voltage of >6V to  pins 1&5 for all the digits, then individually apply a logic low (close to 0V) to turn an individual segment on.
(http://www.crossroadsfencing.com/kingbright_SA18-11EWA.jpg)

When a segment is not on, the bottom of the last LED will go up to whatever voltage you are suppying them with and blow up the output of the arduino or standard shift register if that is above 5V.

To turn the segments on, you will use the shiftout command with 1s & 0s.
The shiftout command looks like this
shiftOut(shiftdataout, serialclock, MSBFIRST, outdata);
where shiftdataout is the pin that data is coming from on the arduino.
serialclock is the clock line from the arduino,
MSBFIRST indidatces bit 7 goes first,
and outdata is the 8 bits you want sent out.

If for example your shift register bits were wired like this:
Output 0 = segment A
O1 = B
O2 = C
O3 = D
O4 = E
O5 = F
O6 = G
O7 = decimal point

Thus to send out a "1" character, you set outdata to
(bit # / segment -on/off)
0/a-off
1/b-on
2/c-on
3/d-off
4/e-off
5/f-off
6/g-off
7/dp-off

outdata would be set to 0b11111001 if you had a shift register that could handle >5V on its outputs,  such as the tpic6b595. The 2 zero bits would result in low outputs for O2 & O3 to turn on segments B & C.
On the other hand, if you used a standard shift register and added transistors to its outputs to control the LEDs instead, such as the last schematic I posted (where I showed 6 LEDs instead of 3 by accident), then you would shift in 1's to turn on the transistors; outdata would be set to 0b00000110.  The two 1 bits would turn on the 2 transistors for segments B & C and turn them on.

You will need 1 shift register per digit. The >6V supply will go to pins 1&5 on all the digits.

Another option is to put a part like an 74LS47 in there, which can work with up to 15V.
A shift register could supply 4 bits to each of two 74LS47s.  The '47s will decode the 4 bits into 15 characters (plus a blank state), so you coud just shift out a "1" and it will show up as 1, "2" for a 2, etc. and hex "f" to blank the display. However, you are stuck with the decode that is built in.  If you wanted characters that looked like some letters (E, h, P, n, L, A, J, C or c, etc.) you're better off with the shift register so you have more control.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 11, 2010, 07:09 pm
But I'd need to use the serial outputs one per digit if I used shift registers right?
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Dec 12, 2010, 02:40 am
1. You could shift out to each shift register individually (have  the data line and the clock line common to all parts, with unique load or enable lines).  Takes 10 arduino output lines.
2. You could have the data shift thru all the parts (output becomes the input to the next) and then shift out the 64 bits of data for all of them every time. Uses less pins that way. Takes 3 output arduino lines.
3. Another option is to use a MAX7221, which combines both these approaches - it has additional logic so that you are only shifting out to 1 part (uses the SPI format, ties up 4 specific output pins, D10-11-12-13).  The registers are individually addressable (you shift out an address and then the data for that address). However, it won't do 6-7.5v outputs.
You would have to add two sets of transistors - one set to switch on the 7.5V to each digit's common anode, and one set to switch the common segments lines to ground.
See Figures 1 & 4 in this application note:
http://www.maxim-ic.com/app-notes/index.mvp/id/1196
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 12, 2010, 04:18 am
So an output line would be a pin? If I don't need to use the serial pins for this then I don't mind taking a lot of output pins since I'm using an Arduino Mega. 10 pins would be fine, but if you need to use a serial pin to send data to the shift register then I don't believe there is enough on the Arduino Mega.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 12, 2010, 04:18 am
Thanks a ton for your help btw!
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Dec 12, 2010, 05:20 am
You will not be using the Serial Rx/Tx lines, just regular I/O lines.
Define a pin as the common data output line.
Define a pins as the common shift clock line.
Define 8 pins as the unique Strobe, or Load, or whatever it is called for the 595 variant that you are using.

Glad to help. Talking others thru these helps me get things clear in my mind for my designs as well. I don't have any shift registers handy, so I am wiring up a 74F374 as shift registers, which also comes in handy for driving (single) LEDS per output (with current limit resister) directly.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 23, 2010, 08:06 am
So would 4 AA or similar batteries in series be a suitable power source? I saw the voltage is typically 6 volts per segment.

That would have a ~3 A current? So then a resistor of roughly 2 Ohm? That can't be right.

So then I have a wire going from each of the segments to the shift register (which pins of the register?). I have one wire going from the Arduino to the shift register. I have a common ground that would connect to the battery, the 7 segment, and the Arduino. Could I get away with a resistor only between the battery and the 7-segment display? Is that how it is connected?
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Dec 23, 2010, 09:26 am
4 AAs would probably be marginal, as soon as they dropped a little you'd be out of voltage. 5 would be okay. You could power the arduino from batteries 1-3 (4.5V into VCC, not Vin), and the segments from batteries 1-5 (7.5v). I have used 3 AAs like this, the arduino was still going well at 4.25V.
So if you had 5 batteries, thats 7.5V, less say 6.5V for a segment, that's 1V across the resistor and transistor of the shift register, so you'd see maybe 0.5V across the resister.
So with ohms law, V=IR, V/I = R => 0.5V/0.02A = 25 ohms. 27 or 33 are  standard values.
You need a resister per segment of each LED if you are using shift registers. More below on why 1 resister per segment.
If you had all segments on in 1 digit, that would be 140mA.
How many digits were you planning on? I don't recall.

You have 3 wires going from the arduino to the shft registers, assuming you have the output of one shift register feeding the input of the next.  The shift_out_clock goes to each part. The shift_data_out goes to part1, its output goes to part 2, etc.
To prevent a bunch of flickering while all this shifting is going on, you also have a load_data line that moves the data from the input shift register to the output drive pin so all the displays update at once.   Then you shiftout bytes until all digits are shifted, and toggle the load line to update the outputs.
The other option is to use more wires, and shift to each digit individually.
Have a common shift_data_out, shift_clock, but individual load_data to each part for the actual output update.

Wire up your shift register - which one are you using? tpic6b595 open drain shift register, which can take higher output voltages (the voltage will go up to the battery voltage when the pin is high)? Or a standard TTL/CMOS part, in which case you will need an NPN transistor like I showed in an earlier post.
Select the mapping you want to use, maybe this:
bit 7 = decimal point
bit 6  = segment G
bit 5 = F
bit 4 = E
bit 3 = D
bit 2 = C
bit 1 = B
bit 0 = segment A
Then to turn on a segment, a bit = LOW will equal a segment turned on for the tpic6b595,
or if the shift register drives a transisor as shown earlier, a bit = HIGH will equal a segment turned on.
Lets go with HIGHs:
for #1, data out for a shift register would be 0B00000110 for segments B & C
for #0, 0B00111111 for segments A,B,C,D,E,F
for #7, 0B00000111 for segments A,B,C and so on.
for L,   0B00111000 for segments D,E,F, and so on.

You have 7.5V  going to the common ANODE of each digit, the segments go thru resistors to the shift register, the battery- goes to the arduino ground.
You could try just 1 resister between the 7.5V and the ANODE of each digit, but you will find the segments changing brightness as the different segments turn on & off. 1 or 2 segments vs 5,6,7 segments all sharing the same 20mA, you see? And you have to limit for the least amount of segments on so you don't burn it out.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Dec 26, 2010, 11:32 pm
I will be using 8 digits. There will be two different 4-digit numbers, so essentially two different displays, so I think it'd be easier as far as programming is concerned to wire those two separately?

I have the 9 volt pack thing for the Arduino.

So I think I follow all that. I may just wire each individually, but idk which would be easier to code. I have a keypad that the user inputs numbers on and I want to display the user's input on the display one number at a time, so they know that their input has been registered. I also need to simply display 4 digit numbers arrived at in different parts of the code as well. Whichever wiring would work best for that would be good.

At this point I supposed I'll just need to translate the input and calculated digits into outputs for the display. With the user input I could have several if then statements that say, for example, if button "1" is pressed then output
for #1, data out for a shift register would be 1B11111001 for segments B & C, but that seems a little sloppy.

Then the other portion will be converting say 3097 into data to be sent to the shift register.

I was planning on using the tpic6b595 open drain shift register you suggested.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Dec 27, 2010, 12:10 am
"9 volt pack thing" what is that? The 9V wallwart?

With the mega, you have plenty of IO, you can have separate control pins for each shift register.

Take a look at this code. I totally do not get how the first highlighted part sets up the shift register for the second highlighted part to display digits, but am told it works.

Code: [Select]

unsigned long currentmillis = 0;
unsigned long previousmillis = 0;
unsigned long interval = 10;

int latchpin = 8; // connect to pin 12 on the 74HC595
int clockpin = 12; // connect to pin 11 on the 74HC595
int datapin = 11; // connect to pin 14 on the 74HC595

int ones_seconds = 0;
int tens_seconds = 0;
int ones_minutes = 0;
int tens_minutes = 0;
int tenths = 0;
int hundredths= 0;

[glow]int segdisp[10] = {
 63,6,91,79,102,109,125,7,127,111 }; //segment references using 74HC595 Shift Registers
//The above numbers light up different segments of a digit[/glow]
int time_update = 0;// added new flag
void setup()
{
 pinMode(latchpin, OUTPUT);
 pinMode(clockpin, OUTPUT);
 pinMode(datapin, OUTPUT);
}

void loop()
{
 currentmillis = millis();  // read the time.
 if (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by
 {
   previousmillis  = currentmillis;  // save the time for the next comparison

   time_update = 1;  
 }  // set flag to upate & shift out

 if (time_update == 1){  // no updating if not at 10ms interval, skip this whole section
   // increment the counters, roll as needed, shift the digits out
   time_update = 0; // reset for next pass thru

   hundredths = hundredths +1;
   if (hundredths == 10){
     hundredths = 0;
     tenths = tenths +1;
   }

   if (tenths == 10){
     tenths = 0;
     ones_seconds = ones_seconds +1;
   }

   if (ones_seconds == 10){
     ones_seconds = 0;
     tens_seconds = tens_seconds +1;
   }

   if (tens_seconds == 6){
     tens_seconds = 0;
     ones_minutes = ones_minutes +1;
   }

   if (ones_minutes == 10){
     ones_minutes = 0;
     tens_minutes = tens_minutes +1;
   }
   if (tens_minutes == 10){
     tens_minutes = 0;
   }

[glow]    // counters are all updated now, just do the shiftout one time here:
   digitalWrite(latchpin, LOW); // send the digits down to the shift registers!
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the % first "hundredths" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tens of hundredths digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print the % first "seconds" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens of seconds digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the % first "minute" digit
   shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens of minutes digit
   digitalWrite(latchpin, HIGH);[/glow]
 } // end if time to be updated

} // end void loop

Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 01, 2011, 08:13 pm
http://www.sparkfun.com/products/734

Is this the shift register you recommend?
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 01, 2011, 09:47 pm
Yes - altho you can find it less expensively if you look around.
Example,
http://parts.digikey.com/1/parts/527098-ic-pwr-8-bit-shift-regis-20-dip-tpic6b595n.html
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 08, 2011, 10:48 pm
Alright, so I think I understand the wiring. I just want to tackle this stage before I start code.

So is the 1 pin of the 7-segment display the positive and the 5 the negative or vice versa?

Or are both positive? I think it's that, right?

So then the wiring for the rest of the 7-segment is, for example,
DRAIN0 (on shift register)-33 OHM Resistor-Pin 7 on 7-segment display

(The batteries I'm using actually are 1,500 mAh)

I have a common ground to the shift register (just to one of the GND pins, right?), battery pack, and Arduino.

So the SER IN is the shift_data_out line and SER OUT goes to the next SER IN.

I assume that the pins of the Arduino for the shift_data_out line, shift_out_clock line, and the load_data line don't matter?

I think I'm just a bit confused about those 3 lines in general.

I believe I understand the shift_data_out line.

What pins on the shift register does the shift_out_clock line and  load_data line go to?



Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 09, 2011, 11:50 pm
Answers mixed in below:

So is the 1 pin of the 7-segment display the positive and the 5 the negative or vice versa?
Or are both positive? I think it's that, right?
>> Both pins 1 & 5 go to the positive of the supply.  They are internally connected on the device.


So then the wiring for the rest of the 7-segment is, for example,
DRAIN0 (on shift register)-33 OHM Resistor-Pin 7 on 7-segment display
>> Yes.

(The batteries I'm using actually are 1,500 mAh)
>> If you have all 7 segments of a digit on, that's 7 x 20mA = 140mA, I don't remember how many digits you have altogether. 4? Then if you all 4 displaying "8888" you can expext to draw 560mA, you will get maybe 3 hours of life form 1500mA batteries.  Most likely longer as you will have fewer segments on at any one time.

I have a common ground to the shift register (just to one of the GND pins, right?), battery pack, and Arduino.
>> Connect all 3 grounds from the shift register.

So the SER IN is the shift_data_out line and SER OUT goes to the next SER IN.
>> Yes.

I assume that the pins of the Arduino for the shift_data_out line, shift_out_clock line, and the load_data line don't matter?
>> Correct.

I think I'm just a bit confused about those 3 lines in general.

I believe I understand the shift_data_out line.

What pins on the shift register does the shift_out_clock line and  load_data line go to?
>> shift_out_clock goes to SRCK
>> load_data  goes to RCK
>> Low on SRCLR will clear the input register, tie it high if not used.
>> Low on G will enable the output transistors so 0s & 1s will show up on your display. With G high, no outputs will turn on.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 11, 2011, 04:38 am
I finished the wiring, but I'm not getting any response to the code. I imagine the other code is only for that shift register mentioned and I'll need to do a lot more work to get this one running.

I currently only have one display connected. I wanted to make sure this way works before I made more.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 11, 2011, 05:19 am
Post your code and a schematic of what you have so far, I'm sure we can get you going.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 12, 2011, 04:38 am
Wait, do I need to connect the positive of the battery power to Vcc?
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 12, 2011, 05:33 am
Basically this is the idea, plug your parts in the correct places.
You may not need the diode to drop the voltage a little to the shift register, the recommended  operating voltage is 5.5, absolute max is 7, so you may be okay with just the 4 batteries as the 1.5V/battery will drop some as they are used.
(http://www.crossroadsfencing.com/shift_register_connections.jpg)
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 12, 2011, 07:35 pm
So I can not use SRCLR by tying it high meaning connecting it to 5V? And I don't have to do anything with G?

I just connected Vcc to the Arduino's 5V.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 12, 2011, 07:43 pm
Is either SRCK or RCK connected to ground?
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 12, 2011, 07:47 pm
Basically I just need to know which is clock, data, and latch.

I assume data is SER IN, but I don't know which of the other two is which.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 12, 2011, 08:22 pm
You need to get a copy of the datasheet
http://focus.ti.com/general/docs/lit/getliterature.tsp?genericPartNumber=tpic6b595&fileType=pdf
SRCK clocks the 8 bits into the Input Register one by one.
RCK then clocks all 8 bits together into the Output Register to drive the LED segments.
G/ can be tied low.
SRCLR/ can be tied high (Vcc) if you do not want to clear all the input registers at once.
SER IN is the data to be shifted in
SER OUT is the data to be shifted into the next device in line.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 14, 2011, 05:21 am
I read that part, but the Arduino site said that the latch pin needs to be connected to ground:

http://arduino.cc/en/Tutorial/ShiftOut

So is that right and if so, which is the latch pin line?
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 14, 2011, 05:41 am
You have to look at the specific part being used.
The 74HC595 will die with the higher voltage you need for your multiple-LED/segment display.
The TPIC6B595 has a different pinout & functionality, you will need the 2 clock inputs as I described.  Electrical Engineer, trust me on this one.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 14, 2011, 06:00 am
Oh ok, I used the TPIC6B595. So is there a latch pin at all then?

http://www.sparkfun.com/datasheets/IC/TPIC6B595.pdf

Right now I have SER IN, SRCK, and RCK connected to the Arduino.

Vcc and G to 5 volts and all three grounds and SRCLR connected to ground.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 14, 2011, 07:13 am
G needs to go to ground, that is the active low output enable.
SRCLR needs to be high, it clears the input register when it is low.
SRCK shifts in the 8 bits.
RCK clocks the 8 bits into the output register to control your segments.

So there is no Latch pin - the functionality is different, you need an edge to clock the register.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 15, 2011, 08:53 pm
Right, I switched those somehow. The code you mentioned had a latch pin, so I don't think it will work.

So I send in the 8 bits through SRCK? I thought that was what SER IN did. I can try writing some code once I figure out what information each input needs sent.

Sorry this is taking so long. I appreciate your help. I was sent this site:
http://arduino.cc/en/Tutorial/ShiftOut
and I tried to use that but it seems to be about the other shift register configuration that uses a latch pin. Both shift registers are 595s though.

Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 15, 2011, 11:08 pm
You'll need something like this:

Code: [Select]

shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.


where shiftdatapin connects to SER IN,
shiftclockpin connects to SRCK.
MSBFIRST says bit 7 of your data is going out first,
and shiftregdata is your segment data (bit 0-7 representing segments A-G & DP for example).
595 has lots if variations. Need to read the datasheets and wire accordingly.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 19, 2011, 03:05 am
Wow that works great! Thanks!

Do you know how I could get the code to interpret numbers into bytes that needs to be sent?

Code: [Select]
int shiftdatapin = 48;
int shiftclockpin = 50;
int RCK = 52;

byte numbers[10] =
{
 B00111111, // 0
 B00000110, // 1
 B01010011, // 2
 B01001111, // 3
 B01100110, // 4
 B01101101, // 5
 B01111101, // 6
 B00000111, // 7
 B01111111, // 8
 B01101111  // 9
};

void setup() {
 //set pins to output so you can control the shift register
 pinMode(shiftdatapin, OUTPUT);
 pinMode(shiftclockpin, OUTPUT);
 pinMode(RCK, OUTPUT);
}

void loop() {
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, B01111111); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.

}


The above code works, but I'd like to be able to put a variable into the code instead of B01111111.

Would the above code work for multiple digits too?  For example, could I send 1493 to a string of 4 digits of the display and it'd work or do I have to somehow separate 1493 into individual numbers and send them out?
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 19, 2011, 05:11 am
Easy question first : 1493. Do you have 4 shift registers connected together, so that the output of one feeds the input of 2, two's output feeds 3's input, etc?
If so, you can just do 4 shiftouts in a row. If not, do 4 shiftouts to the individually controlled registers.  Shiftout is a software feature, pretty similar to:
digitalWrite (pin, bit0);
digitalWrite (clock low);
digitalWrite (clock, high);
//repeat 7  times for bit1, bit2, ...bit7.
You can also do a hardware controlled shiftout that would go faster using SPI, but you have to use specific pins for it. Go do some reading about it.
Code: [Select]

shiftregdata = byte1;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.
shiftregdata =  byte2;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.
shiftregdata  = byte3;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.
shiftregdata  = byte4;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.

now, making bytex= numbers
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 01:25 am
I have 4 in a row, but the second data input seems to just overwrite the first.

Code: [Select]
int shiftdatapin = 48;
int shiftclockpin = 50;
int RCK = 52;
int shiftregdata;

byte numbers[10] =
{
 B00111111, // 0
 B00000110, // 1
 B01010011, // 2
 B01001111, // 3
 B01100110, // 4
 B01101101, // 5
 B01111101, // 6
 B00000111, // 7
 B01111111, // 8
 B01101111  // 9
};

void setup() {
 //set pins to output so you can control the shift register
 pinMode(shiftdatapin, OUTPUT);
 pinMode(shiftclockpin, OUTPUT);
 pinMode(RCK, OUTPUT);
}

void loop() {
shiftregdata =  B00000111;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.
shiftregdata =  B00000111;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.

}
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 01:28 am
Code: [Select]
int shiftdatapin = 48;
int shiftclockpin = 50;
int RCK = 52;
int shiftregdata;

byte numbers[10] =
{
 B00111111, // 0
 B00000110, // 1
 B01010011, // 2
 B01001111, // 3
 B01100110, // 4
 B01101101, // 5
 B01111101, // 6
 B00000111, // 7
 B01111111, // 8
 B01101111  // 9
};

void setup() {
 //set pins to output so you can control the shift register
 pinMode(shiftdatapin, OUTPUT);
 pinMode(shiftclockpin, OUTPUT);
 pinMode(RCK, OUTPUT);
}

void loop() {
shiftregdata =  B11111111;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.
shiftregdata =  B00000110;
shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata); // puts the bits into the input register
digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // puts the bits into the output register.

}


Well actually the first number just shows up on both
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 01:30 am
Added a delay and got that sorted out actually.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 01:40 am
Right now the only thing left I have to figure out is this. Say the Arduino does some calculations and comes up with the number (int) 2,590, how would I send that to the display?

Won't I somehow have to separate each place (ones, tens, hundreds, etc.) into a single number and convert that to bytes? How can I convert say 3 into B01001111.

This didn't seem to work:
Code: [Select]
byte numbers[10] =
{
 B00111111, // 0
 B00000110, // 1
 B01010011, // 2
 B01001111, // 3
 B01100110, // 4
 B01101101, // 5
 B01111101, // 6
 B00000111, // 7
 B01111111, // 8
 B01101111  // 9
};


I'm also interested in controlling decimal points.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 20, 2011, 05:17 am
Where'd you put the delay to make it work?

Decimal point - use the 8th bit to drive the DP.

I do things like this to turn the bit Hi & Low:
Say you have databyte B11111111
To make the 8th bit Low, AND it with 0:
databtye = databute && B01111111
The other bits that are ANDed with 1 are not changed from their original state (0 AND 1 = 0, 1 AND 1 = 1)

To make it back high, OR it with a 1:
databyte = databyte || B10000000
The other bits that are ORed with 0 are not changed (0 OR 0 = 0, 1 OR 1 = 1)

Your other question: I need to know more what a number like 2,593 is.
Are those 4 hex digits?
There are ways to separate it into digits.
For example,  hex data  digit = 2593:
digit0 = digit AND 0x000F  now digit0 = 0003
digit1 = digit >>4 now digit 1 = 0259 (shifted 4  bits away)
digit1 = digit1 AND 0x000F now digit1 = 0009
digit2 = digit1 >>4 now digit2 = 0025
digit2 = digits AND 0x000F now digit2 = 0005
digit3 = digit2 >>4 now digit3 = 0002

Then dataout = numbers[digit0] should give the 7-segment mapping you want for a 3.

So I guess Yes, you have to split it into bytes.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 06:42 pm
the 2,593 would be an int(eger) stored in a variable
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 06:43 pm
I get how to control the decimal points, but I just wanted to make sure that when the integer was converted into bytes the decimal was kept.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 06:53 pm
I put the delay at the end.  The code I was running didn't have anything else in it, so as soon as it finished sending say 68 it was sending another 8 through that got rid of the 6.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 20, 2011, 09:12 pm
Okay, so split it  up & send it out.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 20, 2011, 11:27 pm
How do I split it and how do I keep the decimal?
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 21, 2011, 05:45 am
I presented a way to do that earlier:

"Your other question: I need to know more what a number like 2,593 is.
Are those 4 hex digits?
There are ways to separate it into digits.
For example,  hex data  digit = 2593:
digit0 = digit AND 0x000F  now digit0 = 0003
digit1 = digit >>4 now digit 1 = 0259 (shifted 4  bits away)
digit1 = digit1 AND 0x000F now digit1 = 0009
digit2 = digit1 >>4 now digit2 = 0025
digit2 = digits AND 0x000F now digit2 = 0005
digit3 = digit2 >>4 now digit3 = 0002"

Try this:
digit = 0x2593;

digit0 = digit && 0x000F;  // mask off the upper 12 bits
Serial.print (digito, HEX);
digit1 = digit >>4; // shift off the lower 4 bits
digit1 = digit1 && 0x000F; // mask off the upper 12 bits
Serial.print (digit1, HEX);
digit2 = digit >> 8; // shift off the lower 8 bits
digit2 = digit2 && 0x000F; // mask off the upper 12 bits
Serial.print (digit2, HEX);
digit3 = digit >> 12; // shift off the lower 12 bits
digit3 = digit3 && 0x000F; // mask off the upper 12 bits
Serial.print (digit3, HEX);


I don't know where the decimal point goes, not enough info provided.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 22, 2011, 08:02 am
Those would be int numbers not hex, but did you provide a conversion from into to hex in the beginning of the code? If so, then that should work.

The thing is I want to display a calculated number stored in a variable.

So say
x= 36.3
or
x=2.58

Ideally I'd like to be able to convert x into something to send to the 7-segment displays.
Title: Re: 7-Segment Display Wiring and Programming
Post by: guitarboy667 on Jan 22, 2011, 08:51 pm
Non-ideally I'd like to get the decimal between the last 2 digits. (234.5 for example)

Thanks for your help man.
Title: Re: 7-Segment Display Wiring and Programming
Post by: CrossRoads on Jan 23, 2011, 01:06 am
So what do the "two 7-segment displays of 4 digits each" represent?