Measuring analog values on a Raspberry Pi without ADC

Contrary to the ESP8266 or the Arduino, the Raspberry Pi has no analog ports. In order to measure analog values, you can add an ADC. These usually are driven by the I2C port or by SPI.

If however  you only need to measure one analog value with a variable resistor sensor, there is a quick and easy way to do that without adding an ADC converter on your I2C. But, it will still cost you two pins.

If you take a look at the picture, the working appears pretty simple:
The Charge pin, when made HIGH starts charging the 100nF capacitor through the NTC. When at a certain time the voltage over the 100nF capacitor is high enough to be seen as a HIGH by the Raspberry, the ‘measure pin’ gets set from LOW (in fact from Zero) to HIGH. The time it takes from the start of the charge till the measure pin goes to HIGH is then a time value that is a measure for the value of the NTC. It is only influenced by the  value of the NTC. When we feed a Raspberry with 3.3 Volt, a HIGH on a pin means a minimum of 1.6 Volt, so in fact we are measuring the time it takes to charge a capacitor from zero to 1.6 Volt. The 1k resistor is just a safety precaution to prevent too much current coming from the capacitor when it is discharged.

It is paramount that the measurement is always taken from the same starting position, meaning an empty capacitor. The measurement procedure thus looks like this:

Empty capacitor
Start charging capacitor
Start timer
Wait till capacitor is HIGH
Read timer

to decharge the capacitor we can use the measuring pin.

Fortunately very often someone already has written a code that can be used and in this case it was SimonMonk

import RPi.GPIO as GPIO
import time

# declare GPIO mode
GPIO.setmode(GPIO.BCM)

# define GPIO pins with variables charge_pin and measure_pin
# 18=chargepin 23=measure
charge_pin=18 
measure_pin = 

# discharge the capacitor
def discharge():
    GPIO.setup(charge_pin, GPIO.IN) #stop charging
    GPIO.setup(measure_pin, GPIO.OUT) #make the measure pin an output
    GPIO.output(measure_pin, False) # set it low to discharge the capacitor
    time.sleep(0.005)

def charge_time():
    GPIO.setup(measure_pin, GPIO.IN) 
    GPIO.setup(charge_pin, GPIO.OUT)
    count = 0
    GPIO.output(charge_pin, True) #start charging the capacitor
    while not GPIO.input(measure_pin): #wait till the pin goes HIGH
        count = count +1
    return count

def analog_read():
    discharge()
    return charge_time()

# loop to display analog data count
while True:
    print(analog_read())
    time.sleep(1)
    


                  

Leave a comment

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