Get your Pi to read analog data

SPI with Python

For the programming part, you'll be using Python. Install the spidev module to proceed:

sudo pip install spidev --upgrade

The --upgrade option is just in case you already have spidev installed, but want to upgrade to the latest stable version anyway.

Thanks to the spidev module, programming for the 3202 is very straightforward. Look at Listing 2 for an example of a boilerplate program that reads from the ADC and prints out the values of the potentiometer to the command line. (All due thanks to Ethan Dicks' work which I have blatantly used as "inspiration" for this program [4].)

Listing 2

01 import spidev
03 def bitstring(n):
04    s = bin(n)[2:]
05    return ,0'*(8-len(s)) + s
07 def read(spi_channel=0):
08    conn = spidev.SpiDev(0, spi_channel)
09    reply_bytes = conn.xfer2([128, 0])
10    reply_bitstring = ,'.join(bitstring(n) for n in reply_bytes)
11    return int(reply_bitstring, 2)/2047.0
13 if __name__ == ,__main__':
14    print read()

Line 1 imports in the spidev module, and lines 13 and 14 make up the main function of the program, obviously.

The read() function (lines 7 to 11) is where things get interesting. On line 8 you create an SpiDev() object [5]. The initialization module takes two parameters: the 0 tells the Pi that this object is going to be associated with SPI device 0, i.e. the device connected to pin 24/CE0. The second parameter tells the device, the 3202, to listen on channel 0, i.e. port 2/CH0 on the 3202. Examine Figures 2 and 3 again if you are getting confused.

The spidev xfer2() function (line 9) carries out a complete transaction between the Pi and the 3202. "Complete", in this context, means it sends out a petition for data in two bytes, and returns the reply. You send it a python list of values containing as many bytes as you want back. The 3202 can deliver 12 bits of information, although bit 12 is always 0 (NULL). As such, you get up to 11 bits of useful data back. This means that means that, once converted, you get a value between 0 and 2047. As a byte is only 8 bits long, you need to send two bytes to the 3202, to get enough bits back.

You can see what the two bytes sent to the 3202 look like by adding the line

print reply_bytes

after line 9. Note the line should start with a tab.

If you run the modified program, you should get something like what is shown in Listing 3.

Listing 3

Output from (modified)

pi@raspberrypi:~/ADC $ python
[3, 75]

The first line from the output shows the two bytes (in the shape of a Python list) the 3202 sends back. The second line shows the value converted to one single decimal number.

This is, by the way, what you do on line 10: You iterate over the two values in reply_bytes, sending each off to the bitstring() function. bitstring() converts the numbers to a binary string of 0s and 1s and chops of the first two characters (line 4) – Python indicates that a number is binary by preceding it with 0b. It then stuffs the string with 0s to fill the 8 bits that it takes to make up one full byte, then sends it back to read().

Still on line 10, both strings of bits get concatenated together.

On line 11, reply_bitstring, which now contains both bytes concatenated as a binary string, gets converted to decimal, and sent back to the main function for printing. Figure 5 shows the process of converting the two bits into a single decimal number.

Figure 5: How to convert two bytes into a decimal number.

Now's the moment to twiddle your potentiometer's knob and marvel at the fact that the Pi can now understand analog inputs.

Analog Epilogue

So what can you do with this? Pong, obviously. The most common version of Pong played on a Raspberry Pi uses a mouse, which is for barbarians. You need a dial to play this classic properly, which is where a potentiometer comes in handy.

Also, by default the Pi can read from two SPI slaves (read "two 3202 ADC devices") at the same time. Each 3202 has two channels, so, theoretically, you could read from four analog sensors at once. This gives you enough to read from a basic temperature sensor, a wind speed sensor, a UV sensor, and a humidity sensor. That's nearly a whole weather station.

Whatever you do, using an ADC opens the Pi to a whole new range of sensing. Enjoy sniffing the analog world!

Buy this article as PDF

Express-Checkout as PDF

Pages: 5

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content