Analog Inputs for Raspberry Pi Using the MCP3008 (2024)

Overview

Save Subscribe

New Subscription

Please sign in to subscribe to this guide.

You will be redirected back to this guide once you sign in, and can then subscribe to this guide.

Teaching the Raspberry Pi how to read analog inputs is easier than you think! The Pi does not include a hardware analog-to-digital converter, but an external ADC (such as the MCP3008) can be used, along with some SPI code in Python to read external analog devices.

Here is a short list of some analog inputs that could be used with this setup:

  • potentiometer
  • photocell
  • force sensitive resistor (FSR)
  • temperature sensor
  • 2-axis joystick

This guide uses apotentiometer to control the volume of an audio tone, but the code can be used as the basis for any kind of analog-input project.

Connecting the Cobbler to a MCP3008

  • MCP3008 DIP-package ADC converter chip
  • 10K trimer or panel mount potentiometer
  • Adafruit T-Cobbler Plus or for an older 26-pin Pi anAdafruit Pi Cobbler
  • Full-size breadboard
  • Breadboarding wires

And of course a working Raspberry Pi.

The Raspberry Pi computer does not have a way to read analog inputs. It's a digital-only computer. Compare this to the Arduino, AVR or PIC microcontrollers that often have 6 or more analog inputs! Analog inputs are handy because many sensors are analog outputs, so we need a way to make the Pi analog-friendly.

We'll do that by wiring up an MCP3008 chip to it. The MCP3008 acts like a "bridge" between digital and analog. It has 8 analog inputs and the Pi can query it using 4 digital pins. That makes it a perfect addition to the Pi for integrating simple sensors like photocells,FSRs orpotentiometers, thermistors, etc.!

Let's check the datasheet of the MCP3008 chip.On the first page in the lower right corner there's a pinout diagram showing the names of the pins:

In order to read analog data we need to use the following pins:

VDD(power) and DGND(digital ground) to power the MCP3008 chip. We also needfour "SPI" datapins:DOUT(Data Out from MCP3008),CLK(Clock pin),DIN(Data In from Raspberry Pi), and /CS(Chip Select). Finally of course, a source of analog data. We'll be usingthe basic10k trim pot.

The MCP3008 has a few more pins we need to connect:AGND(analog ground, used sometimes in precision circuitry, which this is not) connects toGND, andVREF(analog voltage reference, used for changing the "scale" - we want the full scale, so tie it to3.3V).

Below is a wiring diagram. Connect the 3.3V cobbler pin to the left + rail and the GND pin to the right - rail. Connect the following pins for the MCP chip

  • MCP3008 VDD -> 3.3V (red)
  • MCP3008 VREF -> 3.3V(red)
  • MCP3008 AGND -> GND(black)
  • MCP3008CLK -> SCLK (yellow)
  • MCP3008 DOUT -> MISO (purple)
  • MCP3008 DIN -> MOSI (white)
  • MCP3008 CS -> #22 (green)
  • MCP3008 DGND -> GND(black)

Next connect up the potentiometer.

  • Pin #1 (left) goes to 3.3v (red)
  • Pin #2 (middle) connects to MCP3008CH0(analog input #0) with a purple wire
  • Pin #3 (right) connects to GND (black)

Below we provide to wiring diagrams that will work with all versions of Raspberry Pi released so far (except the compute node which has no header). The first diagram is for the most recent Pi v3 and Pi Zero models which have a 40-pin GPIO header. The second is for the first two generations of Raspberry Pi which had a smaller 26-pin header. In both cases we are using the same GPIOs so the code will not be any different.

T-Cobbler Plus Wiring 40-Pin Pi (v3, Zero)

Pi Cobbler Wiring 26-Pin Pi (v1, v2)

Necessary Packages

Your Pi will need to be running the latest version of Raspbian. This tutorial was written using Raspbian Stretch (Nov. 2018). Checkout our guide for Preparing an SD Card for your Raspberry Pi if you have not done so already. After the installation is complete be sure and run the following commands to make sure your installation packages are up to date.

Download File

Copy Code

$ sudo apt-get update -y$ sudo apt-get upgrade -y

You will also need to enable SPI

pip3 is already installed with a full Raspbian installation, but the Raspbian Lite does not include pip3 so it needs to be installed as shown below. We will use pip3 to install the necessary CircuitPython libraries.

Download File

Copy Code

$ sudo apt-get install python3-pip

Download File

Copy Code

$ sudo pip3 install adafruit-blinka

Download File

Copy Code

$ sudo pip3 install adafruit-circuitpython-mcp3xxx

Python Script

The following code can be downloaded directly to your Raspberry Pi. It will read the trimpot value, translate the reading to a volume range and modify the OS output volume level on your Raspberry Pi.

The remap_range() method is being used to convert the 16-bit analog in range 0 - 65,535 to volume 0-100%.

Download Project Bundle

Copy Code

