Trouble reading SN74HC165N Shift register

Hello,

I am having trouble getting the Texas Instuments SN74HC165N 8-Bit Parallel-Load Shift Registers to do what i expect.
This one: SN74HC165 data sheet, product information and support | TI.com

Eventually i want to use two of them to read the value of a 12 bit counter, but frist, because if have so much to learn, i'd like to see it work in its simpelest form.

I am hoping somebody can point out what im doing wrong.

See below for code and schema, but in essence, here is what im trying:
Connect the following pins to Arduino

  • CLK, SH/_PL, QH
    Connect to following pins to 5V
  • VCC, A
    Connect all other pins to Ground
  • B, C, D, E, F, G, H, _QH, SER

I expect to read "1" but instead i get "2".
If i connect only B to 5V, i expect to read 2 but i get 4
If i connect only C to 5V, i expect to read 4 but i get 8
This continues to pin G reading 128 instead of 64 and pin H reading 0.

I have both a Arduino Uno and Arduino Due. On the the due it gets it right the first time (after hardware reset).

Im getting pretty desperate here, searched this forum and google. I have 4 of these shift registers, tried them all and all give the same results.

const int clk = 8;    // SN74HC165N pin 2, CLK
const int data = 12;   // SN74HC165N pin 9, QH
const int lock = 13;   // SN74HC165N pin 1, SH/LD
// SN74HC165N CLK INH connected to GND
// SN74HC165N A to H connected to GND or VDD, see question
// SN74HC165N _QH, connected to GND
// SN74HC165N SER, connected to GND

void setup() 
{
  pinMode(clk, OUTPUT);  
  pinMode(data, INPUT);   
  pinMode(lock, OUTPUT);  

  Serial.begin(115200);
}

void loop() 
{
  // Lock parallel input
  digitalWrite(lock, HIGH);
  
  // Read
  byte b = shiftIn(data, clk, MSBFIRST);
  Serial.println(b);

  // Re-enable parallel input
  digitalWrite(lock, LOW);

  delay(2000);
}

Oh, i also tried clocking manually, like this

void loop() 
{
  digitalWrite(lock, HIGH);
  byte val = 0;
  for(int i = 0; i < 8; i++)
  {
    digitalWrite(clk, HIGH);
    delay(5);
    val |= digitalRead(data) << (7 - i);
    digitalWrite(clk, LOW);
  }    
  digitalWrite(lock, LOW);
  Serial.println(val);
  delay(2000);
}

Same results, gets it right the first time on Due, after hardware reset. On Uno it does it wrong every time.

Don't know if this will help or not?

Try a 0.1uF ceramic decoupling capacitor as close to the power pins as possible on the shift chip.

Change your code a little:

void loop() 
{
  // Sample the parallel input
  digitalWrite(lock, LOW);
  digitalWrite(lock, HIGH);
  
  // Read
  byte b = shiftIn(data, clk, MSBFIRST);
  Serial.println(b);


  delay(2000);
}

Make sure 2 & 15 are connected together.
Make sure to add 0.1uF cap on VCC as suggested earlier.

Thanks for the help guys,

@dannable: SPI.transfer works, if i cant get it to work with shiftIn() i will use SPI

@grumpy_mike & CrossRoads: Thanks you for the efford, but still no luck. Tried it on both Uno and Due. Again, due gets it right the first time after a hardware reset.

Can it be that shiftIn() is'nt the right function for SN74HC165? And is it for another shift register?

Can it be that shiftIn() is'nt the right function for SN74HC165? And is it for another shift register?

No.

You will have to start describing the results you do get when it is wrong. Try other input bit patterns and see if you can establish a pattern. You know input is this output is that sort of thing.

I have got it working, turns out i have to put clock to HIGH before sampling.

like so

const int clk = 13;    // SN74HC165N pin 2, CLK
const int data = 12;   // SN74HC165N pin 9, QH
const int lock = 8;   // SN74HC165N pin 1, SH/LD
// SN74HC165N CLK INH connected to GND
// SN74HC165N A to H connected to GND or VDD, see question
// SN74HC165N _QH, connected to GND
// SN74HC165N SER, connected to GND

void setup() 
{
  pinMode(clk, OUTPUT);  
  pinMode(data, INPUT);   
  pinMode(lock, OUTPUT);  


  Serial.begin(115200);
}

void loop() 
{
  // This line made it work: Turn clock HIGH before sampling
  digitalWrite(clk, HIGH);

  // Sample the parallel input
  digitalWrite(lock, LOW);
  digitalWrite(lock, HIGH);
  
  // Read
  byte b = shiftIn(data, clk, MSBFIRST);
  Serial.println(b);

  delay(2000);
}

I may end up using Dannable's way afterall, because less pins 'n stuff. But it is nice know how to get shiftIn to work as expected.

Thanks for the help.

Cool.

Not my way, Nick Gammon's way. He's one of the mods around here.