Raspberry Pi: Read Analog Inputs with Python (MCP3008)

In this guide, you’ll learn how to read analog signals on the Raspberry Pi GPIOs using a Python program. The Raspberry Pi can only read digital signals. To read analog signals, we need to use an analog-to-digital converter like the MCP3008, for example. As an example, we’ll read the values from a potentiometer, but the example can be applied to any analog sensor. We’ll use the gpiozero interface.

Read Raspberry Pi Analog Inputs with Python MCP3008

Table of Contents

Throughout this tutorial, we’ll cover the following main topics:

  1. Introducing the Raspberry Pi GPIOs
  2. Introducing the MCP3008 Analog-to-Digital Converter
  3. Wire the Raspberry Pi to the MCP3008
  4. Enabling SPI on the Raspberry Pi
  5. Reading Analog Signals with the Raspberry Pi – Python Script

Prerequisites

Before continuing with this tutorial, check the following prerequisites.

  1. Get familiar with the Raspberry Pi board—if you’re not familiar with the Raspberry Pi, you can read our Raspberry Pi Getting Started Guide here.
  2. You must know how to run and create Python files on your Raspberry Pi. We like to program our Raspberry Pi via SSH using an extension on VS Code. We have a detailed tutorial about that subject: Programming Raspberry Pi Remotely using VS Code (Remote-SSH).

Introducing the Raspberry Pi GPIOs

GPIO stands for General Purpose Input Output pins and those allow you to connect and control electronic hardware, like LEDs, motors, and sensors to your Raspberry Pi.

Most models of Raspberry Pi boards have a double row of 40 GPIO pins. The layout of the pins is usually the same for most Raspberry Pi models.

Raspberry Pi Random Nerd Tutorials

If you’re not familiar with the Raspberry Pi GPIOs, we recommend taking a look at our Raspberry Pi Pinout Guide:

Project Overview

To show you how to read analog signals with the Raspberry Pi GPIOs, we’ll build a simple project to control the brightness of an LED using a potentiometer. So, you’ll learn how to read analog signals with the Raspberry Pi and output PWM signals.

Raspberry Pi read Analog Inputs with MCP3008 Potentiometer

For an introduction to PWM signals with the Raspberry Pi, read the following guide:

To learn how potentiometers work, you can read this guide:

Parts Required

For this project, you’ll need the following parts:

Here’s a list of components you need:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Reading Analog Signals with the Raspberry Pi

The Raspberry Pi GPIOs can only read digital signals—they can read either HIGH (3.3V) or LOW (0V), but they can’t read any voltages in between. To be able to read varying voltage levels, we need to use an analog-to-digital converter chip like the MCP3008.

Introducing the MCP3008 Analog-to-Digital Converter

The figure below shows an MCP3008 analog-to-digital converter chip.

MCP3008 chip analog to digital converter

The MCP3008 chip is a 10-bit digital-to-analog converter that reads analog signals and sends them to a microcontroller via SPI communication protocol (SPI signals that the Raspberry Pi can read).

The MCP3008 comes with 16 pins. Half of those pins are analog inputs that you can use to connect to analog devices. The other 8 pins connect to the Raspberry Pi GPIOs.

MCP3008 pin numbering

The following table shows the pinout of the MCP3008 chip. To correctly identify each pin, place the chip with the half-circle mark at the top and follow the notation of the picture above.

PinSymbolDescription
1CH0Analog input (channel 0)
2CH1Analog input (channel 1)
3CH2Analog input (channel 2)
4CH3Analog input (channel 3)
5CH4Analog input (channel 4)
6CH5Analog input (channel 5)
7CH6Analog input (channel 6)
8CH7Analog input (channel 7)
9DGNDDigital ground
10CS/SHDNChip select/shutdown pin
11DinSerial data in
12DoutSerial data out
13CLKSerial clock
14AGNDAnalog ground
15VRefReference voltage input
16VDD+2.7V to 5.5V power supply

Wiring the MCP3008 Chip to the Raspberry Pi

The 8 pins at the left side of the MCP3008 are eight different analog channels. You can connect up to 8 analog devices using those channels. The pins on the right side connect to the Raspberry Pi.

The easiest way to wire an MCP3008 chip to the Raspberry Pi is using a breadboard. Place the MCP3008 chip in the middle of the breadboard. Then, connect it as shown in the following table:

MCP3008 PinRaspberry Pi
1Analog Output
(potentiometer or analog sensor)
9GND
10GPIO 8
11GPIO 10
12GPIO 9
13GPIO 11
14GND
153.3V
163.3V