# SPDX-FileCopyrightText: 2019 Mikey Sklar for Adafruit Industries## SPDX-License-Identifier: MITimport osimport timeimport busioimport digitalioimport boardimport adafruit_mcp3xxx.mcp3008 as MCPfrom adafruit_mcp3xxx.analog_in import AnalogIn# create the spi busspi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)# create the cs (chip select)cs = digitalio.DigitalInOut(board.D22)# create the mcp objectmcp = MCP.MCP3008(spi, cs)# create an analog input channel on pin 0chan0 = AnalogIn(mcp, MCP.P0)print('Raw ADC Value: ', chan0.value)print('ADC Voltage: ' + str(chan0.voltage) + 'V')last_read = 0 # this keeps track of the last potentiometer valuetolerance = 250 # to keep from being jittery we'll only change # volume when the pot has moved a significant amount # on a 16-bit ADCdef remap_range(value, left_min, left_max, right_min, right_max): # this remaps a value from original (left) range to new (right) range # Figure out how 'wide' each range is left_span = left_max - left_min right_span = right_max - right_min # Convert the left range into a 0-1 range (int) valueScaled = int(value - left_min) / int(left_span) # Convert the 0-1 range into a value in the right range. return int(right_min + (valueScaled * right_span))while True: # we'll assume that the pot didn't move trim_pot_changed = False # read the analog pin trim_pot = chan0.value # how much has it changed since the last read? pot_adjust = abs(trim_pot - last_read) if pot_adjust > tolerance: trim_pot_changed = True if trim_pot_changed: # convert 16bit adc0 (0-65535) trim pot read into 0-100 volume level set_volume = remap_range(trim_pot, 0, 65535, 0, 100) # set OS volume playback volume print('Volume = {volume}%' .format(volume = set_volume)) set_vol_cmd = 'sudo amixer cset numid=1 -- {volume}% > /dev/null' \ .format(volume = set_volume) os.system(set_vol_cmd) # save the potentiometer reading for the next loop last_read = trim_pot # hang out and do nothing for a half second time.sleep(0.5)

Download the Code

Let's put this file right in your home directory for simplicity. The wget command makes things easy.

Download File

Copy Code

$ wget https://raw.githubusercontent.com/adafruit/Adafruit_Learning_System_Guides/master/Analog_Inputs_for_Raspberry_Pi_Using_the_MCP3008/code.py

Run It

The following command will start our volume control script. Adjusting the trimpot will printout the OS volume level on the screen.

Download File

Copy Code

$ sudo python3 ./code.py

Testing the Volume Control

Opening a second terminal on your Raspberry Pi we can run the "speaker-test" command and listen to the volume change as we turn the trimpot.

Download File

Copy Code

$ speaker-test -t sine -f 440

Controlling MP3 Volume

The mpg123 command can be used to play MP3 files on your Raspberry Pi. We can open an additional terminal and play MP3 files and adjust the volume with the trimpot we have wired up.

Download File

Copy Code

$ mpg123 <MP3 filename>

This guide was first published on Jul 29, 2012. It was lastupdated on Feb 26, 2024.

Related Guides

MCP3008 - 8-Channel 10-Bit ADC With SPI Interface

ByKattni Rembor

17

Beginner

CircuitPython Libraries on Linux and Google Coral

Bylady ada

4

Intermediate

Windows IoT Core Application Development: Headed Blinky

ByRick Lesniak

14

Beginner

CircuitPython Libraries on Linux and ODROID C2

ByM. LeBlanc-Williams

3

Intermediate

Basic Resistor Sensor Reading on Raspberry Pi

Bylady ada

19

Intermediate

Adding Basic Audio Ouput to Raspberry Pi Zero

Bylady ada

61

Beginner

Adafruit's Raspberry Pi Lesson 12. Sensing Movement

BySimon Monk

70

Beginner

Raspberry Pi E-mail Notifier Using LEDs

ByMichael Sklar

41

Intermediate

Playing sounds and using buttons with Raspberry Pi

ByMichael Sklar

59

Intermediate

Large Pi-based Thermometer and Clock

BySimon Monk

26

Intermediate

Your browser does not support the video tag. This links to the guide LoRa and LoRaWAN Radio for Raspberry Pi.

LoRa and LoRaWAN Radio for Raspberry Pi

ByBrent Rubell

47

Intermediate

Adafruit's Raspberry Pi Lesson 4. GPIO Setup

BySimon Monk

189

Beginner

Windows IoT Core Application Development: Headless...

ByRick Lesniak

9

Beginner

Adafruit's Raspberry Pi Lesson 11. DS18B20...

BySimon Monk

86

Beginner

Adafruit's Raspberry Pi Lesson 13. Power Control

BySimon Monk

56

Beginner

Your browser does not support the video tag. This links to the guide IoT Temperature Logger with Analog Devices ADT7410, Raspberry Pi, and Adafruit IO.

IoT Temperature Logger with Analog Devices ADT7410,...

ByBrent Rubell

17

Beginner

Analog Inputs for Raspberry Pi Using the MCP3008 (2024)
Top Articles
Latest Posts
Article information

Author: Horacio Brakus JD

Last Updated:

Views: 6105

Rating: 4 / 5 (71 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Horacio Brakus JD

Birthday: 1999-08-21

Address: Apt. 524 43384 Minnie Prairie, South Edda, MA 62804

Phone: +5931039998219

Job: Sales Strategist

Hobby: Sculling, Kitesurfing, Orienteering, Painting, Computer programming, Creative writing, Scuba diving

Introduction: My name is Horacio Brakus JD, I am a lively, splendid, jolly, vivacious, vast, cheerful, agreeable person who loves writing and wants to share my knowledge and understanding with you.