Pages: [1]   Go Down
Author Topic: Trouble with TPIC6B595N shift register  (Read 4170 times)
0 Members and 1 Guest are viewing this topic.
Texas
Offline Offline
Jr. Member
**
Karma: 1
Posts: 97
Eso es lo que es
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am attempting to control 8 LED's with the TPIC6B595N shift register.  I looked at the shiftout tutorial, and noticed that the 74HC595 output pins supply +5V to the LED's, and they're all hooked to a common ground.
However, my TPIC6B595N outputs are open drain, so I have to connect the anodes of the LED's to a common +5V source, and their cathodes to respective shift register drains (w/ a 220 ohm resistor with each LED of course).  This is correct, right?  I believe this web tutorial verifies this...

http://www.mblock.com.tw/en_download_file/Application%20Note/How%20to%20substitute%20MBI5168%20or%20MBI5026%20for%20TPIC6B595%20V0.1.pdf

I tried to copy the "one by one" code off the shiftout tutorial, but with no success.  The LED's did nothing.

I connected...
Vcc - +5vdc
SER IN - Arduino dataPin
SRCLR - +5vdc
G - GND
SRCK - Arduino clockPin
RCK - Arduino latchPin

After reading the datasheet, these connections seemed to make sense to me if I am understanding correctly how the shift register works.  Here's the datasheet...

http://www.datasheetcatalog.org/datasheet2/4/08fhqcp9cl9a5h153qt6qpottjfy.pdf


However, I recently noticed from the circuit in the example I provided show pins 1 and 20, the NC pins, connected to Vcc.  This is the only thing I didn't have hooked up when I tried the code...but they're not internally connected.  What would it matter if anything was connected to them?  Thanks in advance for the help.
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26421
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think the extra connections hurt anything.
Please post your code, and confirm you are wired like this:


digitalWrite(dataloadclock, LOW);
shiftout (datapin, shiftclock, MSBFIRST,your_data);
digitalWrite(dataloadclock, HIGH); // this low-high transition moves the data to the output pins

or similar code for one bit at a time:
// loop thru this 8 times to clock out 8 bits and have them show up one at a time
digitalWrite(dataloadclock, LOW);
digitalWrite(datapin, value);
digitalWrite(shiftclock, LOW);
digitalWrite(shiftclock, HIGH);// this low-high transition moves the bit into an input register
digitalWrite(dataloadclock, HIGH); // this low-high transition moves the data to the output pins






* tpic6b595_example.jpg (64.21 KB, 960x720 - viewed 219 times.)
« Last Edit: January 31, 2011, 01:23:50 am by CrossRoads » Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

nr Bundaberg, Australia
Online Online
Tesla Member
***
Karma: 126
Posts: 8472
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
However, my TPIC6B595N outputs are open drain, so I have to connect the anodes of the LED's to a common +5V source, and their cathodes to respective shift register drains (w/ a 220 ohm resistor with each LED of course).  This is correct, right?
Correct.

Quote
1 and 20, the NC pins, connected to Vcc
When they say NC they mean just that, so no need to connect to VCC, no harm done either way. Sometimes you'll see DNC (Do Not Connect) in this case you definately shouldn't connect to anything.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Texas
Offline Offline
Jr. Member
**
Karma: 1
Posts: 97
Eso es lo que es
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok.  I've got my hardware tested with this basic code.  I figured out that I could write a decimal number in my shiftOut code, and it would convert to binary and turn on the lights I wanted to turn on.  Great.  Hardware all works as it should.  However, I do realize there are much simpler ways than writing in decimal values.

Quote
////Pin connect to Latch
const int latchPin = 8;
////Pin connected to Clock
const int clockPin = 12;
////Pin connected to Data
const int dataPin = 11;

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);
}

void loop() {
    // take the latchPin low so
    // the LEDs don't change while you're sending in bits:
    digitalWrite(latchPin, LOW);
    // shift out the bits:
    shiftOut(dataPin, clockPin, MSBFIRST, 0); 

    //take the latch pin high so the LEDs will light up:
    digitalWrite(latchPin, HIGH);
    // pause before next value:
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 1);
    digitalWrite(latchPin, HIGH);
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 3);
    digitalWrite(latchPin, HIGH);
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 7);
    digitalWrite(latchPin, HIGH);
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 15);
    digitalWrite(latchPin, HIGH);
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 31);
    digitalWrite(latchPin, HIGH);
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 63);
    digitalWrite(latchPin, HIGH);
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 127);
    digitalWrite(latchPin, HIGH);
    delay(100);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 255);
    digitalWrite(latchPin, HIGH);
    delay(3000);
}


I tried to hook up a second register, and just add another shiftOut in the code (i.e. the value 511), thinking that the process would have to go through the first register first before it sent information from the serial out into the serial in of the second register.  Of course, to my dissapointment, this was incorrect.  The LED on the second register was turned on the same time the first LED on the first register was turned on.

