Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Raspberry Pi

Raspberry Pi GPIO Advanced: PWM, SPI and I2C Deep Dive

Raspberry Pi GPIO Advanced: PWM, SPI and I2C Deep Dive

March 11, 2026 /Posted byJayesh Jain / 0

Every Raspberry Pi tutorial starts with blinking an LED and ends with a DHT11 temperature reading. That is the right starting point — but if you want to build real projects, you need to go deeper. Hardware PWM for precise motor control, SPI for high-speed displays and ADCs, I2C for sensor networks, and the RP2040’s programmable I/O for bit-banging custom protocols — these are the tools that separate functional projects from impressive ones.

This guide assumes you are comfortable with basic GPIO (digital read/write, simple sensor interfacing) and takes you through the advanced capabilities of the Raspberry Pi’s GPIO system with practical Python examples and real component hookups.

GPIO Architecture: Hardware Versus Software

The Raspberry Pi’s BCM283x/BCM2712 SoC exposes 40 GPIO pins, but not all pins are equal. Understanding the hardware capabilities of specific pins avoids frustrating bugs later.

Pin Numbering Systems

Three numbering systems coexist in Pi documentation, and confusing them is a constant source of errors:

  • BCM (Broadcom) numbers: The GPIO chip’s internal numbering. Most Python libraries (RPi.GPIO, gpiozero, lgpio) use BCM by default. GPIO 18 = BCM pin 18.
  • Physical (board) numbers: The literal pin position on the 40-pin header, 1–40. Pin 12 on the board = BCM GPIO 18.
  • WiringPi numbers: A third scheme from the wiringPi library. Largely deprecated — avoid it for new projects.

Always specify your numbering scheme explicitly in code. In RPi.GPIO: GPIO.setmode(GPIO.BCM) or GPIO.setmode(GPIO.BOARD). In gpiozero, all pin numbers are BCM by default.

GPIO Electrical Characteristics

Pi GPIO operates at 3.3V logic — not 5V tolerant. Connecting a 5V signal directly to a Pi GPIO pin risks permanent damage. Always use a level shifter (e.g., TXS0108E) between 5V microcontrollers/sensors and the Pi. Maximum current per GPIO pin is 16 mA, total GPIO bank limit is 51 mA. Drive LEDs through resistors — never direct-connect without current limiting.

Hardware PWM: Precision Servo and Motor Control

Software PWM (bit-banged by the CPU) works for LEDs but fails for servos and ESCs because Linux’s multitasking introduces timing jitter that causes servo jitter. Hardware PWM uses dedicated silicon timers and is not affected by CPU load.

Raspberry Pi exposes hardware PWM on four channels:

  • PWM0: GPIO 12 (physical pin 32) and GPIO 18 (physical pin 12)
  • PWM1: GPIO 13 (physical pin 33) and GPIO 19 (physical pin 35)

Only one pin per channel can be active at a time (GPIO 12 OR GPIO 18 for PWM0). Enable hardware PWM via the device tree overlay in /boot/config.txt:

dtoverlay=pwm-2chan,pin=18,func=2,pin2=13,func2=4

Reboot, then control PWM via the sysfs interface or the pigpio library. The pigpio daemon provides the best hardware PWM interface in Python:

import pigpio
import time

pi = pigpio.pi()

# Set servo pulse on GPIO 18
# Pulse width 1000–2000 microseconds = 0–180 degrees
for angle in range(0, 181, 10):
    pulse_width = 1000 + int(angle / 180 * 1000)
    pi.set_servo_pulsewidth(18, pulse_width)
    time.sleep(0.05)

pi.set_servo_pulsewidth(18, 0)  # Stop PWM
pi.stop()

This produces jitter-free servo movement. For motor speed control (DC motor via L298N or DRV8833), use pi.hardware_PWM(18, 1000, 500000) — frequency 1 kHz, 50% duty cycle.

Recommended: Raspberry Pi 5 Model 4GB RAM — the Pi 5 uses the RP1 I/O controller chip which provides improved GPIO performance including more reliable hardware PWM. For robotics projects requiring precise servo control across multiple channels, the Pi 5 is the strongest foundation.

SPI Deep Dive: High-Speed Peripheral Communication

SPI (Serial Peripheral Interface) is a synchronous four-wire protocol capable of multi-megabit speeds. It is used by displays (ILI9341, ST7789, SSD1351), ADCs (MCP3008, ADS1256), DACs, SD card interfaces, and many sensors requiring fast data transfer.

SPI Pins on Raspberry Pi

  • MOSI (Master Out Slave In): GPIO 10 (SPI0) / GPIO 20 (SPI1)
  • MISO (Master In Slave Out): GPIO 9 (SPI0) / GPIO 19 (SPI1)
  • SCLK (Clock): GPIO 11 (SPI0) / GPIO 21 (SPI1)
  • CE0 (Chip Enable 0): GPIO 8 (SPI0) / GPIO 18 (SPI1)
  • CE1 (Chip Enable 1): GPIO 7 (SPI0)

