Go Down

Topic: Are Four 74HC595 Sift-registers in a row too many? (Read 18266 times) previous topic - next topic

PaulJakob

Hi,

I am trying to control 32 solenoids through four shift registers (74HC595 plus one Tip120 for every solenoid). Therefor I started using the example for two shiftregister by Tom Igoe
http://www.arduino.cc/en/Tutorial/ShiftOut

It also works super fine for two shift registers, I only modified it a bit in order to control them individually through the serial.read() function:

Code: [Select]

void loop() {

  if (Serial.available() > 0) {
    int thisLed = Serial.read()-48;
   
    registerWrite(thisLed, HIGH);
    delay(500);
    // if this is not the first LED, turn off the previous LED:
    if (thisLed > 0) {
      registerWrite(thisLed - 1, LOW);
    }
    // if this is  the first LED, turn off the highest LED:
    else {
      registerWrite(31, LOW);
    }
    // pause between LEDs:
    delay(250);
  }

}



NOW the problem is as soon as I attach four shift registers it seems that it works still fine with the first two, but instead of controlling the two following separately they also go off when the first two are addressed. As if mirrored...

Meaning when I address the first pin of the first shift-register the signal also goes to the first pin of the third shift register.
I open the Serial Monitor and input from "0" to "7" in order to address the first 8 outputs of the shift-register (Hope this makes sense?) the "8" to "?" for the next 8 following the asciitable:
http://www.asciitable.com/

The same happens with the others (when the first pin of the second register is addressed, the solenoid attached shoots once and at the same time the one attached to the first pin of the fourth register starts to go off in a frequent way)

THANKS for any suggestions to this issue.

Best,
PJ

madworm

So where's the rest of your code? Does your apparently proprietary code clear the whole chain?

And btw. did you add that infamous capacitor on the latch line? With that respect the tutorial is simply wrong. It's been that way for ages...

PaulJakob

Hi,

the rest of the code is still the same as in the tutorial, I just posted the little change I made:

Code: [Select]

