HomeTutorials › Getting Started With The Raspberry Pi 16 Channel ADC HAT

Getting Started With The Raspberry Pi 16 Channel ADC HAT

In this tutorial we are going to go over the basics of using our Raspberry Pi 16 Channel Analog Input HAT. This board is designed to give the Raspberry Pi analog read capabilities similar to those found on the Arduino. In this case, the board can provide 16 channels at 10 bit resolution through two MCP3008 Analog to Digital Converters (ADCs). We will start with the very basics including soldering the header, configuring the Raspberry Pi’s operating system, how to connect different analog sensors to the board, the pull up/pull down resistor options, and how to read each channel using Python.


Please Note: This tutorial uses an outdated library and will no longer work with current version of Raspbian / Raspberry Pi OS. We have released a new tutorial with up to date instructions and examples. We will keep the tutorial up for reference.

About The Board:
The 16 Channel Analog Input HAT was designed right here at BC Robotics – it isn’t the most complicated board out there – just a few components and two MCP3008 ADCs. It is common to see the MCP3008 chipset used with the Raspberry Pi – in this case we have just made it into a finished board – something a little more suited to permanent applications. The board uses both SPI channels on the Pi (one per MCP3008 chip) and features 10 bit resolution, 0 – 3.3V range, and integrated resistor pads for creating voltage dividers with basic resistive sensors.

The Parts Needed:


This tutorial will be requiring a few common parts:

Step 1 – A Quick Overview


There isn’t much in the way of assembly required with this board – just select your headers for the Pi and the ADC inputs and solder them in place. We will be using the Raspberry Pi GPIO Header and regular 40 pin breakaway headers, but feel free to go a different way. Once we have the headers soldered in, we will install a Python library to simplify getting the data from each of the MCP3008 ADCs. To finish off: we will write a bit of basic coded to read the sensors and hook up a few examples on a breadboard.

Step 2 – Soldering the header


First we need to solder the header that allows this board to plug into the Raspberry Pi. We recommend using this header, but any compatible Raspberry PI GPIO header will work. If you haven’t soldered before, or want a quick refresher course, have a look at this awesome comic: Soldering Is Easy! https://mightyohm.com/…/FullSolderComic_EN.pdf

Start by Tacking two opposite corners of the connector in place and checking the connector alignment. We do this to ensure the connector is sitting correctly before soldering all 40 pins; once these have all been soldered, it is very difficult to adjust the alignment.

Step 3 – Soldering the header (continued)


Once the connector is aligned to the board, and you are happy with the alignment, solder the remaining pins. It should look something like the header in the attached photo when you are finished!

Step 4 – Soldering the ACD inputs


Next, we are going to solder in the headers for each of the ADC inputs. The holes are 2.54mm (O.100″) pitch and will fit any standard breakaway headers. Alternatively, if you know this board is going to be stacked with another board on top (or clearance is an issue), these 4 x 3 Right Angle headers will also work. For this example, we are using standard 40 pin breakaway headers.
Just like the other header, tack one pin in place for each piece, check the alignment, and solder the remaining pins.

Step 5 – Double Check Your Work!


Before we power anything up, it is always a good idea to go through and make sure there are no issues with the work that has been done. Make sure all the solder joints are clean, with no un-intended bridging. Once the board has been checked over, install it on top of the Pi.

Step 6 – Getting Ready To Power Up Your Pi

Before we get the Pi powered up, you should have a microSD card pre-installed with Raspbian. We are using the installation image dated June 27, 2018. Using a different version than this *could* require additional steps during the installation process – so for this reason we recommend using the exact version we are. At the time of writing this tutorial, this is the most current version available from the Raspberry Pi Foundation and it can be found here

Once this has been completed, we are going to insert the microSD card into the Pi. Your keyboard, mouse and monitor should also be connected at this time. Power up the Pi by plugging in the Power Supply. Once the Pi has done its initial boot of the operating system you should arrive at a desktop. A dialogue should appear for initial configuration – we will take care of this in the next step.

Step 7 – OS Configuration

As of this version of Raspbian, most initial setup can be done by following the dialogue that pops up on first boot up. However, we do need to set up a few additional things once this is initial configuration is completed. Follow through the initial setup, if prompted to reboot – go ahead and do that as well.

