Designing and Building an ADC for the Raspberry Pi

Raspberry Pis have become a rage wherever one needs to add some electronics to a project, yet they are not a very good tool for controlling electronics. It comes with few 3v3 digital GPIO pins. Now say for instance you want to hook on a potentiometer to the Pi how would you do it? The answer is normally to use an external ADC. There are numerous prebuilt ADCs out there. I however decided to try to build my own ADC.

There are numerous ADC designs out there, however when designing such a device one must take into account a few things:

  • Sample rate
  • Hardware complexity
  • Accuracy
  • Resolution

For my home made ADC accuracy and resolution are not the highest priority – I just want to be able to read the value of a Potentiometer. Hardware complexity is very important though. Ideally I should require a minimal number of components to build this ADC.

The central component of an ADC is the comparator. The comparator is a circuit that, as its name suggests,  compares two voltages.  The circuit symbol for the comparator is:


A comparator

Basically if V1 > V2, Vout will be High otherwise Vout is low. One of the techniques used known as the Flash ADC takes multiple such comparators with each ones voltage held at a different level to determine the incoming voltage. However, the Flash ADC requires many comparators. Another way of solving the problem is by using only one comparator and varying V1. This does not give us the best results but its a good enough compromise for us.

In order to vary V1 I decided that I would use a capacitor and a resistor as a reference for my voltage. A capacitor stores energy while a resistor dissipates energy. What I would do is charge the capacitor fully then slowly let the voltage across the capacitor and resistor drop.


RC Circuit – View Full Simulation

In the circuit above a short pulse of a high voltage is sent to the capacitor. The capacitor gets fully charged then discharges across the 1k resistor. The diode prevents the current from flowing back to the source. This creates a well defined pattern. The equation for the discharge is;

V = V_0 e^{-\frac{t}{RC}}

I used this as the reference voltage for the comparator. The schematic would look something like this:


Schematic for simple ADC – Simulation

I went on to breadboard the above circuit together with a potentiometer:

mysketch_bbThis allowed me to test the theoretical simulation. The blue wire supplies the charging current (pulse source in the case of the above circuit) for the reference voltage, the orange wire is the output of the comparator and the purple wire is the input voltage. The rails were connected to ground and 3v3 respectively. In order to test the circuit behavior I chose to use my Arduino as an oscilloscope instead of my Pi. The latest Arduino IDE comes with a beautiful serial plotter that consumes CSV data sent by the serial uplink.

ADC WaveformThe red line represents the output, the green is the input voltage as set by the potentiometer. And the blue line is the changing reference voltage. Notice that at the point where the reference (blue) drops below the input (green) the output (red) goes high. Based on the time at which this change takes place one can determine the voltage. All we have to do is take this formula:

V = V_0 e^{-\frac{t}{RC}}

and change the subject to time.

t = -RCln\frac{V}{V_0}

Thus the time taken from the start of the discharge cycle to the point at which the output goes high is proportional to the natural logarithm of the voltage. You just need to know the values for R, C and V0.

Choosing the values for the resistor and capacitor

As shown above the discharge time is proportional to the RC constant. The RC constant also affects the sample rate and resolution. The LM393 has a switching speed of roughly 1.3us. This means at the most it can operate at around 700KHz. Thus in order to get a good 10bit resolution we would have to take 1024 samples. We need to discharge in roughly about 1.3us \times 1023 = 1329.9us \approx 1.3ms. Normally we would say a capacitor is fully discharged after about 99.3% of it is discharged. This happens around 5RC. For a full explanation see this article. But either ways we would divide 1.3ms by 5 to get 0.26 for our RC constant. You can combine a 2.6K resistor with a 100 microfarad capacitor to achieve this. Or you could use a 50 microfarad capacitor with a 5.2k resistor and so on.

Some interesting quirks about this design

Higher voltages have lower resolution. Since the discharge time is proportional to the logarithm of the voltage this means that the rate of change of voltage vs discharge time is 1/n. Thus the higher the voltage the lower the precision.

Where to go next

This ADC is lacking a very important component – The sample and hold circuit. This makes it unsuitable for use with fast changing signals. If the voltage changes midway through an RC discharge cycle we will find ourselves with only the earliest reading where the ADC took the correct reading. Perhaps in the future I’ll do something about it.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s