Raspberry Pi GPIO basics: 3.3V logic, pull-ups and lighting an LED with Python

TUREFF• •0
The row of 40 pins along the edge of most Raspberry Pi models is the GPIO header (general-purpose input/output). It is how a Pi talks to LEDs, buttons, sensors and other hardware. It is also the easiest place to damage a Pi, so the safety rules come first.

Rule one: 3.3 V logic, not 5 V

The GPIO pins work at 3.3 V. They are not 5 V tolerant, and the board has no protection against over-voltage on them. A 5 V signal connected directly to a GPIO pin can destroy that pin or the whole Pi. This catches people coming from the classic 5 V Arduino boards, and many hobby sensors and modules output 5 V. When you connect anything:
  • check the device's logic voltage
  • for a 5 V output, use a level shifter, or a voltage divider for a simple input signal
  • power 3.3 V devices from a 3.3 V pin
Confusingly, the header does have 5 V pins. They supply power to devices; they are not safe to connect to a GPIO input. Shorting a 5 V pin to a neighbouring pin is a classic way to kill a board, so be careful with loose jumper wires.

Other safety habits

  • Shut down and unplug before changing wiring.
  • GPIO pins supply very little current. Drive motors, relays and LED strips through a transistor or driver board.
  • Use a resistor with every LED.
  • Never connect two outputs together, or an output straight to ground.

Pin numbering

There are two ways of numbering the pins, which causes endless confusion:
  • Physical numbers: 1 to 40, by position on the header.
  • GPIO (BCM) numbers: the chip's own names, such as GPIO17.
Most Python libraries, including the one below, use GPIO numbers. Keep a pinout diagram for your model handy. Running the command pinout in a terminal on Raspberry Pi OS prints one.

Inputs and pull-up resistors

A GPIO input that is connected to nothing floats and reads randomly. A pull-up resistor holds it HIGH until something pulls it LOW; a pull-down does the opposite. The Pi has internal pull-ups and pull-downs you switch on in software, so a simple button needs no extra resistor:
  • wire one side of the button to a GPIO pin and the other to a GND pin
  • enable the pull-up: the pin reads HIGH when released, LOW when pressed

Lighting an LED with Python

The friendliest library is gpiozero, which comes with Raspberry Pi OS. On the newest models, the older RPi.GPIO library cannot reach the pins in the same way, which is another reason to use gpiozero. Wiring, with the Pi switched off:
  1. GPIO17 to a resistor (a few hundred ohms suits most LEDs at 3.3 V).
  2. The resistor to the LED's longer leg (anode).
  3. The LED's shorter leg (cathode) to a GND pin.
The program, saved as blink.py: from gpiozero import LED from time import sleep led = LED(17) while True: led.on() sleep(1) led.off() sleep(1) Run it with python3 blink.py and stop it with Ctrl+C.

Adding a button

gpiozero's Button uses the internal pull-up by default. Wire a button between GPIO2 and GND, and: from gpiozero import LED, Button from signal import pause led = LED(17) button = Button(2) button.when_pressed = led.on button.when_released = led.off pause() The LED lights while the button is held.

Where to go next

  • PWM: gpiozero's PWMLED fades an LED smoothly.
  • Sensors that use I2C or SPI, enabled in the Raspberry Pi configuration tool.
  • A breakout board that labels each pin, which makes breadboard work much easier.
  • For timing-critical hardware, consider a microcontroller alongside the Pi.
Not sure whether a module is safe to connect? Ask in the comments before wiring it, and share your first GPIO projects there too.

Comments (0)