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
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
IoT Temperature Logger with Analog Devices ADT7410,...
ByBrent Rubell
17
Beginner