My ultimate goal here is to use a pressure transducer (0-5000 psi, 1-5vdc output) to control 50 LED's, using 7 registers.  Each LED will represent 100 psi.  As the pressure rises, I want all LED's that have been "passed" to remain on.  Example: If I have 1000 psi, I want 10 LED's on.

The stump I've hit is which is the best (least amount of code) way to achieve this.  I've read the example codes provided in the shiftOut tutorial.  I noticed there are arrays in one of them, and I thought this might be the answer, however, case statements with a map of my transducer range seems like it might be easier for me.

At this point though, I mainly need to know how to delay information to the second register until the first is "filled" when turning the LED's on, and the opposite sequence when turning them off.

Thanks in advance for the help.
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26421
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You have pin 18 of the first connected to pin 3 of the second?
You can only shift out 0-255, shift out only does 8 bits.
Why not just display a number from 0 to 5000 on the 7 segment displlays? I would find that  lot easier to interpret.
If you want to make a 50-segment bargraph, with 6 shift registers.
You will either have to perform 6 shift outs every time:
(replace the array refence 'segdisp[hundreths] with your numbers representing 0b00000001, 0b00000011, 0b00000111,
0b00001111, 0b00011111,0b00111111, 0b01111111, 0b11111111), such
Code:
 shiftOut(datapin, clockpin, MSBFIRST, segdisp[hundredths]); // print the  hundredths digit
  shiftOut(datapin, clockpin, MSBFIRST, segdisp[tenths]); // print the tenths digit
  shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_seconds]); // print ones_seconds digit
  shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_seconds]); // print the tens_seconds digit
  shiftOut(datapin, clockpin, MSBFIRST, segdisp[ones_minutes]); // print the ones_minutes digit
  shiftOut(datapin, clockpin, MSBFIRST, segdisp[tens_minutes]); // print the tens_minutes digit
Or connect up the 6 separate lines for SRCK (and have a common dataout & RCK line). Thus you could control which of the 6 got updated, and refresh all 6 with RCK (the data in the input register would not have changed if SRCK did not change for that register).
« Last Edit: February 05, 2011, 03:42:10 pm by CrossRoads » Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Texas
Offline Offline
Jr. Member
**
Karma: 1
Posts: 97
Eso es lo que es
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
You have pin 18 of the first connected to pin 3 of the second?
Yes sir

Quote
Why not just display a number from 0 to 5000 on the 7 segment displlays? I would find that  lot easier to interpret.
You would think so, but people in my industry tend to find it easier to interpret information more easily if it's presented in a more visual form, rather than numerically, if that makes any sense.  For example, for data that moves a lot, I like a needle type gauge rather than a digital one.  That's really what I'm trying to achieve here.  But thanks for the suggestion.

Quote
Or connect up the 6 separate lines for SRCK (and have a common dataout & RCK line). Thus you could control which of the 6 got updated, and refresh all 6 with RCK (the data in the input register would not have changed if SRCK did not change for that register).
That's a good idea.  It will cost me more I/O pins, but I'm not in short supply of those for what I'm doing here.

I've been copying examples and attempting to learn from them and bend them to suit my needs.  I just tried the one posted below, and I think I can make it work if I could just understand what every command is specifically doing.  I've read everything I could find in reference, my "Getting Started with Arduino" book, and forum discussions.  I'll figure it out sooner or later.

One more question:  How large of binary number can I write in my code?  I read in my book the largest decimal number the board can interpret is 4,294,967,295 if I use unsigned long.  Does specifying that the value is binary make this ok, as I will have (50) ones?
Code:
// Turn on LED's in sequence as per location on 2 shift
// registers.

//Pin connected to latch pin (RCK) of TPIC6B595N
const int latchPin = 8;
//Pin connected to clock pin (SRCK) of TPIC6B595N
const int clockPin = 12;
////Pin connected to Data in (SER IN) of TPIC6B595N
const int dataPin = 11;

char inputString[2];

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT); 
  pinMode(clockPin, OUTPUT);
}

void loop() {
  // iterate over the 16 outputs of the two shift registers
  for (int thisLed = 0; thisLed < 16; thisLed++) {
    // write data to the shift registers:
    registerWrite(thisLed, HIGH);
    // pause between LEDs:
    delay(250);
  }

}

// This method sends bits to the shift registers:

void registerWrite(int whichPin, int whichState) {
  // the bits you want to send. Use an unsigned int,
  // so you can use all 16 bits:
  unsigned int bitsToSend = 0;   

  // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);

  // turn on the next highest bit in bitsToSend:
  bitWrite(bitsToSend, whichPin, whichState);

  // break the bits into two bytes, one for
  // the first register and one for the second:
  byte registerOne = highByte(bitsToSend);
  byte registerTwo = lowByte(bitsToSend);

  // shift the bytes out:
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);
  shiftOut(dataPin, clockPin, MSBFIRST, registerTwo);

  // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);
}

Thanks again for your help.  I understand hardware fairly easily, but this code is about to eat my lunch. smiley
Logged

