Level shifter
Many of the sensors here speak 5 V logic while the Pi speaks 3.3 V, and a GPIO fed 5 V is damaged by it. A level shifter costs $3.50 and is the tidy fix: each channel is a BSS138 MOSFET whose gate sits on the low-side rail, with a 10 kΩ pull-up on each side. It is bidirectional and automatic — pull either side low and the other follows — so the same four channels carry 3.3 V signals up to 5 V and 5 V signals down to 3.3 V. What it cannot do is drive a load: the pull-ups are 10 kΩ, good for signals only.
Pins
| Pin | What it is | Type |
|---|---|---|
| LV | Low-side supply (2.5–5.5 V) | power |
| HV | High-side supply (4.5–5.5 V) | power |
| LV1 | Channel 1, low side | io |
| LV2 | Channel 2, low side | io |
| LV3 | Channel 3, low side | io |
| LV4 | Channel 4, low side | io |
| HV1 | Channel 1, high side | io |
| HV2 | Channel 2, high side | io |
| HV3 | Channel 3, high side | io |
| HV4 | Channel 4, high side | io |
LevelShifter()— Level shifter, 4-channel — $3.50- Pins: 10
LV is the low-side supply (the Pi's 3V3) and HV the high side (5 V); they must satisfy HV ≥ LV. The four channels are LV1–LV4 and HV1–HV4: one side of each is wired to a 3.3 V signal, the other to the 5 V signal. There is no ground pin — both circuits already share the board's ground.
Wiring it in circuit.py
An HC-SR04 sonar with both of its signals shifted: the trigger goes up to 5 V, the echo comes back down.
from wiring import *
pi = Pi()
shifter = LevelShifter()
sonar = HCSR04()
pi.V3_3 >> shifter.lv # the low side: 3.3 V logic
pi.V5 >> shifter.hv # the high side: 5 V logic
pi.V5 >> sonar.vcc
sonar.gnd >> pi.GND
pi.GPIO17 >> shifter.lv1 # 3.3 V out, 5 V in: the trigger
shifter.hv1 >> sonar.trig
sonar.echo >> shifter.hv2 # 5 V out, 3.3 V in: the echo
pi.GPIO27 >> shifter.lv2The usual alternative — a resistor divider on the echo and a straight 3.3 V trigger — works for the HC-SR04 because its trigger happens to accept 3.3 V as high. The shifter is the general answer, and it also protects the pin: whatever the 5 V side does, the GPIO only ever sees LV.
Driving it in main.py
from gpiozero import DistanceSensor
from time import sleep
sensor = DistanceSensor(echo=27, trigger=17) # both signals behind the shifter
while True:
print(f"{sensor.distance * 100:.1f} cm")
sleep(0.5)Electrical notes
- A low on the low side turns the channel on through the gate (3.3 V above the source). A low on the high side first pulls the source down through the MOSFET's body diode, and the channel takes over as soon as the source drops a threshold below the gate. Both directions are in the simulator's tests.
- The 10 kΩ pull-ups set the speed: about 2 MHz into a few tens of picofarads, and slow edges on long wires.
- Channel resistance is a couple of ohms, so a shifted signal can carry a milliamp or two — enough for a logic input, not for an LED.
- Only a few BSS138 models are in the simulator's library (
BSS138,2N7000,IRLZ44N,AO3401); the module here uses the BSS138. - Like every part, it is flattened into its real components when the board runs: four MOSFETs, eight resistors and four body diodes — one channel's worth of each per side. Select it and press Open internals in the Inspector to watch a channel work: the module drawn against the Pi, its parts, and the live voltage on every net inside.
Simulator vs real hardware
- The body diode is drawn as an explicit 1N4148 in the model, because the simulator's MOSFET has no body diode yet; a real BSS138 has one inside, and it is what makes the high-to-low direction work.
- Real shifters are picky about the low rail: with
LVat 1.8 V a BSS138's threshold is marginal, which is why the datasheet's circuit is quoted for 2.5 V and up.