74HC165 input quirk

Hi,

I'm using a 74HC165E to shift 8 pushbuttons into the Arduino using 3 wires.

Switch 1 is connected to IC Pin 11 (D0)
...
Switch 8 is connected to IC Pin 6 (D7)

(cf. pin layout from datasheet)

Using the following sketch code:

int latchPin = 5;
int dataPin = 6;
int clockPin = 7;
int input;

void setup() {
  pinMode(5, OUTPUT);
  pinMode(6, INPUT);
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(latchPin, HIGH);
  input = shiftIn(dataPin, clockPin, MSBFIRST);
  digitalWrite(latchPin, LOW);
  Serial.println(input);
  }

I get the following results:

No press -> 255
Switch 1 -> 253 (i.e bit 2 — binary 2)
Switch 2 -> 251 (i.e bit 3 — binary 4)
Switch 3 -> 247 (i.e bit 4 — binary 8)
...
Switch 7 -> 127 (i.e bit 8 — binary 128)

BUT

Switch 8 -> 254 (i.e bit 1 — binary 1)

which seems odd because all the buttons are switched sequentially. If the wires were not properly connected, I'd get no behavior at all. But here, all the switches are working, only with the bits shifted around one position to the left (or right, because with LSBFIRST I get the opposite behavior, i.e. the bits shifted from the buttons are in this order: 64, 32, 16, 8, 4, 2, 1, 128).

Is there a problem somewhere, or is it normal for the IC input pin switches to work in this order: D7, D0, D1, D2, D3, D4, D5, D6?

Thanks.

BTW it's easier to see with "Serial.println(255^input);" but the result is the same, obviously.

cd74hc165.pdf (page 1 of 17).png

This is the correct behaviour from how I understand the datasheet. As soon as PL* (1, I guess this is your latchPin) goes high, the most significant bit is available at Q7 (9). With every rising edge of CP (2) the next bit is rotated to Q7.

As for the shiftIn function:

uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
	uint8_t value = 0;
	uint8_t i;

	for (i = 0; i < 8; ++i) {
		digitalWrite(clockPin, HIGH);
		if (bitOrder == LSBFIRST)
			value |= digitalRead(dataPin) << i;
		else
			value |= digitalRead(dataPin) << (7 - i);
		digitalWrite(clockPin, LOW);
	}
	return value;
}

the clock pin is put to HIGH before the value is read, so the first bit read is not bit 7 but bit 6.

To fix that you probably (I have not tested that!) can put CP to HIGH before you make the same for PL*. This way no rising edge is produced when the shiftIn function also put a HIGH to that pin (which already is HIGH) and the first value read should be bit 7.

You were right. The following works as expected:

void loop() {
  digitalWrite(clockPin, HIGH);
  digitalWrite(latchPin, HIGH);
  input = shiftIn(dataPin, clockPin, LSBFIRST);
  digitalWrite(latchPin, LOW);
  Serial.println(255^input);
  }

Thank you very much!