74HC165 Shift Register with a Raspberry Pi Pico
The 74HC165 is an 8-bit parallel-in, serial-out shift register that reads eight buttons or switches on three microcontroller pins.

On the Raspberry Pi Pico the 74HC165 runs from 3V3, so its QH output never rises above the 3.3 V the RP2040's pins are made for. The page reads eight inputs on just GP0 (SH/LD), GP1 (CLK) and GP2 (QH) with a hand-written loop, because the arduino-pico core's shiftIn() clocks before it reads and drops bit H.
Wiring the 74HC165 Shift Register to the Raspberry Pi Pico
Pin by pin.
| 74HC165 Shift Register | Raspberry Pi Pico | Note |
|---|---|---|
| VCC | 3V3 | |
| GND | GND | |
| SH_LD | GP0 | |
| CLK | GP1 | |
| QH | GP2 | |
| CLK_INH | GND | |
| SER | GND | |
| A | GND | through a 10 kΩ resistor |
| B | GND | through a 10 kΩ resistor |
| C | GND | |
| D | GND | |
| E | GND | |
| F | GND | |
| G | GND | |
| H | GND |
What to know on the Raspberry Pi Pico
- QH swings to the chip's own VCC. On 3V3 it stays within the RP2040's IOVDD + 0.5 V pin limit; the same chip on VBUS would put about 5 V on GP2.RP2040 datasheet, section 5.5.3.1; Raspberry Pi Pico datasheet, release 21, p. 8
- Do not swap the loop for shiftIn(): on arduino-pico it raises CLK before sampling QH, so it returns G to A plus the next register's first bit. The sketch reads QH first, then pulses CLK.ArduinoCore-API shiftIn() source, as used by arduino-pico
- The chip draws 80 µA at most when idle, a negligible part of the 300 mA Raspberry Pi recommends as the limit for loads on the Pico's 3V3 pin, so a chain of several registers can share it.TI SN74HC165 datasheet SCLS116H, p. 1; Raspberry Pi Pico datasheet, release 21, p. 8
- For long chains the RP2040's hardware SPI can do the clocking: CLK on SPI0's SCK (GP18), QH on MISO (GP16), then SPI.transfer(0) per register in mode 0 after the load pulse.Raspberry Pi Pico datasheet, release 21, p. 4
74HC165 Shift Register code for the Raspberry Pi Pico
Compiled for rp2040:rp2040:rpipico on 2026-10-29.
// 74HC165 Shift Register on Raspberry Pi Pico: wiring and a free simulation at https://www.tinkered.ai/components/74hc165-shift-register/raspberry-pi-pico
#include <Arduino.h>
const int LOAD_PIN = 0; // SH/LD
const int CLOCK_PIN = 1; // CLK
const int DATA_PIN = 2; // QH
// Load A-H, then read QH before each clock: H first, A last (bit 0 = A).
uint8_t readInputs() {
digitalWrite(LOAD_PIN, LOW);
delayMicroseconds(5);
digitalWrite(LOAD_PIN, HIGH);
uint8_t value = 0;
for (int i = 7; i >= 0; i--) {
value |= digitalRead(DATA_PIN) << i;
digitalWrite(CLOCK_PIN, HIGH);
delayMicroseconds(2);
digitalWrite(CLOCK_PIN, LOW);
}
return value;
}
void setup() {
Serial.begin(115200);
pinMode(LOAD_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(DATA_PIN, INPUT);
digitalWrite(LOAD_PIN, HIGH);
digitalWrite(CLOCK_PIN, LOW);
}
void loop() {
uint8_t inputs = readInputs();
Serial.print("button A: ");
Serial.print(inputs & 0x01 ? "pressed" : "released");
Serial.print(" button B: ");
Serial.println(inputs & 0x02 ? "pressed" : "released");
delay(100);
}
74HC165 Shift Register on the Raspberry Pi Pico: questions
Can I power the 74HC165 from the Pico's VBUS pin?
Not while QH feeds a GPIO. QH swings to VCC, VBUS is about 5 V on USB (Pico datasheet, p. 8), and the RP2040 rates its pins to IOVDD + 0.5 V (RP2040 datasheet, section 5.5.3.1). The chip runs from 2 V to 6 V (TI SCLS116H, p. 4), so 3V3 suits it.
Why are my buttons off by one bit on the Pico?
That is shiftIn(): on the arduino-pico core it pulses CLK before it reads, so bit H is lost. Use the page's loop, which reads QH before each clock.
How do I read 16 inputs from one Pico?
Wire the first register's QH to the second one's SER, keep SH/LD and CLK shared on GP0 and GP1, and run the loop for 16 bits. The Pico still uses three pins.
Keep going
This guide as plain Markdown. /components/74hc165-shift-register/raspberry-pi-pico.md