/*
  Shift Register Example
for two 74HC595 shift registers

This sketch turns on each of the LEDs attached to two 74HC595 shift registers,
in sequence from output 0 to output 15.

Hardware:
* 2 74HC595 shift register attached to pins 2, 3, and 4 of the Arduino,
as detailed below.
* LEDs attached to each of the outputs of the shift register

Created 22 May 2009
Modified 23 Mar 2010
by Tom Igoe

*/

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
////Pin connected to Data in (DS) of 74HC595
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);
  Serial.begin(9600);
  Serial.println("reset");
}

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:
  if (Serial.available() > 0) {
    int thisLed = Serial.read()-48;
    //Serial.println(thisLed);
   
    registerWrite(thisLed, HIGH);
    delay(500);
    // if this is not the first LED, turn off the previous LED:
    if (thisLed > 0) {
      registerWrite(thisLed - 1, LOW);
    }
    // if this is  the first LED, turn off the highest LED:
    else {
      registerWrite(31, LOW);
    }
    // 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, registerTwo);
  shiftOut(dataPin, clockPin, MSBFIRST, registerOne);

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



I didn't add the capacitor since I read on another post that it could supposedly damage the arduino... then I didn't put it anywhere.
Should it go between  Pin 16 (Vcc) of the shift-register and ground of the arduino?

Best,
PJ

takao21106

You need capacitors when you drive 4 registers,
and also you need capacitors because of the solenoids.

If you don't use capacitors, there are spikes for some nanoseconds,
where the supply to the registers will drop down.

I use one 47uF Tanatalum for a matrix 7x17 LEDs, I think it has 6 registers.
If you use electrolytic higher capacity is required or low ESR is required.

You can use many shift registers, if you have 2 and another 2,
after 4 cycles, the last two will have the same content as the first two.

Means for 4 cycles you need to send 4 different bytes.

Your program seems to have logic errors! I looked and as far as I understand, you send the bitstream each time. and why do you wrap 2 8 bit writes into one 16 bit write?

What you need to do:

Prepare the data you want to send into 4x8 bits.
Send the data once, 4x 8 bits.

To make it easier at first test with dummy values (as it looks you read the data from a serial port).

madworm

I also think you're better off writing your own code.

The registerWrite() function only deals with a 16-bit wide variable. If you instruct it to set pin #31 in a chain of 4 shift registers it simply must fail !

As suggested before, do your own data preparation. Then you know what it is doing. When you have all 4 bytes ready, simply send all of them out. The code you use to set up the data-bytes should be aware of the number of shift registers it has to deal with.

PaulJakob

#5
Mar 10, 2012, 08:41 pm Last Edit: Mar 10, 2012, 08:43 pm by PaulJakob Reason: 1

You need capacitors when you drive 4 registers,
and also you need capacitors because of the solenoids.


ok, i got that. So you would suggest to use 4 capacitors (0.1uF?), one for each shift-register? Put between the Vcc of the register and arduino ground?

takao21106



You need capacitors when you drive 4 registers,
and also you need capacitors because of the solenoids.


ok, i got that. So you would suggest to use 4 capacitors (0.1uF?), one for each shift-register? Put between the Vcc of the register and arduino ground?


1 capacitor is enough for the 4 registers together I would not say it has to be 0.1 uF.
Use whatever you have around, apply common sense, experiment.
0.01uF might be enough, where 470uF also won't do damage.
Some types/brands also don't work right for some purposes.

Show a photo of the solenoids + TIP120 and then I can tell you if you need more capacitors.

If you use low frequency you can get away without 0.1 capacitors eventually but you have to verify that for each individual circuit.

PaulJakob

On the top is the Capacitor 47uF, where the 5V from the arduino comes and the ground is. I made it pretty much like described here:
http://www.thebox.myzen.co.uk/Tutorial/De-coupling_files/shapeimage_13.png

The there are the 32 tip120s for the solenoids. The second image shows the soldering from the shift register to the tip120s.


takao21106

#8
Mar 10, 2012, 10:00 pm Last Edit: Mar 10, 2012, 10:03 pm by takao21106 Reason: 1
There is one big capacitor already on the board!

Have you changed the program so it works? I don't think the code you show can work correctly at all.

At max. I would add 2 capacitors, one each for two register chips.
The value does not really matter. It's just buffering/decoupling.

For instance I use one small 1uF capacitor for 5 chips together, one PIC, 3 shifting register,
one LED display, works fine.

If you already have one 47uF somewhere, you don't neccessarily need another big 47uF capacitor.

But these buffering/decoupling capacitors are required. I saw it when I built this 7x17 matrix, without capacitor, only one half of the LED would update, and it was sensible to touching of the PCB.

Decoupling capacitors become more important when you use more MHz, and nanoseconds timing.
And you also need them when you switch high currents.
If you have many available, don't have to save on capacitors, and have board space available, add as many as you like or you think make any sense.

I also highly doubt you can switch on 32 Solenoids at once, using the Arduino 5 volts. I would even question if it is enough for 2 or 3 solenoids.

There is one rule that says add at least 1000uF/Ampere. It really depends if you have a 50Hz wall adapter, or a switching regulator (they do not need that much capacity).

PaulJakob

thanks, the solenoids run on 18v which comes from a power supply.

dou have any idea on how to send the right bits to the registers. i am a bit confused quiet frankly...

CrossRoads

Electrical Engineer says: put a 0.1uF cap from every Vcc pin to gnd.
Use SPI to down the 4 bytes into the shift registers.
Code: [Select]

digitalWrite (SS, LOW); // SS goes to the SRCK line
SPI.transfer (shiftRegister1data); // SCK goes to RCK pin, MOSI goes to Serial Data pin
SPI.transfer (shiftRegister2data);
SPI.transfer (shiftRegister3data);
SPI.transfer (shiftRegister4data);
digitalWrite (SS, HIGH); // all outputs are updated when SS goes high.

spend the rest of your time in void loop deciding on the order you want things to turn on or off.
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.

PaulJakob

thanks sir, so i did :)
thanks for the code, i'll start the software now.

PaulJakob

ok, one question regarding your code:

At the moment I have it like this:

Datapin (Arduino: 11)    -> goes to SI (14) pin of the 74HC595
Clockpin (Arduino: 12)  -> goes to SCK (11) pin of the 74HC595
Latchpin (Arduino: 8 )    -> goes to RCK (12) pin of the 74HC595

NOW, it says in your code in the comments that "SCK goes to RCK pin, MOSI goes to Serial Data pin" what does this exactly mean? I mean, which arduino pin do I connect with which of the registers pins?

Thanks!

runaway_pancake

This display ?
http://www.youtu.be/OW8FVmrA7js
has 9 '595s daisy-chained.
The display has 70 pixels, the 595s have 72 outputs total, so I have to knock out two dummy bits at the end to push everything through.
"Who is like unto the beast? who is able to make war with him?"
When all else fails, check your wiring!

PaulJakob


This display ?
http://www.youtu.be/OW8FVmrA7js
has 9 '595s daisy-chained.
The display has 70 pixels, the 595s have 72 outputs total, so I have to knock out two dummy bits at the end to push everything through.



Hey, that looks super cool!

I don't really get the dummy bit part? Could you share some of your code for me in order to understand? I'm a bit stuck with the transfer part...how do I address one specific pin of one of the 4 registers and shut up all the others?

Cheers!

Go Up