Once all of that has been completed, we can go ahead and configure a few more things. Click the Raspberry Logo in the top left corner, scroll down to Preferences, and select “Raspberry Pi Configuration”.

On the first tab you can change your overscan settings. If you are using a computer monitor, you may want to disable the overscan setting to remove the black bars on the sides of the screen.

On the second tab we are going to want to enable the SPI interface. This is the interface our ADCs are connected to.

If prompted to reboot, click yes. Once the Pi boots back up we can proceed.

Step 8 – Internet Connectivity


Before we can install the library and set up the ADCs, we need internet connectivity. If you are using WiFi, this was probably already set up during the initial configuration. If it isn’t working, or you skipped that step, it can be accessed by clicking the connectivity logo (located beside the Volume control in the top right corner of the screen).

Ethernet is as simple as plugging it into the Pi – if you are planning to use ethernet, go ahead and plug this in if you haven’t already.

Step 9 – Terminal


Now that all of the basic configuration is done, we can get on with installing the software libraries needed to read each of the sensors. These libraries of code are going to take a lot of the hard work out of reading the sensors. We are going to install these using the “Terminal” , in the bar at the top of the screen, click the black square logo, and this window should pop up:

///////////////////Right Image//////////////////////

Step 10 – Adafruit MCP3008 library


To read each of the MCP3008 ADC chips we will be using a Python library Adafruit has kindly put together for the MCP3008. The library will be installed by typing a series of commands into the terminal window we just opened up.

Run each of these commands (in order!) by typing them in and hitting enter:

sudo apt-get update

sudo apt-get install build-essential python-dev python-smbus git

cd ~

git clone https://github.com/adafruit/Adafruit_Python_MCP3008.git

cd Adafruit_Python_MCP3008

sudo python setup.py install

Step 11 – Adafruit MCP3008 library


Next, we will want to test out the MCP3008 Library to make sure everything is working properly. Since there are several ways to connect the MCP3008, we will need to configure the test file (included in the Adafruit library we just installed) by running the following commands in the Terminal:

cd ~/Adafruit_Python_MCP3008/examples

nano simpletest.py

We are using hardware SPI so we are going to comment out lines 13 - 17 using the “#” and uncomment lines 20-22 by removing the “#”. Your end result should look like the attached image.

Step 12 – Save for now


This test file by Adafruit is designed to read a single chip at address 0. We will try reading from this first chip for now; save this file by pressing “Ctrl + X” and then “Y” to accept changes.

Step 13 – Test run the first chip


Now that the file is saved, try running the following command:

sudo python simpletest.py

A continuous stream of numbers should spit out – each column representing a reading from one of the 8 inputs from the first chip. Press "Ctrl + C" to stop the program. If you wish to test the second chip; follow the last two steps again but modify the chip address to 0,1 in the test file.

Step 14 – Load up Python

Ok so both sensors should be working – time to write our own code. We want to program in Python 2.7 so type the following command in the terminal and hit enter:


A new window should have opened for the Python 2.7 Shell. We are now done with the terminal window so it can be minimized or moved out of the way (but don’t close it!).


Step 15 – Write some of our own code


In the Python Shell window we just opened, click “File” and “New File” to start a new Python file. This will open another window that we will write all of our code in. We aren’t going to write anything too complicated – just a basic bit of code to read a channel from either of the ADCs we have on board. This code can then be used going forwards to work this ADC board into your project!

Step 16 – Starting The Code

Before we can read either of the ADCs, we will need to create the basic framework of the program. This means we need to import the time library, create our loop, and set the interval we want to pause the code each time the loop has completed. For those unfamiliar with Python, note that the white spaces (tabs and spaces) are very important in this language so be sure to format exactly as shown in the example.

import time

interval = 1  #How long we want to wait between loops (seconds)

while True:


Libraries are added to the project using the import command. On the first line we are importing the time library. On line 3 we define a variable to store the length of time in seconds that we want to sleep the program during each loop of the code. Next, we want to create the loop itself - in Python this can be done in a variety of ways; "While true:" works well. Note that when you press "Enter" the next line becomes indented. Finally, on line 8 we "sleep" or pause our program using the variable we set above. The end result is a program that starts, and then runs whatever code we stick in the loop once a second.

