Tuesday, December 24, 2013

Analog Sensors without Analog Inputs on the Raspberry Pi

The Raspberry Pi does not have any analog inputs, but that does not mean that you can't use some types of analog sensors. Using a couple of resistors and a capacitor, you can use a "step response" method to measure resistance. Which is just great if you are using a pot, photoresistor or thermistor.
The Recipe that follows is taken from my new book "The Raspberry Pi Cookbook". This way of using sensors was inspired by this work from Adafruit.

To make this recipe, you will need:
• Breadboard and jumper wires 
• 10kΩ trimpot 
• Two 1kΩ resistors 
• 220 nF capacitor 

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
the Raspberry Pi Cookbook website, where it is called pot_step.py.

import RPi.GPIO as GPIO
import time

a_pin = 18
b_pin = 23

def discharge():
  GPIO.setup(a_pin, GPIO.IN)
  GPIO.setup(b_pin, GPIO.OUT)
  GPIO.output(b_pin, False)

def charge_time():
  GPIO.setup(b_pin, GPIO.IN)
  GPIO.setup(a_pin, GPIO.OUT)
  count = 0
  GPIO.output(a_pin, True)
  while not GPIO.input(b_pin):
  count = count + 1
  return count

def analog_read():
  return charge_time()
  while True:

When you run the program, you should see some output like this:

$ sudo python pot_step.py

The reading will vary between about 10 and about 170 as you rotate the knob of the

To explain how this program works, I first need to explain how the step response technique
can be used to measure the resistance of the variable resistor.

This way of doing things is called step response because it works by seeing how the circuit
responds from the step change when an output is switched from low to high.

You can think of a capacitor as a tank of electricity, and as it fills with charge, the voltage
across it increases. You can’t measure that voltage directly, because the Raspberry Pi
doesn’t have an ADC converter. However, you can time how long it takes for the capacitor
to fill with charge to the extent that it gets above the 1.65V or so that constitutes
a high digital input. The speed at which the capacitor fills with charge depends on the
value of the variable resistor (Rt). The lower the resistance, the faster the capacitor fills
with charge and the voltage rises.

To be able to get a good reading, you must also be able to empty the capacitor each time
before you take a reading. Connection A is used to charge the capacitor through Rc and Rt, and connection B is used to discharge (empty) the capacitor through
Rd. The resistors Rc and Rd are used to make sure that there is no way too much current
can flow as the capacitor is charged and discharged.

The steps involved in taking a reading are first to discharge the capacitor through Rd
and then to let it charge through Rc and Rt.

To discharge it, connection A (GPIO 18) is set to be an input, effectively disconnecting
Rc and Rt from the circuit. Connection B (GPIO 23) is then set to be an output and low.
This is held there for 5 milliseconds to empty the capacitor.

Now that the capacitor is empty, you can start to allow charge to flow into it by setting
connection B to be an input (effectively disconnecting it) and then enabling connection
A to be a high output at 3.3V. Capacitor C will now begin to charge through Rc and Rt.
The while loop will then simply count as fast as possible until the voltage at connection
B switches from being low to high at about 1.65V. At that point, the counting stops and the count value is returned.

The figure below shows how a resistor and capacitor in this kind of arrangement charge and
discharge as the voltage is toggled between high and low.

You can see that the voltage at the capacitor increases rapidly at first but then tails off
as the capacitor becomes full. Fortunately, you are interested in the area of the curve up
until the capacitor reaches about 1.65V, which is a fairly straight line, meaning that the
time taken for the voltage across the capacitor to rise to this point is roughly proportional
to the resistance of Rt and hence the position of the knob.

This approach is not hugely accurate, but it is very low cost and easy to use.

About the Author
These are my books. Click on the image below to find out more about them.


leszcz said...


leszcz said...


One of Many said...

This is great! I kept searching online for a way to read soil moisture hygrometer that I bought off eBay. It comes with an analogue and digital output, but the digital output only does 1 or 0 and nothing in between regarding the moisture percentage. All the online searching was recommending going down the route of an analogue to digital converter chip that I find more cumbersome because I want to have about 10 sensors. Now, I think it could work with this technique where I don't use the provided outputs at all and connect directly to the electrodes that I stick in the ground.