chain from 3 x 74hc165 shiftin registers

Hi! Does anyone know how to make the chain from 3(or more) hc165 registers?

I did this example. The problem is:
When i made a chain from 2 registeres it worked fine!

#define NUMBER_OF_SHIFT_CHIPS   [b]2[/b]
#define BYTES_VAL_T unsigned[b] int[/b]

But, when i add 3rd register

#define NUMBER_OF_SHIFT_CHIPS  [b]3[/b]
#define BYTES_VAL_T unsigned[b] long[/b]

The 1st one stopped to work! It doesnt recognise button pressed.

Why?? Here is the code and scheme(Buttons are on every input!!! I didn’t draw them all!)

/* How many shift register chips are daisy-chained.
*/
#define NUMBER_OF_SHIFT_CHIPS   3

/* Width of data (how many ext lines).
*/
#define DATA_WIDTH   NUMBER_OF_SHIFT_CHIPS * 8

/* Width of pulse to trigger the shift register to read and latch.
*/
#define PULSE_WIDTH_USEC   5

/* Optional delay between shift register reads.
*/
#define POLL_DELAY_MSEC   20

/* You will need to change the "int" to "long" If the
 * NUMBER_OF_SHIFT_CHIPS is higher than 2.
*/
#define BYTES_VAL_T unsigned long

int ploadPin        = 8;  // Connects to Parallel load pin the 165
int clockEnablePin  = 9;  // Connects to Clock Enable pin the 165
int dataPin         = 11; // Connects to the Q7 pin the 165
int clockPin        = 12; // Connects to the Clock pin the 165

BYTES_VAL_T pinValues;
BYTES_VAL_T oldPinValues;

/* This function is essentially a "shift-in" routine reading the
 * serial Data from the shift register chips and representing
 * the state of those pins in an unsigned integer (or long).
*/
BYTES_VAL_T read_shift_regs()
{
    byte bitVal;
    BYTES_VAL_T bytesVal = 0;

    /* Trigger a parallel Load to latch the state of the data lines,
    */
    digitalWrite(clockEnablePin, HIGH);
    digitalWrite(ploadPin, LOW);
    delayMicroseconds(PULSE_WIDTH_USEC);
    digitalWrite(ploadPin, HIGH);
    digitalWrite(clockEnablePin, LOW);

    /* Loop to read each bit value from the serial out line
     * of the SN74HC165N.
    */
    for(int i = 0; i < DATA_WIDTH; i++)
    {
        bitVal = digitalRead(dataPin);

        /* Set the corresponding bit in bytesVal.
        */
        bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

        /* Pulse the Clock (rising edge shifts the next bit).
        */
        digitalWrite(clockPin, HIGH);
        delayMicroseconds(PULSE_WIDTH_USEC);
        digitalWrite(clockPin, LOW);
    }

    return(bytesVal);
}

/* Dump the list of zones along with their current status.
*/
void display_pin_values()
{
    Serial.print("Pin States:\r\n");

    for(int i = 0; i < DATA_WIDTH; i++)
    {
        Serial.print("  Pin-");
        Serial.print(i);
        Serial.print(": ");

        if((pinValues >> i) & 1)
            Serial.print("HIGH");
        else
            Serial.print("LOW");

        Serial.print("\r\n");
    }

    Serial.print("\r\n");
}

void setup()
{
    Serial.begin(9600);

    /* Initialize our digital pins...
    */
    pinMode(ploadPin, OUTPUT);
    pinMode(clockEnablePin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, INPUT);

    digitalWrite(clockPin, LOW);
    digitalWrite(ploadPin, HIGH);

    /* Read in and display the pin states at startup.
    */
    pinValues = read_shift_regs();
    display_pin_values();
    oldPinValues = pinValues;
}

void loop()
{
    /* Read the state of all zones.
    */
    pinValues = read_shift_regs();

    /* If there was a chage in state, display which ones changed.
    */
    if(pinValues != oldPinValues)
    {
        Serial.print("*Pin value change detected*\r\n");
        display_pin_values();
        oldPinValues = pinValues;
    }

    delay(POLL_DELAY_MSEC);
}

Any power supply decoupling on those chips?

Grumpy_Mike: Any power supply decoupling on those chips?

No. My scheme is identical to one i drew. I use 5V and GND pins on arduino UNO for all of these registers.

int clockEnablePin  = 9;  // Connects to Clock Enable pin the 165

Not according to the schematic it doesn't. But it is tied to GND so I think that's ok.

I would decouple those chips and see what happens then.


Rob

No. My scheme is identical to one i drew.

Then you need some.

Then you need some.

I would decouple those chips and see what happens then.

How can i decouple them? So, i need external power source to be able to run more then 2 registers in the chain?

So, i need external power source to be able to run more then 2 registers in the chain?

No. http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Grumpy_Mike:

So, i need external power source to be able to run more then 2 registers in the chain?

No. http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

So I need to place capacitors? But where and what kind of capacitors? Sorry, it quite difficult for me to understand principles of De-coupling.

Am i right??

Close. The 0.1uF ceramic ( only ceramic ) capacitors should be placed as close to the chip’s pins as you can get them with the leads on the capacitors as short as possible.

The same problem. (((

Pin0(from the last chained register(the farest from arduino)) - work ok pin1 - ok pin2 - ok pin3 - ok pin 4 - ok 5- ok 6 - not ok(displayed as 6 and 7 pins at the same time)

7 - not ok(displayed as 6 and 7 pins at the same time)

next register 8 -ok 9 - ok ... 14 - ok 15 - not ok! (Shown as 15 - 23 pins pressed at the same time)


1-st register 14 - 23 pins do not work at all.

Try this modification:-

 /* Pulse the Clock (falling edge shifts the next bit).
        */
        digitalWrite(clockPin, HIGH);
        delayMicroseconds(PULSE_WIDTH_USEC);
        digitalWrite(clockPin, LOW);
        delayMicroseconds(PULSE_WIDTH_USEC);

It doesn't help. ((( I trying to fing examples with 3+ registers or more... without success for now>

Did you write that code or get it from somewhere else? The comment about clocking edge was wrong, as was the name of the variable for the CE pin, it is chip enable not clock enable. It won't affect the results but shows the person who wrote the code only has a flimsy grip on what is going on.

I found this code. I just wanna look out is it works and then try to adopt it for my needs. I need just simple function like if (buttonX == 1) { DigitalWrite (X, HIGH) } But, yeah. I can't move forward before it start to work at least with someone's test code.

Anyone? Is there the way to use more then 2 input registers?

http://dduino.blogspot.com/2012/04/arduino-74hc165-psio-shift-regsiter.html

I've looked at that code 10 times and I can't see any reason it will work for 2 chips and not for 3. I would however change

       bytesVal |= (bitVal << ((DATA_WIDTH-1) - i));

which I think is unnecessarily complex and time-consuming to

        bytesVal << 1;
        bytesVal |= bitVal;

I can't see that has anything to do with the problem but code that's difficult to understand is always worth changing.


Rob

http://www.gammon.com.au/forum/?id=11979

Hey Black_Parrot,

I just read your post and see some similarities to my post. Especially the case that two inputs fire the same time happens to me as well. I do use two SN74HC165N daisy-chained.

Here is my story: http://forum.arduino.cc/index.php?topic=222209.0

Let me know if you are making progress. I will keep you posted.

Thanks, Musterstrasse