Note: Because we are going to be adding code over the next few steps, each new line we add will be highlighted in the example code and the line number will correspond to notes below the code.

Step 17 – Import the libraries

We are going to import the Adafruit MCP3008 library and the Adafruit GPIO library we installed earlier to use in this program. This is done the same way as we imported the time library.

import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008

interval = 1 # How long we want to wait between loops (seconds)

while True:
  • (2) import the SPI portion of the Adafruit GPIO library
  • (3) import the Adafruit MCP3008 library

Step 18 – Create the MCP3008 Objects

Next, we are going to create two instances of the mcp object (one for each of our chips) and assign them to their correct addresses. mcp0 will refer to the first chip while mcp1 will refer to the second chip.

import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008

interval = 1 # How long we want to wait between loops (seconds)

#Address for the first MCP3008 (0, 0)
mcp0 = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(0, 0))

#Address for the first MCP3008 (0, 1)
mcp1 = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(0, 1))

while True:
  • (8) mcp0 refers to the first chip, it is located at SPI address 0,0
  • (11) mcp1 refers to the second chip, it is located at SPI address 0,1

Step 19 – Read The Channels

Now that we have created each of the MCP3008s, the library will be able to read any channel we wish by calling very simple code. The addresses of each input are printed on the board; so if you have connected a sensor to input 1-5, you would use mcp1 and read channel 5. Connected to input 0-3, you would use mcp0 and read channel 3.

import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008

interval = 1 # How long we want to wait between loops (seconds)

#Address for the first MCP3008 (0, 0)
mcp0 = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(0, 0))

#Address for the first MCP3008 (0, 1)
mcp1 = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(0, 1))

while True:

    print mcp0.read_adc(3)
    print mcp1.read_adc(5)
  • (15) To grab data from the first chip we would use mcp0 and we are reading channel 3 (0-7 are valid inputs)
  • (16) To grab data from the second chip we would use mcp1 and we are reading channel 5 (0-7 are valid inputs)

Step 20 – Hook up some sensors

Now that we have some basic code to read sensors, let's hook up a few and get a reading. We don't want to be messing around with electrical connections while the Pi is on so save you work, close everything, and shutdown. Once the Pi is shutdown, grab your breadboard and set up a few sensors in the breadboard. We will go through the proper connection of a basic resistive sensor (normally used with a voltage divider circuit) and an analog output sensor with a specific analog output pin.

In this case we are going to use a CDS photocell and a Potentiometer. With the CDS photocell we will also need a 10K Ohm resistor to create the voltage divider. Connect each sensor up as shown:

Wiring for the Potentiometer:
Red is 3.3V Power (To "+")
Blue is the analog signal to the board (To: "SIG")
Black is the Ground (To "GND")

Wiring for the CDS Photocell:
Red is 3.3V Power (To: "+")
Green is the analog signal to the board (To: "SIG")
Black is the Ground (To "GND")
10K Resistor between Green and Black (On Breadboard)

Double check all of your connections, and once satisfied they are correct, boot up the Pi. Load up your Python program again and try it out. You should see the sensor readings correspond to your analog sensors!

Step 21 – Using the onboard jumpers

Finally, we are going to take a look at what all these onboard jumpers and solder pads are for. As you may have noticed in Step 20, we have to add a resistor along with the CDS photocell to get a useable reading. This is the same for all basic resistive sensors. On this board we have added solder pads and jumpers that allow for this resistor to be placed and configured on the HAT if desired. In the case of our CDS Photocell using a pull-down resistor, the configuration shown in the attached image would be correct:

1. Close the "EN" jumper to enable the onboard resistor circuit
2. Solder the required resistor to this pad - these are 1206 SMD Resistor Pads - they can be soldered with a conventional iron without too much difficulty.
3. Select whether this should connect to power or ground (pull up or pull down) by soldering this jumper to the correct position.

And with that, no need for the resistor in the breadboard!


Have A Question?
If you have any questions, or need further clarification please post in the comments section below; this way future users of this tutorial can see the questions and answers!

Parts Used In This Tutorial:


  1. mike87
  2. John
      • Rob

Leave a Reply