Lithium battery tester![]() The "finished" product, after a test run. I bought a lithium battery tester that was made in China. It seemed to work OK, but it was real picky about the load current. It wouldn't run at all if the current was "too high", except the currents weren't all that high. Finally, I bought some batteries from a vendor who claimed they were new, and the batteries all tested "bad", so I started to doubt my Chinese tester. So I lashed up a "simple" tester using an Arduino, and started getting much more reasonable results. I decided to make this a "finished" project, in a case and everything, so I'd always have a decent tester. The simplest tester is a fixed resistor across the battery, and some means of disconnecting it when the battery is "fully" discharged. For Lithium-ion batteries, this means a voltage of about 3.6 volts. The problem with this simplest tester is that as the battery voltage drops, the load current drops, so it's hard to measure/compute the milli-amp hours the battery can supply. (Yes, I know I could integrate little slices of mAh, but that's ugly.) The next enhancement is to vary the load resistor (down) as the battery voltage drops. This way, the tester can maintain a constant load current, making computation of mAh trivial. Also, often an electronic load is designed to draw constant current (or sometimes, constant power) from the battery, so I think this test method close to real-world battery usage. I chose to switch discrete resistors in and out to vary the load. The Chinese tester used a MOSFET as a variable resistance, and this is certainly valid, but then I'd have to measure the current accurately in order to control the resistance the MOSFET presents to the battery, and that seemed like a more complex solution, both software and hardware, than I wanted to build (because then I'd have to worry about the current sense (burden) resistor, and that needs an amplifier to raise the voltage up to where the microprocessor can measure it, but the voltage is millivolts referenced to ground, so I'd need a special op amp, yadda yadda yadda . . .). If you can vary the load resistor, it follows that you can choose any discharge current you like, to accomodate larger or smaller (or older/weaker) batteries. As long as you've got a microprocessor running things, you might as well measure internal resistance. That's easy: measure the unloaded voltage, add a known load, measure the loaded voltage, and the internal resistance is:
(unloaded voltage - loaded voltage) change in voltage
------------------------------------ = -----------------
(unloaded voltage / load resistance) load current
Schematic and Circuit Discussion![]() There's not much to this. The micro controls the display, looks for button presses, and controls the load resistors and relay that enables charging. The most interesting part of this is the load resistor "bank". It's really a 7 bit DAC, where a 7 bit number enables load currents up to 127 * 12.5 mA. Max load is nominally 1587.5 mA, so a bit over 1.5 Amps, which is plenty for an 18650. For the loads up to 100mA, any decent NPN transistor (like 2N2222) can saturate and act as a "perfect" switch for our purposes. For the two higher current loads, 200 and 400mA, I used MOSFETS, which have very low Rds-on resistances. These need a full 5V of drive on their gates, so there are two NPN transistors that amplify the digital output of the Atmega 328 (processor on the Arduino UNO and Nano) up to a full 5V swing. I put a tiny fan in the box, and some vent holes, to push the heat out of the box during a test run. The 7805 regulator that drops the 9V wall wart to 5V has an external heat sink. This is only needed when charging the battery after a run, as the Nano itself barely draws anything. The fan runs when the relay is off, which is when the Nano is doing a test run. Note that the battery plus terminal is wired directly to the analog input of the Atmega 328. This means that you can't test a battery that has a voltage over 5v (or whatever VCC is for your Atmega 328). I designed this to test a single Lithium cell (doesn't matter what chemistry), but it could also test a NiCd or NiMH battery (though the load calculation at setup time assumes a 4V battery. I should fix that . . .). The User Interface (UI)
Up and Down buttons change the target load current and the display shows both current and the approximate resistance that will be the the initial load.
Also, when a run ends, the relay is switched so that the battery charger is hooked to the battery, though through the toggle switch so the user can manually enable or disable the battery charger.
Construction DetailsOften, when I design a microprocessor project, I find it convenient to just wire a bunch of pre-built modules together, rather than run a PCB. In this case, I used pre-built modules, except for the load resistor bank, which I hand wired on a piece of perf board. The modules are:
The hard wired bit is the 7 load resistors and 5 transistor switches, and, on a second "overflow" board, two MOSFET switches for the high-current loads (10Ω and 5Ω). The second hand wired bit is the 7805 voltage regulator, which is just hanging off the heat sink mounting bolt. The third hand wired bit is the NPN transistor inverter used to drive the fan. This tiny board is bolted/glued to the relay board, since it's input is from the relay coil drive. ![]() Inside view. The Nano is viewed almost end-on, so you can't really see it. I haven't figured out how to mount the Nano. Right now, it just hangs on all the wires. Processor SelectionI started using an Arduino UNO, because:
The Arduino UNO worked well enough, but I switched to a Nano in "production" because the Nano is smaller and has two more I/O pins, so I could use parallel i/o for the LCD. Side note about "Dupont" jumpers"Dupont" (.025" square pins and matching sockets) jumper wires are convenient for lashing something up quickly, but they don't have the best retention force, and fall out at the least provocation. I may come to regret using these Dupont connectors for this project. One trick is to bundle several wires and connections into a multi-pin housing. This makes single connections less likely to pop apart. ![]() "Dupont" connectors and their plastic housings. The single pin housing is far right, and the rest are the multi-pin housings.
Controlling the DisplayThis project didn't need a GUI, so it's a 44780 based two line LCD for me. I have a handful of these in my junk box, too. One can interface with these at least three ways: the Modern Devices serial board (which uses a PIC micro), the relatively common PCF8560 I2C port expander, or just driving the 44780 in "parallel" mode using 4 data pins plus "E" and "RS". Since I had enough I/O pins on the Nano, I used parallel mode. The code has support for all three LCD interfaces, but you'll probably have to fiddle with the I/O port assignments. Unexpected Difficulty 1The initial development was done with the Arduino powered by the USB from my workstation. Later, after building the unit in a box and powering it from a 9V wall wart, the calibration of the voltage measurement was way off (like 10%). This was because, when the Arduino is powered from a USB cable, there's a diode drop from the nominal 5V of the USB power, in addition to whatever voltage drop is in the USB cable itself, which gives a Vcc of about 4.7 V to the Arduino. Since the Arduino's Vdd is related to the Arduino's A/D reference voltage, this messes with the Arduino's A/D converter calibration, which will be about 4.7V for 1023 counts, or about 4.59 mV / count. When the Arduino has a voltage greater than 5V + 2V applied to it's "Vin" terminal, the onboard 5V regulator feeds very near 5V to the Arduino. So the A/D calibration will be close to 5V for 1023 counts in this case, (about 4.89 mV / count). There wasn't much to do about this except to calibrate the unit for when it's running off of the wall wart, and accept that the voltage readings would be way high when powered off of the USB cable. Unexpected Difficulty 2I couldn't figure out, after I had built most of it into the box, why the voltage readings were not stable, but instead were varying by +/- 0.2v. Testing revealed that the voltage readings were stable when the unit was powered via the USB connection to the Nano, but bad when powered by the 9V wall wart and 5V regulator. Looking at the 9V output with a scope revealed that the 9V output had nasty high frequency "hash" on it, obviously an artifact of the internal switching power supply in the wall wart. I soldered a 100µF capacitor across the barrel jack and that sorted it. Moral of this story: it isn't necessary that you have a scope, but there are times when that's the only way to see what's happening. Also, the scope should have a bandwidth of at least a few MHz if you want to see stuff like this switching noise. So your $9.99 Temu scope may not hack it. Without a scope, I would have just slapped a cap on there and noticed the voltage readings stabilized, and the result would have been the same. But it was good to be able to see the problem before throwing parts at it.
Source CodeSource code here.
FAQ
Q. Will you make me one? A. No, I'm retired and so not interested in a job.
Disclaimer/WarningThis is just my documentation for my repair. I don't claim that doing this is safe or recommended. Soldering irons are dangerous, be careful. Oh, and don't eat the solder.
William Dudley
|
![]() ![]() ![]() ![]() ![]() Views
|