Rustic Retreat
Hot Projects
Live broadcasts and documentation from a remote tech outpost in rustic Portugal. Sharing off-grid life, the necessary research & development and the pursuit of life, without centralized infrastructure.
This is an old revision of the document!
Batteries in general and lithium based batteries in particular require special attention, when it comes to charging and balancing. For this reason, the lab has a Junsi iCharger 1010B+, which offers a complete battery management solution for virtually every battery technology out there and some non-battery related features as well (like DC-Motor burn-in and foam-cutting programs).
It has proved itself as reliable hardware for over a year, especially taking care of the custom made LiPo battery packs for the orion. It even offers a USB port for software updates and data-logging. Unfortunetaly, until now, only LogView users could get the logging data, but that would require a closed-source non-free operating system to run, which isn't available here (see Apollo-NG's Code of Conduct). Additionally, while LogView itself may be free (as in free beer), it doesn't seem to be open-source, so another solution was due…
Luckily, the USB port is actually just a serial port based on the cp210x serial to USB converter. Remember to build and load the kernel module, it should look like this, when you plug-in the iCharger:
[2865177.518351] usb 1-6.2: new full-speed USB device number 60 using ehci_hcd [2865177.604715] usb 1-6.2: New USB device found, idVendor=10c4, idProduct=ea60 [2865177.604720] usb 1-6.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [2865177.604723] usb 1-6.2: Product: Junsi iCharger 1010B+ [2865177.604726] usb 1-6.2: Manufacturer: Silicon Labs [2865177.604728] usb 1-6.2: SerialNumber: 0906102520 [2865177.605380] cp210x 1-6.2:1.0: cp210x converter detected [2865177.668344] usb 1-6.2: reset full-speed USB device number 60 using ehci_hcd [2865177.753915] usb 1-6.2: cp210x converter now attached to ttyUSB0
The following code will read, translate and calculate all vital battery and voltage/current data. It was written in Python, since it's always inherently available on Gentoo systems, but should be easily adaptable into any other language. A node.js implementation with realtime web(socket) graphs would be interesting, to make it even possible to remote-monitor the process.
#!/usr/bin/env python # -*- coding: utf-8 -*- # ######################################################################## # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # ######################################################################## import os, sys import time import serial # discharge end voltage (empty) dchg_end = 3.2 # iCharger modes of operation mop=[None]*13 mop[1] = "Charging" mop[2] = "Discharging" mop[3] = "Monitor" mop[4] = "Waiting" mop[5] = "Motor burn-in" mop[6] = "Finished" mop[7] = "Error" mop[8] = "LIxx trickle" mop[9] = "NIxx trickle" mop[10] = "Foam cut" mop[11] = "Info" mop[12] = "External-discharging" # configure the serial connections # change according to the ttyUSB assigned to the iCharger (dmesg) ser = serial.Serial( port='/dev/ttyUSB0', ) ser.open() ser.isOpen() ### MAIN ############################################################# while 1 : line = ser.readline () raw = line.split (';') v_bat = float (raw[4])/1000 v_c1 = float (raw[6])/1000 v_c2 = float (raw[7])/1000 v_c3 = float (raw[8])/1000 v_in = float (raw[3])/1000 i_chg = int (raw[5])*10 i_sum = float (raw[18])/1000 t_int = float (raw[16])/10 t_ext = float (raw[17])/10 s_vc1 = ((float (raw[6])/1000)-dchg_end)*100 s_vc2 = ((float (raw[7])/1000)-dchg_end)*100 s_vc3 = ((float (raw[8])/1000)-dchg_end)*100 s_bat = round ((((float(raw[4])/1000) - (dchg_end*3))*100/3), 1) print "Mode: " + mop[int(raw[1])] print "Batt: " + str(v_bat) + " V (" + str(s_bat) + "%)" print "Cell 1: " + str(v_c1) + " V (" + str(s_vc1) + "%)" print "Cell 2: " + str(v_c2) + " V (" + str(s_vc2) + "%)" print "Cell 3: " + str(v_c3) + " V (" + str(s_vc3) + "%)" print "Supply: " + str(v_in) + " V" print "Charge Current: " + str(i_chg) + " mA" print "Charge Amount: " + str(i_sum) + " A" print "Temp INT: " + str(t_int) + " °C" print "Temp EXT: " + str(t_ext) + " °C" print ">>" + line
It only requires the pyserial package, on gentoo you can just:
$ emerge -av pyserial
To run the application, make sure your user has permission to read the ttyUSB device and run:
$ python pycharger.py
There was not enough time to come up with a fancy pygtk or any other graphical implementation to show the data in real-time on a graph. Since the basic code, the data-mapping and the calculations are done and released under GPL3+ now, maybe someone else can step-in and extend the features to have realtime graphs :)
The following example shows the data-log output of pycharger.py, with the iCharger in monitoring mode. The battery is one of orion battery packs, after half a night of recording:
Mode: Monitor Batt: 12.199 V (86.6%) Cell 1: 4.064 V (86.4%) Cell 2: 4.072 V (87.2%) Cell 3: 4.067 V (86.7%) Supply: 12.315 V Charge Current: 0 mA Charge Amount: 0.0 A Temp INT: 34.3 °C Temp EXT: 22.3 °C >>$1;3;;12315;12199;0;4064;4072;4067;0;0;0;0;0;0;0;343;223;0;46 Mode: Monitor Batt: 12.199 V (86.6%) Cell 1: 4.065 V (86.5%) Cell 2: 4.071 V (87.1%) Cell 3: 4.068 V (86.8%) Supply: 12.328 V Charge Current: 0 mA Charge Amount: 0.0 A Temp INT: 33.8 °C Temp EXT: 22.5 °C >>$1;3;;12328;12199;0;4065;4071;4068;0;0;0;0;0;0;0;338;225;0;39 Mode: Monitor Batt: 12.199 V (86.6%) Cell 1: 4.064 V (86.4%) Cell 2: 4.071 V (87.1%) Cell 3: 4.067 V (86.7%) Supply: 12.315 V Charge Current: 0 mA Charge Amount: 0.0 A Temp INT: 33.8 °C Temp EXT: 22.2 °C >>$1;3;;12315;12199;0;4064;4071;4067;0;0;0;0;0;0;0;338;222;0;32
The same battery pack, at the end of a charge cycle, in the final balancing phase:
Mode: Charging Batt: 12.618 V (100.6%) Cell 1: 4.2 V (100.0%) Cell 2: 4.205 V (100.5%) Cell 3: 4.205 V (100.5%) Supply: 12.362 V Charge Current: 180 mA Charge Amount: 0.725 A Temp INT: 40.0 °C Temp EXT: 26.7 °C >>$1;1;;12362;12618;18;4200;4205;4205;0;0;0;0;0;0;0;400;267;725;31 Mode: Charging Batt: 12.599 V (100.0%) Cell 1: 4.2 V (100.0%) Cell 2: 4.205 V (100.5%) Cell 3: 4.205 V (100.5%) Supply: 12.315 V Charge Current: 180 mA Charge Amount: 0.725 A Temp INT: 39.7 °C Temp EXT: 26.6 °C >>$1;1;;12315;12599;18;4200;4205;4205;0;0;0;0;0;0;0;397;266;725;29 Mode: Charging Batt: 12.579 V (99.3%) Cell 1: 4.194 V (99.4%) Cell 2: 4.205 V (100.5%) Cell 3: 4.204 V (100.4%) Supply: 12.315 V Charge Current: 170 mA Charge Amount: 0.725 A Temp INT: 39.7 °C Temp EXT: 26.6 °C >>$1;1;;12315;12579;17;4194;4205;4204;0;0;0;0;0;0;0;397;266;725;19
Although the code could only be tested with the 1010B+ here, it is likely to be compatible to all sister models. If you have a different Junsi model and are able to test the code, please be so kind and leave some feedback for other people, who also look for free and open-source data logging alternatives.
<note tip> If you're looking for a cheap grid power supply to drive the charger, any old PC AT or ATX power supply will do, since the charger itself is nothing else but a versatile buck/boost converter, regulated by a micro controller and assisted by a battery of balancing resistors. The 12V output of a 300W ATX supply is being used here. </note>