Working with analog sensors in the Raspberry Pi
Published by António Lopes on March 5, 2013
Categories: DIY, Geek, Technology

As interesting as the Raspberry Pi may be, it does not have a way to read analog inputs directly, which makes it difficult to use in some DIY projects. Luckily, working with an ADC on the RPi is really simple and easy thanks to this lesson from Adafruit.

In that tutorial, you’ll learn how to setup the MCP3008 ADC with the RPi by using SPI communication to use a potentiometer to adjust the volume of an MP3 that is currently playing. I followed the tutorial and it worked nicely but I had other ideas for this ADC.

For a long time now, I wanted to build a home-monitoring device with a bunch of analog sensors and the RPi, combined with this ADC, seems to be just the right computer for it. So, this required a small test and I decided to use two simple analog sensors to measure temperature (TMP36) and humidity (HIH4030). I followed the ADC connection diagram in the Adafruit tutorial and then connected the TMP36 and the HIH4030 to analog channels 0 and 1, respectively.

The following is the python code (adapted from the Adafruit tutorial code) that checks the analog sensors every second and calculates the right values for temperature and humidity:

#!/usr/bin/env python
import time
import os
import RPi.GPIO as GPIO


# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
        if ( (adcnum > 7) or (adcnum < 0) ):
                return -1
        GPIO.output(cspin, True)

        GPIO.output(clockpin, False)  # start clock low
        GPIO.output(cspin, False)     # bring CS low

        commandout = adcnum
        commandout |= 0x18  # start bit + single-ended bit
        commandout <<= 3    # we only need to send 5 bits here
        for i in range(5):
                if (commandout & 0x80):
                        GPIO.output(mosipin, True)
                        GPIO.output(mosipin, False)
                commandout <<= 1
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)

        adcout = 0
        # read in one empty bit, one null bit and 10 ADC bits
        for i in range(12):
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)
                adcout <<= 1
                if (GPIO.input(misopin)):
                        adcout |= 0x1

        GPIO.output(cspin, True)

        adcout >>= 1       # first bit is 'null' so drop it
        return adcout

# change these as desired - they're the pins connected from the
# SPI port on the ADC to the Cobbler
SPICS = 25

# set up the SPI interface pins

# temperature sensor (TMP36) connected to adc #0
temperature_adc = 0;
humidity_adc = 1;

while True:
        # read the analog pin
        analog_temp_value = readadc(temperature_adc, SPICLK, SPIMOSI, SPIMISO, SPICS)
        analog_hum_value = readadc(humidity_adc, SPICLK, SPIMOSI, SPIMISO, SPICS)

        temp_voltage = (analog_temp_value * 3.3 / 1024.0) * 1000.0;
        temp = (temp_voltage - 500)/10;

        humidity = ((analog_hum_value * 12) / 75) - 26;

        if DEBUG:
                print "Temperature analog value: ", analog_temp_value
                print "Temperature voltage: ", temp_voltage
                print "Humidity analog value: ", analog_hum_value

        print "Temperature: ", temp
        print "Humidity: ", humidity
        print ""

        # hang out and do nothing for a second

Running this python script (it must be run as root, otherwise you won’t get access to the GPIO) should output something like:

Temperature:  21.865234375
Humidity:  72

Temperature:  22.1875
Humidity:  73

In case you’re wondering where those calculations for temperature and humidity came from: for temperature check this post, for humidity check this post.

UPDATE: CodingCat has left a very valuable set of comments regarding the process of obtaining exact values from the humidity sensor. Check the comments below.

I’d like to thank Filipe Valpereiro from Inmotion for providing the MCP3008 ADC for me to test. If you’re a “do-it-yourself-er” in Portugal, check their website for all kinds of components.


  1. OrangeTux says:

    Line 23 contains an error. & should be replaced by &. & is the HTML representation of the ampersand.

  2. codingCat says:

    Brilliant. This is exactly what I have been looking for.

    Reading the tech specs for the humidity sensor it states that the value has to be adjusted for temperature. Have you taken that into account somewhere that I missed?

    • No, the processing of the values in this example is very basic. My concern wasn’t for the exact reading of the sensors, but only their connection to the Raspberry Pi.
      So, further adjustments/processing may be required to get the exact values.

      • codingCat says:

        Part 2:

        Thank you for posting high res pictures of your set up. I zoomed my browser way in and managed to pick up that you are indeed running everything off of the 3v line form the RPi. A little more research showed that the humidity sensor is tolerant of this (though it may lower its accuracy). Once I rewired the sensor it started showing values in the 400’s which converts to about 45% humidity which is what my AC is reporting.

        I did a little digging and the tech sheet for the HIH4030 provides this equation for conversion to true humidity:

        True RH = (Sensor RH)/(1.0546 – 0.00216T), T in ºC

        Converted for you test code above it comes out as:

        trueHumidity = humidity / (1.0546 – (0.00216 * temp))

        Now for a little more digging to see if I can switch the power in the other direction and run the ADC from the 5v line of the RPi.

        Thanks again.

        • codingCat says:

          The answer is yes. The ADC will tolerate up to 7v. Everything is now tied to the 5v line of the RPi. And I am getting consistent results, including a spike when I exhale on the sensor.

          Thanks again. 🙂

      • codingCat says:

        Something isn’t quite right with my values. What type of numbers are you getting in from the sensor? Mine are in the 900 – 940 range. When I plug that into the equation I get a number around 120.

        Perhaps I have it wired wrong. It is hard to tell from your photo’s, when you hooked up the ADC and the humidity sensors how did you power them? I have the ADC powered with the three volt line, the sensor powered with the five volt line, Vref tied to the five volt line and everything grounding to pin 6.

        Does that mach your set up?

  3. […] the work with analog sensors on the Raspberry Pi, I decided to test the PulseSensor‘s behavior in building a pulse sensing application. […]

Comment this post

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.