Question 12.4: You want to measure an analog voltage....

You want to measure an analog voltage.

Step-by-Step
The 'Blue Check Mark' means that this solution was answered by an expert.
Learn more on how do we answer questions.

The Raspberry Pi GPIO connector has only digital inputs. If you wish to measure a voltage, you need to use a separate analog-to-digital converter (ADC).

Use the MCP3008 eight-channel ADC chip. This chip actually has eight analog inputs, so you can connect up to eight sensors to one of these and interface to the chip using the Raspberry Pi SPI interface.

To make this recipe, you will need:

• Breadboard and jumper wires (see “Prototyping Equipment” on page 380)

• MCP3008 eight-channel ADC IC (see “Integrated Circuits” on page 381)

• 10kΩ trimpot (see “Resistors and Capacitors” on page 380)

Figure 12-9 shows the breadboard layout for using this chip. Make sure that you get the chip the right way around. The little notch in the package should be toward the top of the breadboard.

The variable resistor has one end connected to 3.3V and the other to ground, which allows the middle connection to be set to any voltage between 0 and 3.3V.

Before trying the program, make sure you have SPI enabled and the SPI Python library installed (Recipe 8.6).

Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of http://www.raspberrypicookbook.com, where it is called adc_test.py.

import spidev, time
spi = spidev.SpiDev()
spi.open(0, 0)
def analog_read(channel):
r = spi.xfer2([1, (8 + channel) << 4, 0])
adc_out = ((r[1]&3) << 8) + r[2]
return adc_out
while True:
reading = analog_read(0)
voltage = reading * 3.3 / 1024
print(“Reading=%d\tVoltage=%f” % (reading, voltage))
time.sleep(1)

The interesting part of the program is contained in the analog_read function. This takes a parameter that should be between 0 and 7 and specifies which of the eight analog inputs down the lefthand side of the chip should be read.

The bit manipulation sets up a request for the appropriate channel and then sends the bits to the MCP3008, which reads the resultant data:

$ sudo python adc_test.py
Reading=0 Voltage=0.000000
Reading=126 Voltage=0.406055
Reading=221 Voltage=0.712207
Reading=305 Voltage=0.982910
Reading=431 Voltage=1.388965
Reading=527 Voltage=1.698340
Reading=724 Voltage=2.333203
Reading=927 Voltage=2.987402
Reading=10 Voltage=3.296777
Reading=1020 Voltage=3.287109
Reading=1022 Voltage=3.293555

Discussion

The MCP3008 has 10-bit ADCs, so when you take a reading, it gives you a number between 0 and 1023. The test program converts this into a voltage reading by multiplying the reading by the voltage range (3.3V) and then dividing it by 1,024.

You can combine any of the following recipes that use the MCP3008 to allow readings to be taken from up to eight sensors.

You can also use resistive sensors with the MCP3008 by combining them with a fixed-value resistor and arranging them as a voltage divider (see Recipe 12.6 and Figure 12-11).

See Also

If you’re just interested in detecting the turning of a knob, you can use a rotary encoder instead of a pot (Recipe 11.7).

You can also detect the position of a pot without the use of an ADC chip using the step response method (Recipe 12.1).

Check out the datasheet for the MCP3008.

Table A-3. Prototyping equipment
Description Suppliers
M-M jumper wires SparkFun: PRT-08431, Adafruit: 759
M-F jumper wires SparkFun: PRT-09140, Adafruit: 825
F-F jumper wires SparkFun: PRT-08430, Adafruit: 794
Half-sized breadboard SparkFun: PRT-09567 Adafruit: 64
Pi Cobbler Adafruit: 1105
Table A-6. Integrated circuits
7805 voltage regulator SparkFun: COM-00107
L293D motor driver SparkFun: COM-00315, Adafruit: 807
ULN2803 Darlington driver IC SparkFun: COM-00312, Adafruit: 970
DS18B20 temperature sensor SparkFun: SEN-00245, Adafruit: 374
MCP3008 eight-channel ADC IC Adafruit: 856
TMP36 temperature sensor SparkFun: SEN-10988, Adafruit: 165
Table A-4. Resistors and capacitors
270Ω 0.25W resistor Mouser: 293-270-RC
470Ω 0.25W resistor Mouser: 293-470-RC
1kΩ 0.25W resistor Mouser: 293-1k-RC
3.3kΩ 0.25W resistor Mouser: 293-3.3k-RC
4.7kΩ 0.25W resistor Mouser: 293-4.7k-RC
10 kΩ trimpot Adafruit: 356, SparkFun: COM-09806, Mouser: 652-3362F-1-103LF
Photoresistor Adafruit: 161, SparkFun: SEN-09088
220nF capacitor MCM: 31-0610, Mouser: 80-C322C224M5U5HA
12.9
12.11

Related Answered Questions

Question: 12.11

Verified Answer:

Use the Tkinter library to open a window and write...
Question: 12.10

Verified Answer:

Use a low cost SR-04 rangefinder. These devices ne...
Question: 12.12

Verified Answer:

Write a Python program that writes the data to a f...
Question: 12.9

Verified Answer:

Use the DS18B20 digital temperature sensor. This d...
Question: 12.7

Verified Answer:

Use an MCP3008 ADC chip. However, unless you need ...
Question: 12.8

Verified Answer:

Use an analog accelerometer with a MCP3008 ADC chi...
Question: 12.6

Verified Answer:

Use a potential divider with one fixed resistor an...
Question: 12.2

Verified Answer:

Use the same basic recipe and code as Recipe 12.1,...
Question: 12.3

Verified Answer:

Low-cost resistive gas sensors are available that ...
Question: 12.5

Verified Answer:

Use a pair of resistors to act as a voltage divide...