Go Down

Topic: chain from 3 x 74hc165 shiftin registers (Read 12120 times) previous topic - next topic

Black_Parrot

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!
Code: [Select]
#define NUMBER_OF_SHIFT_CHIPS   [b]2[/b]
#define BYTES_VAL_T unsigned[b] int[/b]


But, when i add 3rd register
Code: [Select]
#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!)

Code: [Select]
/* 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);
}

Grumpy_Mike

Any power supply decoupling on those chips?

Black_Parrot


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.

graynomad

Code: [Select]
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
Rob Gray aka the GRAYnomad www.robgray.com

Grumpy_Mike

Quote
No. My scheme is identical to one i drew.

Then you need some.

Black_Parrot

Quote
Then you need some.

Quote
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?

Grumpy_Mike

Quote
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

Black_Parrot


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

Black_Parrot


Grumpy_Mike

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.

Black_Parrot

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.

Grumpy_Mike

Try this modification:-
Code: [Select]

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



Black_Parrot

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

Grumpy_Mike

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.

Black_Parrot

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.

Go Up