Raspberry Pi GPIO - Python
Python examples for accessing Raspberry Pi GPIO, I2C, SPI, I2S, and PWM.
GPIO (Digital I/O)
Installation
1# Install RPi.GPIO
2sudo apt install python3-rpi.gpio
3
4# Or use pip
5pip3 install RPi.GPIO
6
7# Alternative: gpiozero (higher-level)
8pip3 install gpiozero
Basic GPIO (RPi.GPIO)
1import RPi.GPIO as GPIO
2import time
3
4# Set mode (BCM or BOARD)
5GPIO.setmode(GPIO.BCM) # Use BCM pin numbering
6
7# Setup pins
8LED_PIN = 18
9BUTTON_PIN = 23
10
11GPIO.setup(LED_PIN, GPIO.OUT) # Output
12GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
13
14# Digital output
15GPIO.output(LED_PIN, GPIO.HIGH)
16time.sleep(1)
17GPIO.output(LED_PIN, GPIO.LOW)
18
19# Digital input
20button_state = GPIO.input(BUTTON_PIN)
21if button_state == GPIO.LOW:
22 print("Button pressed!")
23
24# Cleanup
25GPIO.cleanup()
GPIO with gpiozero (Recommended)
1from gpiozero import LED, Button
2from signal import pause
3
4# LED
5led = LED(18)
6led.on()
7led.off()
8led.toggle()
9led.blink(on_time=1, off_time=1) # Blink every second
10
11# Button
12button = Button(23)
13
14def button_pressed():
15 print("Button pressed!")
16 led.toggle()
17
18button.when_pressed = button_pressed
19
20# Keep program running
21pause()
PWM (Pulse Width Modulation)
Software PWM
1import RPi.GPIO as GPIO
2import time
3
4GPIO.setmode(GPIO.BCM)
5LED_PIN = 18
6GPIO.setup(LED_PIN, GPIO.OUT)
7
8# Create PWM instance (pin, frequency in Hz)
9pwm = GPIO.PWM(LED_PIN, 1000)
10
11# Start PWM (duty cycle 0-100%)
12pwm.start(0)
13
14# Fade in
15for duty in range(0, 101, 5):
16 pwm.ChangeDutyCycle(duty)
17 time.sleep(0.1)
18
19# Fade out
20for duty in range(100, -1, -5):
21 pwm.ChangeDutyCycle(duty)
22 time.sleep(0.1)
23
24pwm.stop()
25GPIO.cleanup()
Hardware PWM (pigpio)
1import pigpio
2import time
3
4# Connect to pigpio daemon
5pi = pigpio.pi()
6
7if not pi.connected:
8 exit()
9
10PWM_PIN = 18
11
12# Set PWM frequency (Hz)
13pi.set_PWM_frequency(PWM_PIN, 1000)
14
15# Set PWM duty cycle (0-255)
16pi.set_PWM_dutycycle(PWM_PIN, 128) # 50%
17
18# Fade
19for i in range(0, 256, 5):
20 pi.set_PWM_dutycycle(PWM_PIN, i)
21 time.sleep(0.01)
22
23pi.set_PWM_dutycycle(PWM_PIN, 0)
24pi.stop()
I2C
Installation
1# Enable I2C
2sudo raspi-config
3# Interface Options > I2C > Enable
4
5# Install tools
6sudo apt install i2c-tools python3-smbus
7
8# Check I2C devices
9i2cdetect -y 1
I2C Communication
1import smbus2
2import time
3
4# I2C bus (1 for newer Pi, 0 for very old models)
5bus = smbus2.SMBus(1)
6
7# Device address (e.g., 0x48 for ADS1115)
8DEVICE_ADDR = 0x48
9
10# Write byte
11bus.write_byte_data(DEVICE_ADDR, 0x01, 0x83)
12
13# Read byte
14data = bus.read_byte_data(DEVICE_ADDR, 0x00)
15print(f"Read: {data}")
16
17# Read block
18block = bus.read_i2c_block_data(DEVICE_ADDR, 0x00, 2)
19print(f"Block: {block}")
20
21# Write block
22bus.write_i2c_block_data(DEVICE_ADDR, 0x01, [0x83, 0x00])
23
24bus.close()
I2C Example: BMP280 Sensor
1import smbus2
2import time
3
4class BMP280:
5 def __init__(self, address=0x76):
6 self.bus = smbus2.SMBus(1)
7 self.address = address
8
9 # Read calibration data
10 self.dig_T1 = self.read_uint16(0x88)
11 self.dig_T2 = self.read_int16(0x8A)
12 self.dig_T3 = self.read_int16(0x8C)
13
14 # Configure sensor
15 self.bus.write_byte_data(self.address, 0xF4, 0x27)
16
17 def read_uint16(self, reg):
18 data = self.bus.read_i2c_block_data(self.address, reg, 2)
19 return data[0] | (data[1] << 8)
20
21 def read_int16(self, reg):
22 val = self.read_uint16(reg)
23 return val if val < 32768 else val - 65536
24
25 def read_temperature(self):
26 # Read raw temperature
27 data = self.bus.read_i2c_block_data(self.address, 0xFA, 3)
28 adc_T = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
29
30 # Compensate
31 var1 = ((adc_T / 16384.0) - (self.dig_T1 / 1024.0)) * self.dig_T2
32 var2 = (((adc_T / 131072.0) - (self.dig_T1 / 8192.0)) ** 2) * self.dig_T3
33 t_fine = var1 + var2
34 temperature = t_fine / 5120.0
35
36 return temperature
37
38# Usage
39sensor = BMP280()
40temp = sensor.read_temperature()
41print(f"Temperature: {temp:.2f}°C")
SPI
Installation
1# Enable SPI
2sudo raspi-config
3# Interface Options > SPI > Enable
4
5# Install library
6pip3 install spidev
SPI Communication
1import spidev
2import time
3
4# Open SPI bus
5spi = spidev.SpiDev()
6spi.open(0, 0) # Bus 0, Device 0 (CE0)
7
8# Configure
9spi.max_speed_hz = 1000000 # 1 MHz
10spi.mode = 0 # SPI mode 0
11
12# Transfer data
13to_send = [0x01, 0x02, 0x03]
14received = spi.xfer2(to_send)
15print(f"Received: {received}")
16
17# Read data
18data = spi.readbytes(3)
19print(f"Read: {data}")
20
21# Write data
22spi.writebytes([0x01, 0x02, 0x03])
23
24spi.close()
SPI Example: MCP3008 ADC
1import spidev
2import time
3
4class MCP3008:
5 def __init__(self):
6 self.spi = spidev.SpiDev()
7 self.spi.open(0, 0)
8 self.spi.max_speed_hz = 1350000
9
10 def read_channel(self, channel):
11 if channel < 0 or channel > 7:
12 return -1
13
14 # Build command
15 cmd = [1, (8 + channel) << 4, 0]
16
17 # Send command and read response
18 reply = self.spi.xfer2(cmd)
19
20 # Extract 10-bit value
21 value = ((reply[1] & 3) << 8) + reply[2]
22
23 return value
24
25 def read_voltage(self, channel, vref=3.3):
26 value = self.read_channel(channel)
27 voltage = (value * vref) / 1023.0
28 return voltage
29
30 def close(self):
31 self.spi.close()
32
33# Usage
34adc = MCP3008()
35
36while True:
37 value = adc.read_channel(0)
38 voltage = adc.read_voltage(0)
39 print(f"Channel 0: {value} ({voltage:.2f}V)")
40 time.sleep(1)
I2S (Audio)
Installation
1# Enable I2S
2sudo raspi-config
3# Interface Options > I2S > Enable
4
5# Install libraries
6pip3 install pyaudio numpy
I2S Audio Playback
1import pyaudio
2import wave
3import numpy as np
4
5# Play WAV file
6def play_wav(filename):
7 chunk = 1024
8
9 wf = wave.open(filename, 'rb')
10
11 p = pyaudio.PyAudio()
12
13 stream = p.open(
14 format=p.get_format_from_width(wf.getsampwidth()),
15 channels=wf.getnchannels(),
16 rate=wf.getframerate(),
17 output=True
18 )
19
20 data = wf.readframes(chunk)
21
22 while data:
23 stream.write(data)
24 data = wf.readframes(chunk)
25
26 stream.stop_stream()
27 stream.close()
28 p.terminate()
29
30# Generate tone
31def generate_tone(frequency=440, duration=1, sample_rate=44100):
32 t = np.linspace(0, duration, int(sample_rate * duration))
33 wave_data = np.sin(2 * np.pi * frequency * t)
34
35 # Convert to 16-bit PCM
36 wave_data = (wave_data * 32767).astype(np.int16)
37
38 p = pyaudio.PyAudio()
39
40 stream = p.open(
41 format=pyaudio.paInt16,
42 channels=1,
43 rate=sample_rate,
44 output=True
45 )
46
47 stream.write(wave_data.tobytes())
48
49 stream.stop_stream()
50 stream.close()
51 p.terminate()
52
53# Usage
54play_wav('sound.wav')
55generate_tone(440, 2) # A4 note for 2 seconds
Complete Example: Weather Station
1from gpiozero import LED, Button
2import smbus2
3import time
4
5class WeatherStation:
6 def __init__(self):
7 self.led = LED(18)
8 self.button = Button(23)
9 self.bus = smbus2.SMBus(1)
10 self.bmp280_addr = 0x76
11
12 # Setup BMP280
13 self.bus.write_byte_data(self.bmp280_addr, 0xF4, 0x27)
14
15 # Button callback
16 self.button.when_pressed = self.read_and_display
17
18 def read_temperature(self):
19 # Simplified BMP280 reading
20 data = self.bus.read_i2c_block_data(self.bmp280_addr, 0xFA, 3)
21 adc_T = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
22 # ... (calibration code omitted for brevity)
23 return adc_T / 1000.0 # Simplified
24
25 def read_and_display(self):
26 self.led.on()
27 temp = self.read_temperature()
28 print(f"Temperature: {temp:.2f}°C")
29 time.sleep(0.5)
30 self.led.off()
31
32 def run(self):
33 print("Weather Station Running. Press button to read temperature.")
34 while True:
35 time.sleep(0.1)
36
37# Usage
38station = WeatherStation()
39station.run()
Best Practices
- Always cleanup GPIO - Use
try/finallyor context managers - Use pull-up/pull-down resistors - Prevent floating inputs
- Check voltage levels - RPi GPIO is 3.3V, not 5V tolerant!
- Use level shifters - For 5V devices
- Limit current - Use resistors with LEDs
- Enable interfaces - I2C, SPI, I2S must be enabled in raspi-config
Related Snippets
- Raspberry Pi GPIO - Go
Go examples for accessing Raspberry Pi GPIO, I2C, SPI, and PWM using periph.io. …