In this tutorial, we will explore how the Raspberry Pi can be used to read analog signal data accurately and the use of potentiometers in carrying out this great task. Let’s get started!

One thing to note about RPi is that it is unable to read analog signals directly. It can detect digital signals like the push of a button or a simple change in a digital sensor’s state, but not the changes made by an analog sensor. But the good thing, there are two ways to actually sort this problem out.

The first method is to use an ADC (Analog-to-Digital Converter) like the MCP3008 (for 8 channels of analog input) or ADS1X15 (for 4 channels of analog input). The only difference between them is that ADS1X15 is better in precision compared to MCP3008.

Fortunately, there’s another way to read the analog signals without having to buy an ADC chip. This saves us from the hassle of spending a lot on expensive chips. This method is known as “step-response.” Using this methodology, we see how the circuit behaves during a change in state from high to low or low to high, also known as ‘step change.’ This is done by using the charging and discharging circuit controlled by a potentiometer with a Rpi.

Now, let’s dive into that.

What is a Potentiometer?

A potentiometer is a variable resistor used to vary the resistance in a circuit by rotating a knob. This is used to vary voltages in any circuit or to control current flow in a circuit. It contains three pins; the first one is used as an input and the second is for ground connection, and the third is situated in the corner as the output pin.

Reading Analog Signal Data with Potentiometer in RPi

Now let’s build a sample project to understand this better!

Components Required:

Wiring Diagram

But before we proceed, let me explain something to you more clearly.

This entire circuitry depends on the charging and discharging of a capacitor, which, in turn, depends on how this circuit responds to an electrical pulse within a particular period of time. So, we particularly target the time to detect the analog signal value. This time is dependent on the variable resistance of the resistor, which we will change. All of these will be shown in the RPi terminal.

In simple terms, the capacitor acts like a container of charge. As it fills with charge, the voltage across it rises, but you cannot read the voltage as RPi is incapable of reading analog voltage value. Thus, to read this value, we basically note the time it takes for the voltage to go above 1.5-1.6V, typically a value that registers a digital high. The charging speed depends upon the value of the variable resistor; the less the value, the faster the capacitor will charge.

The second most important step to note here is that the capacitor needs to discharge completely before being used again to get a good reading. So for this, we use the resistor R1 connected to pin 18 with the 10K variable resistor for completely charging the capacitor. On the other hand, we use R2 for discharging the capacitor connected to pin 24 in RPi.

We will now apply the step-response signal for 4 to 5 ms (well, generally 5ms). In that particular time, the capacitor will charge via R1 and variable resistor and will discharge via R2. The discharge time here is set to less than 1 ms and is done via the python code shown below. As this cycle continues for charging and discharging, the code acts as a counter and provides values equivalent to the step-response read by the RPi. This is how the RPi reads the entire analog signal with a potentiometer’s help in a step-response circuit.

In summary, we basically use R1 and the potentiometer to charge the circuit together, and R2 to discharge the circuit which is then read by a python code to give us the values for the step-response change with time.

Code

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

pin-a = 18
pin-b = 24

def discharge():
    GPIO.setup(pin-a, GPIO.IN)
    GPIO.setup(pin-b, GPIO.OUT)
    GPIO.output(pin-b, False)
    time.sleep(0.004)

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

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

while True:
    print(analog_read())
    time.sleep(1)

After completing the circuit, use the code above in the RPi terminal and name it as step-res.py.

Run the code by typing the following command in the terminal:

sudo python step-res.py

Terminal Response

After running the code, you will start seeing the response in the terminal like the one shown above. As you rotate the potentiometer, the value will increase in one direction and decrease in the other.

This is the best possible method to read analog signals of any sensor. Just note that we did the step-response technique instead of using ADCsfor practical reasons. But if you have the resources, it’s better to use an ADC with the RPi as they are far easier and accurate.