I am going to share a trade secret with you today. It’s a common practice (or at least it was) but seems to have been lost to many judging by the questions I have been asked recently. Did you know you could read an analog signal even if you only have digital inputs on your microcontroller or single board computer? Or what if you ran out of analog pins on your Arduino? You can, and all you need is a simple resistor and capacitor.
Welcome to the magical world of RC timing circuits! The secret lies in the fact that it takes a finite amount of time for a capacitor to charge and discharge, and that time is based on the voltage applied, the resistor and capacitor values. In short, by measuring how long it takes a capacitor to discharge we can calculate the analog voltage driving the RC circuit connected to our microcontroller pin. Mathematically, the time it takes to fully charge or discharge a capacitor is approximated as 5T where T (pronounced 'Tau') is the timing constant. For an RC circuit the timing constant is R x C; therefore the time to charge/discharge the capacitor is approximated as 5 time constants of 5(R x C). Keep this in mind for later.
Let’s show the hardware setup. Again, all we need is a capacitor and a resistor. Since we are normally dealing with 5V or less for our signals we can utilize a 1-uF capacitor. The resistor is typically the variable device, that is to say the resistance will vary as a result of a change in the physical stimuli applied. These can include devices like Force Sensitive Resistors (FSRs) and photocells. A small fixed resistor in series with the variable resistance device helps to ensure there is always some amount of resistance between Vcc and your devices I/O pin.
Now in our code we have to run through a few different steps to handle the discharging and charging of our RC circuit. In general, the pseudo code process is as follows:
• Set the I/O pin as an output and set it low in order to discharge the capacitors. Don't forget the calculation regarding charging/discharge a capacitor. Allow enough time to discharge the capacitor as given by the equation 5(R x C). I told you we'd come back to this!
• Change the pin to an input and enter a loop that increments a counter so long as the input reads as low.
• Once the pin read high, exit the loop and print out the value to the serial port if so desired. Or have the circuit alter and output device in response to the input changes.
What will you do with this new knowledge? Any embedded projects you've worked on that could benefit from being able to handle additional analog input? Let us know down below in the comments.
Michael Parks, P.E. is the co-founder of Green Shoe Garage, a custom electronics design studio and embedded security research firm located in Western Maryland. He produces the Gears of Resistance Podcast to help raise public awareness of technical and scientific matters. Michael is also a licensed Professional Engineer in the state of Maryland and holds a Master’s degree in systems engineering from Johns Hopkins University.