This chapter contains a short and simple guide to voltage measurement with Raspberry Pi for hobbyists with limited electronics knowledge.
Arguably the biggest disadvantage of Raspberry Pi is that, unlike its cousin Arduino, it has no proper analogue inputs. This means that all general purpose input output (GPIO) pins are purely digital, that is they basically only supply/detect two voltages, 0.0V for the Low state and 3.3V for the High state. If you want to read out an arbitrary voltage, you have to use an analogue-to-digital converter (ADC) circuit and connect it to several GPIO pins.
Selecting, installing and programming an ADC microprocessor chip can be quite a feat, especially for a hobbyist. Fortunately, there are few ready-made commercial solutions for this purpose, with detailed instructions, program libraries and examples:
All these devices connect to the I2C pins of Raspberry Pi, where the AB Electronics devices use two programmable and the Adafruit device uses one programmable address. This is an advantage because all your GPIO pins remain free for other uses. All devices also have an internal voltage reference, making voltage measurement very accurate and independent of Raspberry Pi. The basic differences are listed in the table:
|Name||Voltage (V)||Inputs||Max. precision||Max. samples per second||Impedance (Ω)||Addresses|
|ADC Differential Pi||−2.048 to +2.048||8 differential||18 bit||240||2.25M/25M||0x68 to 0x6F|
|ADC Pi Plus||0.0 to +5.0||8 single ended||18 bit||240||16.8k||0x68 to 0x6F|
|ADS1115||−3.3 to +3.3||2 differential||16 bit||860||15M||0x48 to 0x4B|
|0.0 to +3.3||4 single ended||16 bit||860||6M||0x48 to 0x4B|
Unless you plan to imitate an oscilloscope, the sampling speed is probably not important (and in that case you would not use a slow I2C protocol anyway). The precision is also comparable and satisfactory for all devices. The main differences are therefore:
If you want to be on the safe side, there is a relatively simple solution: you can buy ADC Differential Pi or ADS1115 and build a small simple voltage divider yourself. This is explained in the next section.
This chapter contains a short and simple guide to building a simple and compact four channel voltage divider for hobbyists with limited electronics knowledge.
We must start with the principle of a voltage divider. This basically consists of two resistors R1 and R2 connected in series to the source voltage Vin, as shown in the figure above. The voltmeter is connected only to the second resistor R2. Since the internal resistance of the voltmeter is very large, much larger than resistances R1 and R2, we can safely assume that the current through the voltmeter IV is zero. Then the current through both resistors I and the voltage at the second resistor and voltmeter Vout can be easily evaluated.
The resistances must be carefully selected and should be much smaller than the internal resistance of the voltmeter, but still as large as possible. For our needs values around 10 kΩ are appropriate. Knowing the maximum source voltage and the maximum voltmeter voltage, one can select a suitable resistor pair for the voltage transmission. Note that common resistors are available in discrete values, typically 1 kΩ, 1.2 kΩ, 1.5 kΩ, 1.8 kΩ, 2.2 kΩ, 2.7 kΩ, 3.3 kΩ, 3.9 kΩ, 4.7 kΩ, 5.6 kΩ, 6.8 kΩ, 8.2 kΩ, 10.0 kΩ, etc.
Suppose we want to transfer 5.0V to 2.048V, which is the maximum voltage of ADC Differential Pi. Some of the suitable combinations are R1 = 10.0 kΩ R2 = 6.8 kΩ (used by ADC Pi Plus) and R1 = 6.8 kΩ R2 = 4.7 kΩ. In my demonstration below, I use the second combination.
To build a four channel voltage divider, we need a prototype board with copper strips, a single row male pin header connector and at least eight resistors of power of 1/4 W and a tolerance of 1 %, four of resistance R1 and four of resistance R2. A tolerance of 1 % is essential to get a reliable voltage value and at the same time very cheap and easy to get. The final result can be improved by purchasing ten resistors of each value and selecting four with a resistivity closest to the average value.
To create a compact four channel voltage divider, we cut out a board with seven strips with ten holes each, as shown in the left picture. The resistance of the horizontal resistors is R1, while the resistance of the vertical resistors is R2. Connections below the R1 resistors should be broken by scratching the copper strip, as shown in the right picture. The upper left pins can be connected to the positive poles of four input source voltages Vin, while the upper right pins are connected to the positive poles of four voltmeter voltages Vout. The lower left pins represent the ground and are connected to the negative poles of the source and voltmeter voltages.
This chapter contains a short and simple guide to voltage output with Raspberry Pi for hobbyists with limited electronics knowledge.
Neither Raspberry Pi nor Arduino have proper analogue outputs. In fact, both microprocessors have a few general purpose input output (GPIO) pins with pulse width modulation (PWM) output. By switching between two digital states, the Low state at 0.0 V and the High state at 3.3 V, GPIO simulates mid-voltages. However, this is rather imprecise and not suitable for use in precise electronic devices. If you want to write an arbitrary voltage, you have to use a digital-to-analogue converter (DAC) circuit and connect it to several GPIO pins.
Selecting, installing and programming a DAC microprocessor chip can be quite a feat, especially for a hobbyist. Fortunately, there is one ready-made commercial solution for this purpose, with detailed instructions, program libraries and examples:
What I do not like about this solution is that it provides only one voltage output and has a fixed I2C address at 0xC0. But there are many alternatives. For example, Microchip also offers MCP4728, which has four voltage outputs, while the I2C address can be programmed between 0xC0 and 0xC7. An additional plus is that the chip is really cheap!
To prepare our four channel DAC, we need the MCP4728 chip, a DIP adapter PCB (printed circuit board), a single row male pin header connector (I strongly recommend the use of round pins), one to three R = 1.8 kΩ resistors (anything up to 10 kΩ will do), optional C = 100 nF capacitor and a solder wick. The biggest challenge is to solder the chip to the PCB: The chip is extremely small, with overall dimensions of 3 mm × 3 mm, and the distance between the pins is only 0.5 mm! The task is difficult but feasable.
I succeeded in soldering three chips with an amateur soldering iron and a solder wire, and the result is shown on the picture above. I used a good solder paste to flood the PCB before soldering and a good solder wick to remove excess solder afterwards. There are dozens of instructions on the Internet on how to do this, for example general instructions for surface mount soldering or soldering a similar chip onto an adapter PCB. This is an extremely small and light chip, so I also use the kapton tape to fix it during soldering.
Since there was currently no Python library for this chip, I decided to get involved and create a simple library myself. The latest version of the library is written in C and is published on github.
The figure above shows the setup for changing the output voltages. There are no pull-up resistors because the setup uses Raspberry i2c-1 pins (GPIO2 and GPIO3) with built-in pull-up resistors. The capacitor is optional, but strongly recommended. One can also use Rasperry i2c-0 pins (GPIO0 and GPIO1), but in this case pull-up resistors are mandatory.
The figure above shows the setup for reading and writing the I2C address. The method requires an additional LDAC line and is not I2C protocol compliant, so bitbanging must be applied. The easiest way is to select another GPIO and use the pull-up resistor R. Three non-I2C GPIOs can also be used for reading and writing, but in this case all three lines must have pull-up resistors and it is not possible to change output voltages.
Please note: The MCP4728 manual from 08/04/10 contains serious errors:
I have lost two days banging my head to figure this out!
Please use the feedback form to tell me what else you would like to see here, suggestions, new tricks, etc.
Created by Marko Pinteric: feedback form.
Updated . Web page has been read by visitors since February 2017.