You can also use the following diagram as a reference. We’re also wiring an LED to GPIO 14.

Wire potentiometer to Raspberry Pi using MCP3008

Enabling SPI on the Raspberry Pi

By default, SPI communication is not enabled on the Raspberry Pi. Run the following command on the Raspberry Pi terminal window to enable SPI:

sudo raspi-config nonint do_spi 0

Reading Analog Signals with the Raspberry Pi – Python Script

The gpiozero library comes with an MCP3008 class, specially developed to read analog signals from the MCP3008 chip.

The following example reads the value from the potentiometer and adjusts the LED brightness accordingly:

  • read the analog input value from the potentiometer through the MCP3008 chip;
  • control the LED brightness using PWM;
  • change the PWM duty cycle accordingly to the input value from the potentiometer.

Create a new Python file called potentiometer_led.py and copy the following code.

# Complete Project Details: https://RandomNerdTutorials.com/raspberry-pi-analog-inputs-python-mcp3008/

from gpiozero import PWMLED, MCP3008
from time import sleep

#create an object called pot that refers to MCP3008 channel 0
pot = MCP3008(0)

#create a PWMLED object called led that refers to GPIO 14
led = PWMLED(14)

while True:
    if(pot.value < 0.001):
        led.value = 0
    else:
        led.value = pot.value
    print(pot.value)
    sleep(0.1)

View raw code

How to Read Analog Inputs on the Raspberry Pi

Reading analog inputs on the Raspberry Pi using the MCP3008 class is very straightforward.

1. Import the MCP3008 class.

from gpiozero import MCP3008

2. Create an MCP3008 object and pass as an argument the analog channel you’re using. You can create different MCP3008 objects on different channels if you’re using multiple analog peripherals.

pot = MCP3008(ANALOG_CHANNEL)

3. Read the value of the analog input using the value property.

pot.value

How the Code Works

Now that you know how to read analog inputs on the Raspberry Pi GPIOs, it’s easy to understand the code.

You start by importing the required libraries:

from gpiozero import PWMLED, MCP3008
from time import sleep

Then, you create an object called pot that refers to MCP3008 channel 0, which is the channel that the potentiometer is connected to. Remember that channel 0 corresponds to the MCP3008 pin 1, channel 1 to pin2, and so on.

pot = MCP3008(0)

You also create a PMWLED object called led to control the LED using PWM. To learn how to use PWM on the Raspberry Pi pins follow this tutorial.

led = PWMLED(14)

To read the analog value on the GPIO that the potentiometer is connected to, you simply use pot.value.

To adjust the LED brightness using PWM, you need to change its duty cycle – you just need to attribute a value between 0 and 1 to the led.value, in which 0 corresponds to a fully off LED and 1 to a fully on LED.

In this example, we’re using a while loop that is always True to keep the program running forever.

while True:

We’re constantly checking the value of the potentiometer. If the value is below 0.001, we set the duty cycle to zero to turn the LED off.

if(pot.value < 0.001):
    led.value = 0

Otheriwse, the code will run the else statement in which the duty cycle changes accordingly to the value read from the potentiometer.

else:
    led.value = pot.value
    print(pot.value)

Finally, we print the analog value of the potentiometer and wait 0.1 seconds before checking the potentiometer value again.

print(pot.value)
sleep(0.1)

Demonstration

Save your python file. Then run it on your Raspberry Pi. Run the following command on the directory of your project file (use the name of your file):

python potentiometer_led.py

After running the script, rotate the potentiometer and see the LED brightness adjusting accordingly.

You can stop the execution of the program by pressing CTRL+C.

Wrapping Up

In this tutorial, you learned how to read analog values on the Raspberry Pi GPIOs using a Python script. The Raspberry Pi GPIOs can’t read analog signals, so we need to use an analog-to-digital converter chip like the MCP3008 chip that sends the analog signals via SPI communication protocol that the Pi can read.

The gpiozero library provides an easy interface called MCP3008 that allows us to easily get the analog values using the value property. As an example, we’ve shown you how to use a potentiometer, but you can use the same methods for any analog sensor that outputs a maximum of 3.3V.

We hope you’ve found this tutorial useful. If you want to learn more about the basics of controlling the Raspberry Pi GPIOs using Python programming language, take a look at our Raspberry Pi tutorials:

You can check all our Raspberry Pi projects on the following link:



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.