
Introduction Parts List and Arduino Wiring Arduino Code and battery Charge Tests Python Code and Datalogging Battery Voltage Output Conclusion and Continuation
Voltaic has added the ability to read the voltage, and thus the charge level, of the Li-ion cells in its V25 and V75 USB Battery Packs (V50 will follow shortly). If you are building an IoT application using one of these Always On battery packs, you can monitor the state-of-charge (SoC) and potentially make changes to your application’s power consumption in order to keep it running 24 x 7.
In this post, I show how you can use a microcontroller and the INA219 voltage/current sensor to read and report the cell voltage from the batteries’ USB-C port.
An Arduino Uno board is used as the main datalogger for the tutorial, which will allow for real-time measurement of voltages and currents as a function of time. The 10-bit ADC of the Arduino is used to measure the voltage outputted by the V25 battery’s USB-C D+ pin, while the INA219 reads the input voltage and current of the power supply. The INA219 is a good choice due to its low quiescent current during power down (~6μA) and minimal consumption during reading (~1mA).
V25 USB Battery Pack
The principal components required to follow along with the experiment are:
- V25 USB Battery Pack – $35 [Buy from Voltaic]
- Arduino Uno Board – $13.00 [Buy from Maker Portal]
- INA219 Current/Voltage Sensor – $7.89 [Buy from Amazon]
- USB-C Terminal Breakout – $8.99 [Buy from Amazon]
- 0V-30V, 5A Variable Power Supply – $69.97 [Buy from Amazon]
- 18 AWG Solid Core Wire – $14.49 [Buy from Amazon]
- Mini Breadboard – $3.00 [Buy from Maker Portal]
The 18 AWG wire is a particularly important requirement for the power supply and load circuit, as many of the standard jumper wires included with Arduino kits are incapable of handling the 2A supply currents requested by the V25 battery pack. Another important caveat of the 18 AWG is that the diameter is too thick for Arduino input pins, so be sure to use 22 AWG for the Arduino components and 18 AWG for the power circuit. Any power supply should work for this particular application, under the assumption that it can supply the 5V/2A specification of the USB-C port of the battery. Keep in mind – if a lower capacity charger is used, longer charge times will result. It is also important to use the terminal portion of the INA219 voltage/current sensor, instead of the inline pins. This will again circumvent any amperage limitations on the traces of the breadboard used to wire the INA219 (if at all).
The wiring diagram is given below that links all components used in the tutorial:
Figure 1: Wiring diagram between Arduino board, V25 battery, INA219 voltage/current sensor, and external power supply
The relationship between a USB-C plug and the USB-C terminal can be seen in the figure below:
Figure 2: USB-C plug in relation to USB-C terminal pin inputs.
Since the INA219 is a high-side current sensor, we see its function at the beginning of the circuit taking the input directly from the power supply. Then, the V25 battery follows next in the circuit, ultimately leading back to the power supply’s ground. Additionally, the D+ is broken out from the USB-C terminal to go directly to the Arduino board’s A0 analog pin, which is where we will measure the V25 cell voltage. We also need the Arduino to share a ground with the power supply, which is also what’s done in Figure 1. Lastly, the INA219 is wired to the Arduino Uno via the Inter-Integrated Circuit (I2C) protocol. Another important point to note is the use of the 3.3V analog reference. As stated at the introduction, the V25 battery has a scaled voltage of roughly 1/2, which means that we will see a maximum cell voltage around 4.2 – which scales by half to 2.1. Thus, we don’t need the entire 5V analog range of the Arduino, which is why we have chosen 3.3V as the reference. This will give us higher resolution on the 10-bit reading, which consequently is from 0V-3.3V. In the next section, the Arduino code used to measure voltage and current in real-time is introduced and explained.
The Arduino code given below measures voltage from the input power supply and load current from the V25 battery, while also reading the USB-C D+ voltage output on pin A0 of the Arduino board. The code was developed using the Arduino IDE version 1.8.13.
The code outputs four variables: seconds since the start of the Arduino program, voltage passing through the load, current passing through the load, and scaled voltage outputted by the USB-C D+ pin. These four variables will help us determine what is happening with the system over time during charging. Below is an example output from the Arduino’s serial port upon correct wiring according to Figure 1 and uploading of the code above:
Figure 3: Arduino INA219 serial output example showing the time, load voltage, load current, and USB-C scaled voltage output.
Investigation of Figure 3 tells us that we have an input voltage of roughly 5V (~5.3V in my case), a load amperage of 2A, and a scaled voltage of 2.01V. Similar values should give confidence that the user has wired the components correctly, uploaded the code properly, and is following along closely with the expectations of the experiment. In the next section, a Python code will be presented that reads the serial outputs shown above and plots them in real time. Later in the code, the outputs will be saved for analysis and post processing.
At this stage in the experiment, the user should have a constant stream of voltage and current values being outputted by the Arduino board. In this section, a Python script will be used to read the Arduino serial data and plot the values in real time. Python 3.7 is used, in conjunction with a series of libraries and protocols for reading from the Arduino serial port. The Python code for reading and plotting in real time is given below:
If we first ensure that the battery is fully discharged (this can be done rapidly by using a high current-draw source), we can observe the battery’s behavior as it goes from fully discharged to fully charged. We expect to see several stages of the charge curve: a startup stage involving a rapid change in cell voltage, a constant current stage where the current is steady and the cell voltage is slowly changing, and finally a constant voltage stage where the cell voltage reaches an asymptote and the current decreases [read more about charge curves here]. Typically, the maximum cell voltage is set to 4.2V, which is what we use as the predictor for the maximum voltage in the case of the V25 battery.
The experimental procedure for logging battery voltage is quite simple:
- Ensure the Arduino, INA219, and V25 Battery Pack are wired correctly
- Start the Python data acquisition script
- Set the input voltage to 5V (±5% for DC wall plug supplies)
- Set the input current to 2A (or ensure the wall plug can maintain this)
- Wait for the current to reach approximately 0mA on the Python plot
- Look for the file stored locally with the voltage/current experiment data
Another Python script is included below for data analysis and visualization purposes:
The script above will create a visualization of the charge curve for the V25 battery. We should see several of the stages expected: startup, constant-current (CC), constant-voltage (CV). If these are not visible on your curve after several hours – there is likely either a wiring issue, Arduino code issue, or Python code issue. Look for errors in wiring if the current are very low or voltages are very low. It is also possible that the charger being used is insufficient. It is best to use a supply to get accurate and steady input.
Figure 4: V25 charge cycle results showing the different stages of charge. The cell voltage (purple) has been approximated using a scale factor of 1.84.
The results from our charging experiment are shown above in Figure 4 , where we see five stages of charging. We see the startup stage where the D+ voltage output ramps up, then we see stage two with the long constant-current (CC) spanning just over one hour; finally, we see a crossover stage where the current begins dropping off. The LEDs on the V25 battery stop blinking somewhere in the middle of the third stage, as expected. Then, we see a sharper current dropoff decreasing further, while the voltage starts to decrease as well. Finally, a switched-off stage appears where the current is approximately 0mA and we see steady cell and input voltages. This process takes roughly 3.3 hours, whereas, the technical time to a state-of-charge (SoC) of 100% takes approximately 2.5 hours.
In this tutorial, we showed how to read the voltage of the cells in a V25 USB Battery Pack with an Arduino board. The Arduino was wired to the V25 battery, an external power supply, and an INA219 current/voltage sensor. An Arduino code was then introduced as a way of monitoring the input voltage, load current, and cell voltage. A datalogging routine in Python acquired data from the Arduino board that represented each input and plotted the results in real time.
In the next post, we will show you how to use the cell voltage to monitor charge level and change behavior of your application. For example, when the battery starts to become low, you can put your device into a sleep mode or transmit data less frequently.
This post appeared first on Voltaic Systems.