Go Down

Topic: 7-Segment Display Wiring and Programming (Read 68621 times) previous topic - next topic

CrossRoads

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.
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.

guitarboy667

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?

CrossRoads

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.
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.

guitarboy667

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.

CrossRoads

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.
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.

guitarboy667

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.


CrossRoads

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.
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.

guitarboy667

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?

CrossRoads

#38
Jan 19, 2011, 05:11 am Last Edit: Jan 19, 2011, 05:12 am by CrossRoads Reason: 1
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
  • , maybe something like this:
    shiftregdata[1] = numbers[ones_seconds];
    shiftregdata[2] = numbers[tens_seconds];
    shiftregdata[3] = numbers[ones_hours];
    shiftregdata[4] = numbers[tens_hours];

    and the 4 shifts above could be pulled into a loop? Defined as:
    for (initialization; condition; increment) {
    //statement(s);
    }

    This loop should do 4 shiftouts, fancier than anything I've tried yet:

    Code: [Select]

    //for (x=1 to 4)
    for (x=0;  x<5; x=x+1;){  //maybe x==4, and x++ instead x=x+1?? x=x+1 is clearer (to me). Try it.
    shiftOut(shiftdatapin, shiftclockpin, MSBFIRST, shiftregdata[x]); // load input register
    digitalWrite (RCK, LOW);
    digitalWrite (RCK, HIGH); // load output register.
    //Serial.writeln shiftregdata[x];  // to make sure
    }

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.

guitarboy667

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.

}

guitarboy667

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

guitarboy667

Added a delay and got that sorted out actually.

guitarboy667

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.

CrossRoads

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.
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.

guitarboy667

the 2,593 would be an int(eger) stored in a variable

Go Up