Texas
Offline Offline
Jr. Member
**
Karma: 1
Posts: 97
Eso es lo que es
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

CrossRoads, something you suggested just gave me a really good idea, I think.

Wouldn't it be even simpler to use seperate I/O pins for the data pins of each register, but let them all share the clock and latch pins?  I know the registers were designed to be daisy chained, but for my limited experience in programming, I think it might be easier for me to do this and just use a case statement to interpret the analog data and control the data pins

You think I'm on to something, or am I way off base here?

Thanks.
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26421
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Correct software action results here, but for wrong reason:

Code:
 // turn off the output so the pins don't light up
  // while you're shifting bits:
  digitalWrite(latchPin, LOW);
:
:
  // turn on the output so the LEDs can light up:
  digitalWrite(latchPin, HIGH);

After shifting the bits with shiftout, then you need
digitalWrite(latchPin, LOW);
digitalWrite(latchPin, HIGH);  // the low-high transition here clocks the data into the TPIC6B595 output register.

You can have 32 bit  numbers (2^32), for unsigned long (0xFFFF FFFF)
You will have to break down your 0-5000 number into 0-50 and go from there.

Trying to think of something  better than this tho:
Code:

declare variables etc in preset area
oldreg1 = reg1;
oldreg2 = reg2;
oldreg3 = reg3;
oldreg4 = reg4;
oldreg4 = reg5;
oldreg6 = reg6;
oldreg7 = reg7;

// declare outputs void setup() etc.

void loop(){

// get your PSI_full scale number from wherever

PSI_scaled = int (PSI_full/100);  get a number from 0 to 50
// map the number to the output LEDs
switch(PSI_Scaled){
case 0:
reg1 = 0b11111111;  // or 0xff, all off
reg2 = 0xff;
reg3 = 0xff;
reg4 = oxff;
reg5 = oxff;
reg6 = 0xff;
reg7 = oxff;
break;

case 1:
reg1 = 0b11111110;  // 1 LED on
reg2 = 0xff;
reg3 = 0xff;
reg4 = oxff;
reg5 = oxff;
reg6 = 0xff;
reg7 = oxff;
break;

case 2:
reg1 = 0b11111100;  // 2 LED on
reg2 = oxff;;
etc
break;
:
:
case 50:
reg1 = 0; // all 8 on
reg2 = 0;
reg3 = 0;
reg4 = 0;
reg5 = 0;
reg6 = 0;
reg7 = 0b11111100; // final 2
break;
} // end switch(PSI_scaled

// now shift them out, but only if they have changed - should really help with performance as can skip a bunch of shiftouts if nothing has changed on the lower segments

if (reg1 != oldreg1){  // only shift out if this byte has changed
shiftout (datapin, shiftclock1, MSBFIRST, reg1);
oldreg1 = reg1;} // save for next pass thru

if (reg2 != oldreg2){  // only shift out if this byte has changed
shiftout (datapin, shiftclock2, MSBFIRST, reg2);
oldreg2 = reg2;}

if (reg3 != oldreg3){  // only shift out if this byte has changed
shiftout (datapin, shiftclock3, MSBFIRST, reg3);
oldreg3 = reg3;}

if (reg4 != oldreg4){  // only shift out if this byte has changed
shiftout (datapin, shiftclock4, MSBFIRST, reg4);
oldreg4 = reg4;}

if (reg5 != oldreg5){  // only shift out if this byte has changed
shiftout (datapin, shiftclock5, MSBFIRST, reg5);
oldreg5 = reg5;}

if (reg6 != oldreg6){  // only shift out if this byte has changed
shiftout (datapin, shiftclock6, MSBFIRST, reg6);
oldreg6 = reg6;}

if (reg7 != oldreg7){  // only shift out if this byte has changed
shiftout (datapin, shiftclock7, MSBFIRST, reg7);
oldreg7 = reg7;}

digitalWrite (RCK, LOW);
digitalWrite (RCK, HIGH); // show the new outputs
} // end void loop

kinda ham fisted, but the house is noisy right and I can't really concentrate.
Hopefully a real software guy will pipe with a better way to fill the regx bytes.
« Last Edit: February 05, 2011, 05:10:52 pm by CrossRoads » Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Texas
Offline Offline
Jr. Member
**
Karma: 1
Posts: 97
Eso es lo que es
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Help greatly appreciated.  I'll give it a shot over the next few days.  Take it easy CrossRoads.
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26421
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

"Wouldn't it be even simpler to use seperate I/O pins for the data pins of each register, but let them all share the clock and latch pins? "
No, need separate SRCK (to clock in seperate data), or separate RCK (to clock only 1 output register, altho all input registers might have been filled).
So share data & SRCK, or data & RCk, but not SRCK & RCK, or all registers will get the same data.
The code example I gave assume separate SRCKs.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 524
Posts: 26421
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, good luck JD.
Watch out for falling ice from the stadium in Dallas if you're out that way ...
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Pages: [1]   Go Up
Jump to: