CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-gpiozero

A simple interface to GPIO devices with Raspberry Pi

Pending
Overview
Eval results
Files

spi-devices.mddocs/

SPI Devices

SPI-connected devices including analog-to-digital converters (ADCs) from the MCP3xxx family. These devices enable reading analog sensor values and can be used as sources for other devices.

Base Classes

SPIDevice

Base class for all SPI-connected devices.

class SPIDevice(Device):
    def __init__(self, *, port=0, device=0, pin_factory=None):
        """
        Base class for SPI devices.
        
        Parameters:
        - port: int - SPI port number (usually 0)
        - device: int - SPI device number (chip select)
        - pin_factory: Factory or None - Pin factory for advanced usage
        """

    @property
    def closed(self) -> bool:
        """Returns True if device is closed."""

    def close(self):
        """Close the device and release resources."""

AnalogInputDevice

Base class for analog-to-digital converter devices.

class AnalogInputDevice(SPIDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        Base class for ADC devices.
        
        Parameters:
        - channel: int - ADC channel number to read from
        - differential: bool - True for differential reading, False for single-ended
        - max_voltage: float - Maximum input voltage for scaling
        - **spi_args: Additional SPI configuration arguments
        """

    @property
    def value(self) -> float:
        """Current analog reading scaled to 0.0-1.0 range."""

    @property
    def voltage(self) -> float:
        """Current reading as voltage (0.0 to max_voltage)."""

    @property
    def raw_value(self) -> int:
        """Raw ADC reading as integer."""

    @property
    def channel(self) -> int:
        """ADC channel being read."""

    @property
    def differential(self) -> bool:
        """True if using differential reading mode."""

    @property
    def max_voltage(self) -> float:
        """Maximum input voltage for scaling."""

MCP30xx Series (10-bit ADCs)

MCP3001

Single-channel 10-bit ADC.

class MCP3001(AnalogInputDevice):
    def __init__(self, *, max_voltage=3.3, **spi_args):
        """
        MCP3001 10-bit single-channel ADC.
        
        Parameters:
        - max_voltage: float - Maximum input voltage (default 3.3V)
        - **spi_args: SPI configuration (port, device, etc.)
        """

MCP3002

Dual-channel 10-bit ADC.

class MCP3002(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3002 10-bit dual-channel ADC.
        
        Parameters:
        - channel: int - Channel number (0 or 1)
        - differential: bool - True for differential mode
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

MCP3004

4-channel 10-bit ADC.

class MCP3004(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3004 10-bit 4-channel ADC.
        
        Parameters:
        - channel: int - Channel number (0-3)
        - differential: bool - True for differential mode
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

MCP3008

8-channel 10-bit ADC (most commonly used).

class MCP3008(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3008 10-bit 8-channel ADC.
        
        Parameters:
        - channel: int - Channel number (0-7)
        - differential: bool - True for differential mode
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration (port=0, device=0)
        """

MCP32xx Series (12-bit ADCs)

MCP3201

Single-channel 12-bit ADC.

class MCP3201(AnalogInputDevice):
    def __init__(self, *, max_voltage=3.3, **spi_args):
        """
        MCP3201 12-bit single-channel ADC.
        
        Parameters:
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

MCP3202

Dual-channel 12-bit ADC.

class MCP3202(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3202 12-bit dual-channel ADC.
        
        Parameters:
        - channel: int - Channel number (0 or 1)
        - differential: bool - True for differential mode
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

MCP3204

4-channel 12-bit ADC.

class MCP3204(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3204 12-bit 4-channel ADC.
        
        Parameters:
        - channel: int - Channel number (0-3)  
        - differential: bool - True for differential mode
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

MCP3208

8-channel 12-bit ADC.

class MCP3208(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3208 12-bit 8-channel ADC.
        
        Parameters:
        - channel: int - Channel number (0-7)
        - differential: bool - True for differential mode  
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

MCP33xx Series (13-bit Signed ADCs)

MCP3301

Single-channel 13-bit signed ADC.

class MCP3301(AnalogInputDevice):
    def __init__(self, *, max_voltage=3.3, **spi_args):
        """
        MCP3301 13-bit single-channel signed ADC.
        
        Parameters:
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

MCP3302

4-channel 13-bit signed ADC.

class MCP3302(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3302 13-bit 4-channel signed ADC.
        
        Parameters:
        - channel: int - Channel number (0-3)
        - differential: bool - True for differential mode
        - max_voltage: float - Maximum input voltage  
        - **spi_args: SPI configuration
        """

MCP3304

8-channel 13-bit signed ADC.

class MCP3304(AnalogInputDevice):
    def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args):
        """
        MCP3304 13-bit 8-channel signed ADC.
        
        Parameters:
        - channel: int - Channel number (0-7)
        - differential: bool - True for differential mode
        - max_voltage: float - Maximum input voltage
        - **spi_args: SPI configuration
        """

Usage Examples

Basic Analog Reading

from gpiozero import MCP3008
from time import sleep

# Single channel reading
adc = MCP3008(channel=0)

while True:
    value = adc.value      # 0.0 to 1.0
    voltage = adc.voltage  # 0.0 to 3.3V (or max_voltage)
    raw = adc.raw_value    # Raw ADC counts
    
    print(f"Value: {value:.3f}, Voltage: {voltage:.2f}V, Raw: {raw}")
    sleep(0.5)

Multiple Channel Reading

from gpiozero import MCP3008

# Create ADC objects for different channels
channels = [MCP3008(channel=i) for i in range(4)]

while True:
    readings = [adc.value for adc in channels]
    print(f"Channels 0-3: {readings}")
    sleep(0.1)

Potentiometer Control

from gpiozero import MCP3008, PWMLED
from signal import pause

pot = MCP3008(channel=0)
led = PWMLED(17)

# LED brightness follows potentiometer
led.source = pot

pause()

Analog Sensor with Thresholds

from gpiozero import MCP3008, LED
from time import sleep

sensor = MCP3008(channel=0)
warning_led = LED(17)
alarm_led = LED(18)

while True:
    value = sensor.value
    
    if value > 0.8:
        warning_led.off()
        alarm_led.on()
        print("ALARM: High reading!")
    elif value > 0.6:
        warning_led.on()
        alarm_led.off()
        print("Warning: Elevated reading")
    else:
        warning_led.off()
        alarm_led.off()
        print(f"Normal: {value:.3f}")
    
    sleep(0.5)

Temperature Sensor (TMP36)

from gpiozero import MCP3008
from time import sleep

# TMP36 temperature sensor on channel 0
temp_sensor = MCP3008(channel=0)

while True:
    voltage = temp_sensor.voltage
    # TMP36: 10mV per degree C, 500mV offset, 0°C = 0.5V
    temperature_c = (voltage - 0.5) * 100
    temperature_f = temperature_c * 9/5 + 32
    
    print(f"Temperature: {temperature_c:.1f}°C ({temperature_f:.1f}°F)")
    sleep(1)

Light Sensor (Photoresistor)

from gpiozero import MCP3008, LED
from signal import pause

# Photoresistor voltage divider on channel 0
light_sensor = MCP3008(channel=0)
night_light = LED(17)

def update_light():
    light_level = light_sensor.value
    # Turn on LED when it's dark (low light reading)
    night_light.value = 1 - light_level

# Update every 100ms
light_sensor.when_changed = update_light

pause()

Differential Reading

from gpiozero import MCP3008

# Differential reading between channels 0 and 1
diff_adc = MCP3008(channel=0, differential=True)

while True:
    # This reads the voltage difference between CH0+ and CH0- (CH1)
    diff_voltage = diff_adc.voltage
    print(f"Differential voltage: {diff_voltage:.3f}V")
    sleep(0.1)

Data Logging

from gpiozero import MCP3008
import csv
import time

sensors = [MCP3008(channel=i) for i in range(3)]

with open('sensor_data.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['timestamp', 'channel_0', 'channel_1', 'channel_2'])
    
    try:
        while True:
            timestamp = time.time()
            readings = [sensor.voltage for sensor in sensors]
            writer.writerow([timestamp] + readings)
            print(f"Logged: {readings}")
            time.sleep(1)
    except KeyboardInterrupt:
        print("Data logging stopped")

Custom Voltage Reference

from gpiozero import MCP3008

# Using 5V reference instead of default 3.3V
adc_5v = MCP3008(channel=0, max_voltage=5.0)

while True:
    voltage = adc_5v.voltage  # Now scaled to 0-5V range
    print(f"Voltage (5V ref): {voltage:.2f}V")
    sleep(0.5)

SPI Configuration

All MCP3xxx devices support additional SPI configuration parameters:

# Custom SPI configuration
adc = MCP3008(
    channel=0,
    port=0,           # SPI port (usually 0)
    device=1,         # Chip select (CE1 instead of CE0)  
    max_voltage=5.0,  # Voltage reference
    differential=False # Single-ended reading
)

Common SPI connections on Raspberry Pi:

  • MOSI: GPIO 10 (Pin 19)
  • MISO: GPIO 9 (Pin 21)
  • SCLK: GPIO 11 (Pin 23)
  • CE0: GPIO 8 (Pin 24) - device=0
  • CE1: GPIO 7 (Pin 26) - device=1

Install with Tessl CLI

npx tessl i tessl/pypi-gpiozero

docs

composite-devices.md

index.md

input-devices.md

output-devices.md

pin-factories.md

spi-devices.md

system-monitoring.md

tone-system.md

tools.md

tile.json