Enable SPI in raspi-config → Interface Options → SPI, or add dtparam=spi=on to /boot/config.txt.

Reading an MCP3008 ADC via SPI

The MCP3008 is an 8-channel 10-bit ADC that connects to the Pi via SPI, providing analogue inputs that the Pi’s GPIO lacks. This is essential for reading potentiometers, analogue sensors (LDR, soil moisture), and other non-digital signals.

import spidev

spi = spidev.SpiDev()
spi.open(0, 0)  # Bus 0, device 0 (CE0)
spi.max_speed_hz = 1000000
spi.mode = 0

def read_channel(channel):
    # MCP3008 single-ended read
    adc = spi.xfer2([1, (8 + channel) << 4, 0])
    data = ((adc[1] & 3) << 8) + adc[2]
    return data

def read_voltage(channel, vref=3.3):
    raw = read_channel(channel)
    return (raw / 1023.0) * vref

print(f'CH0 voltage: {read_voltage(0):.3f}V')
spi.close()

Driving an SPI Display (ST7789)

The ST7789 240×240 colour LCD uses SPI at up to 80 MHz. Install the luma.lcd library and the Pillow image library, then you can draw text, shapes, and images to the display from Python. For the Raspberry Pi, the st7789 Python library (by Pimoroni) provides the simplest interface.

Recommended: Waveshare 0.71inch Round LCD Display Module, 160×160 Resolution, SPI Interface, 65K colours — a compact round SPI display perfect for instrument panels, clock faces, and sensor readouts. Uses the GC9A01 driver compatible with many MicroPython and Python libraries.

I2C Deep Dive: Building Sensor Networks

I2C (Inter-Integrated Circuit) uses just two wires — SDA (data) and SCL (clock) — to connect up to 128 devices on the same bus. This makes it ideal for sensor networks where you want multiple sensors without using many GPIO pins.

I2C Pins on Raspberry Pi

  • I2C0: GPIO 0 (SDA) / GPIO 1 (SCL) — reserved for HAT identification, avoid for user devices
  • I2C1: GPIO 2 (SDA) / GPIO 3 (SCL) — the standard user I2C bus

Enable I2C: raspi-config → Interface Options → I2C.

Scanning the I2C Bus

Always scan first to confirm your devices are detected and note their addresses:

sudo i2cdetect -y 1

This prints a grid showing which addresses have responding devices. Common addresses: SSD1306 OLED at 0x3C, BMP280 at 0x76 or 0x77, MPU6050 IMU at 0x68, PCF8574 I/O expander at 0x20–0x27.

Reading BMP280 Pressure and Temperature via I2C

import smbus2
import bmp280

bus = smbus2.SMBus(1)  # I2C bus 1
sensor = bmp280.BMP280(i2c_dev=bus)

print(f'Temperature: {sensor.get_temperature():.2f}°C')
print(f'Pressure:    {sensor.get_pressure():.2f} hPa')
print(f'Altitude:    {sensor.get_altitude():.2f} m')

Install the library: pip3 install bmp280 smbus2. The BMP280 is excellent for weather stations and altitude measurement projects.

Recommended: BMP280 Barometric Pressure and Altitude Sensor I2C/SPI Module — supports both I2C and SPI interfaces (address selectable via SDO pin). Measures pressure to ±1 hPa and temperature to ±1°C. Ideal for weather stations, altitude loggers, and indoor climate monitoring with Raspberry Pi.

I2C Bus at Higher Speeds

The default I2C speed is 100 kHz. Many modern I2C devices support 400 kHz (Fast Mode) or even 1 MHz. Speed up the bus by adding to /boot/config.txt:

dtparam=i2c_arm_baudrate=400000

Higher speed matters when reading multiple sensors in a tight loop — a 10-sensor read at 100 kHz might take 10 ms; at 400 kHz it takes 2.5 ms. Always check your specific sensors’ maximum I2C speed before increasing — some older sensors only support 100 kHz.

Combining SPI and I2C in a Single Project

Real projects often need both buses simultaneously. For example: an I2C sensor network (BMP280 + SHT31 + MPU6050) feeding data to an SPI display (ST7789) with PWM-controlled RGB LED status indicators. This is entirely achievable on a single Pi — the hardware handles all three protocols independently.

A practical pattern for multi-peripheral projects:

  1. Initialise all buses in a setup function
  2. Use a main loop with a time budget — sensor reads on a 100 ms tick, display update on a 500 ms tick
  3. Handle I2C errors gracefully (some sensors time out) — wrap reads in try/except IOError
  4. Log data with timestamps to a CSV file for analysis
