Over a recent couple of weekends I built a thing to measure the current and voltage of the components of a 12V solar/PV power system. Ever since I started using solar power at Burning Man I wanted to get a good measure of how much I was consuming and how much was left. At the time I settled on a Morningstar charge controller with LCD voltage meters to tell me.
This new setup adds data recording+logging into the mix, something I’ve always wanted. Here, the measurement modules are attached to a Raspberry Pi via i2c and a simple python script collects the data and sends it wirelessly to OpenTSDB for storage and charting.
The hardware and other bits, excluding the Pi, ran me around $50-$60. Allegedly this setup should handle about 3 amps, although if somebody wants to do the arithmetic and make an appropriate shunt they should be able to measure much higher currents.
At the heart of the setup are three INA219 (“high side DC current sensor”) modules from Adafruit which do the measuring, one each for the solar input, the battery, and load. They’re about 1″ square, have a terminal on the board for wiring in-line in electrical circuits to measure, and have a small shunt and chip that measures the voltage and current. The bulk of my time was spent making a wiring harness for this setup to plug into my existing solar setup and soldering on all the connectors. I personally insist on everything I have use Power Pole connectors so if one were less inclined they could avoid a lot of work. Working with the rest was relatively quick work. Adafruit has some excellent tutorials on wiring up and working with the INA219, which is where I got the majority of my information.
Each of the INA219 modules speak i2c to the RPi and the SDA/SCL pins daisy-chained with continuous jumpers back to the respective i2c pins on the RPi (P3 and P5) to form an i2c bus. Two have solder junctions to set the i2c address, resulting in the three being accessible on the bus at 0x40, 0x41, and 0x44. Also to power the INA modules themselves, another set of continuous jumpers connect Vcc and GND back to the 5v and GND pins of the Raspberry Pi. Adafruit has a generous tutorial on how to connect and verify i2c is working. For the most part it was painless and simple, enable the i2c kernel module and the three INA modules just showed up when I ran “i2cdetect -y 1”.
The few software libraries for the INA219 and i2c assume use with an Arduino, but some dude over on Github did a nice Python port of the INA219/i2c library. However, there looks to have been a bug in the original Arduino version regarding two’s complements and the code on Github needs a slight patch to properly measure negative voltages. (note to self, submit a patch). Once that’s sorted out, it’s just simple Python method calls to get instant voltage and current information.
A quick example to query the three INA219 modules looks like:
#!/usr/bin/python
from Subfact_ina219 import INA219
for i2caddr in ['0x40', '0x41', '0x44']:
ina = INA219(address=int(i2caddr,16))
print "== %s " % i2caddr
print "Bus voltage: %.3f V" % ina.getBusVoltage_V()
print "Shunt voltage: %.3f mV" % ina.getShuntVoltage_mV()
print "Current: %.3f mA" % ina.getCurrent_mA()
print "Voltage: %.3f V " % ( ina.getBusVoltage_V() +
ina.getShuntVoltage_mV() / 1000 )
To get the voltage of the thing you’re measuring, you must add the bus voltage and shunt voltage to get all the components of the measurement. Also, you must wire grounds of the battery, solar panel, load, and the Raspberry Pi together to be able to measure individual voltages. (Something I forgot to realize for a long time.) Otherwise you only get electrical current data, voltage is indeterminate.
root@solar:/home/pi# python power.py == 0x40 Bus voltage: 12.420 V Shunt voltage: -37.270 mV Current: -373.000 mA Voltage: 12.383 V == 0x41 Bus voltage: 12.548 V Shunt voltage: -37.160 mV Current: -372.000 mA Voltage: 12.511 V == 0x44 Bus voltage: 12.416 V Shunt voltage: 1.000 mV Current: 10.000 mA Voltage: 12.417 V
Here, module 0x40 is represents the load, 0x41 is the battery, and 0x44 are the solar panel. There’s a string of 12V LED lights hooked up right now, drawing 373 milliamps. Likewise there’s a 373 mA draw on the battery. The solar panel is in shade so it’s only contributing 10 mA right now. The negative values are a handy indicator of the direction of the current, i.e. when the battery is charging the values are positive, when it’s being discharged the values are negative.
For the small solar setup, I’m using a solar panel and charge controller from Harbor Freight. Their 7A charge controller features a low voltage disconnect (something I required for this setup), is compact and pretty inexpensive. It fits tidily into the plastic container which temporarily houses the RPi and modules. This will work with any charge controller. Another container holds a small 12V battery. [Edit: I have my doubts about the LVD feature of this charge controller after it apparently let my battery get down to 6 VDC under load overnight. >:( ]
Note: at the time the Raspberry Pi is not solar/battery powered, nor can it switch on/off any of the loads. I have an USB power cord running inside to power the setup. It should be easy to rig up a voltage converter, but that’s a project for another time. This would make it a real standalone unit and be quite handy and adapted into other real applications.
For the data storage, I wrote a Python tcollector script for OpenTSDB which polls the INA modules every 15 seconds and records the values to a database. Using the built-in plotting tools, I can quickly visualize current or historic solar production or power consumption. The shameless cut-n-paste tcollector I wrote is over on my Github page.
The script prints a ‘ina219’-prefixed metric name, timestamp, tags and data suitable for use in a time series database:
ina219.shunt_voltage 1396837555 0.050 address=0x40 name=load ina219.voltage 1396837555 12.672 address=0x40 name=load ina219.bus_voltage 1396837555 12.672 address=0x40 name=load ina219.current 1396837555 0.000 address=0x40 name=load ina219.shunt_voltage 1396837555 -0.690 address=0x41 name=battery ina219.voltage 1396837555 12.671 address=0x41 name=battery ina219.bus_voltage 1396837555 12.672 address=0x41 name=battery ina219.current 1396837555 -7.000 address=0x41 name=battery ina219.shunt_voltage 1396837555 0.130 address=0x44 name=solar ina219.voltage 1396837555 12.672 address=0x44 name=solar ina219.bus_voltage 1396837555 12.672 address=0x44 name=solar ina219.current 1396837555 1.000 address=0x44 name=solar
Two-hour plot of battery voltage while connected to load of lamps for an hour:
Eventually I’d like to have a battery charge monitor, but this involves getting the temperature of the battery to take into account.










