0
0
Iot-protocolsProgramBeginner · 2 min read

Raspberry Pi Program to Read Analog Sensor Using MCP3008

Use the spidev library on Raspberry Pi to communicate with MCP3008 and read analog sensor values by sending SPI commands; for example, open SPI, send read command for channel, and convert response to sensor value.
📋

Examples

InputAnalog sensor connected to channel 0 with voltage 1.65V
OutputSensor value: 512
InputAnalog sensor connected to channel 1 with voltage 3.3V
OutputSensor value: 1023
InputAnalog sensor connected to channel 2 with voltage 0V
OutputSensor value: 0
🧠

How to Think About It

To read an analog sensor with MCP3008 on Raspberry Pi, you use SPI communication. The MCP3008 converts analog voltage to a digital number. You send a command over SPI to select the channel, then read the response bytes. These bytes contain the sensor's digital value, which you convert to a number between 0 and 1023.
📐

Algorithm

1
Initialize SPI communication on Raspberry Pi.
2
Send a 3-byte command to MCP3008 to select the analog input channel.
3
Receive 3 bytes response from MCP3008.
4
Extract the 10-bit analog value from the response bytes.
5
Return or print the analog sensor value.
💻

Code

python
import spidev
import time

spi = spidev.SpiDev()
spi.open(0, 0)  # Open SPI bus 0, device (CS) 0
spi.max_speed_hz = 1350000

def read_channel(channel):
    if channel < 0 or channel > 7:
        return -1
    adc = spi.xfer2([1, (8 + channel) << 4, 0])
    data = ((adc[1] & 3) << 8) + adc[2]
    return data

try:
    while True:
        sensor_value = read_channel(0)
        print(f"Sensor value: {sensor_value}")
        time.sleep(1)
except KeyboardInterrupt:
    spi.close()
Output
Sensor value: 512 Sensor value: 513 Sensor value: 511 ...
🔍

Dry Run

Let's trace reading channel 0 with a sensor voltage that gives a mid-scale value.

1

Open SPI bus

spi.open(0, 0) opens SPI bus 0, device 0.

2

Send command to MCP3008

spi.xfer2([1, (8 + 0) << 4, 0]) sends [1, 128, 0] to select channel 0.

3

Receive response bytes

MCP3008 returns 3 bytes, e.g., [0, 2, 0] where adc[1] = 2, adc[2] = 0.

4

Calculate sensor value

data = ((2 & 3) << 8) + 0 = (2 << 8) + 0 = 512.

5

Print sensor value

Prints 'Sensor value: 512'.

StepSPI Bytes SentSPI Bytes ReceivedCalculated Value
1[1, 128, 0][0, 2, 0]512
💡

Why This Works

Step 1: SPI Communication Setup

The spidev library opens SPI bus 0 and device 0 to communicate with MCP3008.

Step 2: Sending Read Command

The command [1, (8 + channel) << 4, 0] tells MCP3008 which channel to read.

Step 3: Extracting Analog Value

The response bytes contain the 10-bit analog value split across bits; combining them gives the sensor reading.

🔄

Alternative Approaches

Using gpiozero library
python
from gpiozero import MCP3008
import time

pot = MCP3008(channel=0)

try:
    while True:
        print(f"Sensor value: {pot.value * 1023:.0f}")
        time.sleep(1)
except KeyboardInterrupt:
    pass
gpiozero simplifies reading MCP3008 but adds a dependency and less control over SPI.
Using Adafruit CircuitPython MCP3xxx library
python
import board
import busio
import digitalio
import adafruit_mcp3xxx.mcp3008 as MCP
from adafruit_mcp3xxx.analog_in import AnalogIn

spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
cs = digitalio.DigitalInOut(board.D5)
mcp = MCP.MCP3008(spi, cs)
chan = AnalogIn(mcp, MCP.P0)

while True:
    print(f"Sensor value: {chan.value}")
This method uses CircuitPython libraries for easier hardware abstraction but requires installing Adafruit packages.

Complexity: O(1) time, O(1) space

Time Complexity

Reading from MCP3008 involves a fixed number of SPI transfers, so it runs in constant time O(1).

Space Complexity

The program uses a small fixed amount of memory for SPI buffers and variables, so space complexity is O(1).

Which Approach is Fastest?

Direct use of spidev is fastest and most flexible; gpiozero and CircuitPython add abstraction but slightly reduce speed.

ApproachTimeSpaceBest For
spidev directO(1)O(1)Speed and control
gpiozero libraryO(1)O(1)Ease of use, beginners
CircuitPython libraryO(1)O(1)Hardware abstraction, Adafruit devices
💡
Always check your wiring and SPI bus number before running the MCP3008 code.
⚠️
Beginners often forget to enable SPI interface on Raspberry Pi or use wrong SPI bus/device numbers.