Recommended: GY-BME280 Precision Altimeter Atmospheric Pressure and Humidity Sensor — an upgrade over the BMP280 that adds humidity measurement. Three sensors in one I2C device: temperature (±0.5°C), pressure (±1 hPa), humidity (±3% RH). Excellent for complete indoor climate logging projects.

Advanced GPIO Techniques

Interrupt-Driven GPIO

Polling GPIO pins in a loop wastes CPU time. Use hardware interrupts instead — the GPIO hardware detects an edge (rising, falling, or both) and calls your callback function immediately:

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def button_callback(channel):
    print(f'Button pressed on GPIO {channel}')

GPIO.add_event_detect(23, GPIO.FALLING, 
                       callback=button_callback,
                       bouncetime=200)  # 200ms debounce

input('Press Enter to quitn')
GPIO.cleanup()

GPIO with asyncio

For modern Python async projects, the gpiozero library integrates with asyncio through its when_pressed/when_released event model. This allows GPIO monitoring alongside async network operations (MQTT, HTTP server) in a single-threaded event loop.

Using lgpio for GPIO on Pi 5

The Raspberry Pi 5 uses a new RP1 I/O controller chip. The legacy RPi.GPIO library has compatibility issues on Pi 5. Use lgpio or gpiozero (which uses lgpio as its backend on Pi 5) for forward-compatible code:

pip3 install lgpio

Frequently Asked Questions

Can I use more than two I2C devices on the same bus?

Yes — I2C supports up to 128 devices on one bus (7-bit addressing). The practical limit is lower because most sensors come in only two or three address variants. If you need more identical sensors, use an I2C multiplexer like the TCA9548A, which provides 8 separate I2C bus segments switchable via the same two-wire interface.

What is the maximum SPI speed on Raspberry Pi?

The Pi’s SPI hardware supports up to 125 MHz theoretically, but practical limits depend on wire length, capacitance, and the slave device. For most displays and ADCs, 4–32 MHz is the working range. Long wires reduce the maximum safe speed significantly — keep SPI connections short (under 30 cm) for high speeds.

Why does my servo jitter even with hardware PWM?

Check that you are using the pigpio daemon-based approach rather than sysfs PWM or software PWM. Also verify your power supply — servos draw significant current and a weak USB supply causes voltage drops that affect the Pi’s GPIO output voltage and thus servo behaviour. Use a dedicated servo power supply and share only ground with the Pi.

Can I run SPI and I2C on the same GPIO pins?

No — SPI and I2C use different pin functions. SPI0 uses GPIO 7–11; I2C1 uses GPIO 2–3. They do not conflict. You can run both buses simultaneously. If you need more SPI devices, use separate CE (chip enable) lines — the Pi supports CE0 and CE1 on SPI0, and you can use any GPIO as a software CE for additional devices.

How do I handle 5V sensors with the Pi’s 3.3V GPIO?

Use a bidirectional logic level shifter module (TXS0108E or similar). For simple one-directional signals (sensor output → Pi input), a voltage divider (two resistors) works: a 10kΩ + 20kΩ divider on the signal line shifts 5V down to 3.3V. Never connect a 5V output directly to a Pi GPIO input.

Conclusion

Mastering hardware PWM, SPI, and I2C unlocks the full potential of Raspberry Pi GPIO for professional-grade electronics projects. Hardware PWM delivers jitter-free servo and motor control. SPI enables high-speed displays and precision ADCs. I2C makes it easy to connect a network of sensors with minimal wiring. Together, these three protocols cover the vast majority of real-world peripheral interfacing you will ever encounter.

The key to success is understanding which pins have hardware support for each function, choosing the right Python library for your Pi model (lgpio/gpiozero for Pi 5, RPi.GPIO or pigpio for older models), and handling errors gracefully so your long-running projects remain stable.

Find sensors, displays, and Raspberry Pi boards for your next GPIO project at Zbotic.in — India’s maker electronics store with fast delivery and expert technical support.

Tags: Electronics, i2c raspberry pi, pwm raspberry pi, python gpio, raspberry pi gpio, spi raspberry pi
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Arduino Serial Communication: ...
blog arduino serial communication uart softwareserial debugging 595035
blog arduino mega 2560 buying guide best uses projects 595041
Arduino Mega 2560 Buying Guide...

Related posts

Svg%3E
Read more

Raspberry Pi Benchmarks: Performance Testing All Models

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi PoE: Power Over Ethernet Setup Guide

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi GSM HAT: SMS and Cellular IoT

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi RS485: Industrial Sensor Network

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading
Svg%3E
Read more

Raspberry Pi CAN Bus: Vehicle OBD2 Data Reader

April 1, 2026 0
Table of Contents Introduction and Use Cases Hardware Requirements Software Installation Configuration and Setup Testing and Validation Advanced Features Troubleshooting... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now