Minimalist Li-Ion Discharger/Capacity meter.

What you need to grade your scavenged cells for building balanced packs.

Similar projects worth following
I needed a cell discharger for the 18650's I'm using for the Mountain board project to grade them. I decided to build one. This is it.

Independently discharges up to 4 cells with programmable constant current.
Standalone use if you add the display, or use USB-serial and skip the display as well.
No controls. Cell voltage tells it what to do.

Simple circuit. You need a 5V Arduino Nano. Then for each cell (up to 4) you need one logic level N channel mosfet, and one 3 Ohm 10W resistor (or some nichrome wire/fan)

Put in a cell. Wait. Read out the mAh. Put in the next cell.

Put a cell in backwards, and prepare to buy yourself a new Nano. :)

What is this for?

Li-Ion battery packs are arranged with cells in parallel to increase current, and then groups of those in series to increase voltage.  So a 10s5p pack has 5 cells in parallel, and 10 sets of those in series.  

To build a battery pack that you can charge and discharge quickly, it has to be balanced.   The total mAh capacity for each parallel bank of cells needs to match the total mAh capacity of every other parallel bank of cells.  Why building a balanced pack matters..  

Fully charging and then discharging each cell at a known rate will give you the capacity.  Then you can just play matchmaker to build your balanced pack.  This is the discharger which gives you those used cell capacity numbers. 

Constant current, mostly..

Normally as the battery voltage drops off, so would the current provided by a fixed value load resistor.  This discharger monitors the current, and then adjusts the PWM duty cycle as need to maintain the target current.  Current is directly measured as the voltage drop across the load resistor, so this consumes 2 ADC channels per cell. 

The 3 ohm value of the load resistor was chosen to provide the target discharge current of 1A at the cutoff voltage of 3.0V.  So over the voltage range of a fully charged cell to a fully discharged cell, this results in PWM tracking from about 80% to 100%.  Doing true DC constant current just takes a couple more components, but this then runs the mosfet in the linear range instead of switching.  That produces a *ton* of heat.  I prefer cheating.

You set the target discharge current and the starting PWM level in the .ino file.  You will still need to calibrate for accurate results.


Discharging starts when you insert a cell. Cell voltage and accumulated mAh are displayed while discharging.

Discharge is stopped when a cell is discharged to 3V (or whatever you set) and the capacity in mAh is displayed.  For a good cell, discharging takes about 2 hours.

Discharging will not restart again until the cell is removed to prevent cell recovery from starting another cycle. 


I'm sampling values which are directly connected to a running PWM source, so the input to the ADC is essentially one of two levels. To compensate for this and still get my desired analog reading, I'm oversampling the ADC inputs by a factor of 100x and then averaging.  Works.


There is no protection for reverse hookup, the mosfet gates are directly connected to the Nano with no pulldown resistors to prevent 'floating' inputs if turned off, the ADC pins are directly exposed to whatever you plug in... etc.  There are tons of ways to improve this.  That being said, as long as you don't put the cells in backwards, everything should work just fine for the foreseeable future.  Eventually you will screw up and destroy the Nano.  Twenty minutes later you will have a new one in its place.

This project is all about turning battery power into heat, and will need to continuously dissipate 12W.  Make sure you have somewhere for that heat to go.  Discharging at just 1A can still cause 'bad' cells to heat up, which can turn them into little rockets.  I added the fans to keep my nichrome wire load resistors cool, but keeping the batteries cool isn't a bad idea either.  Be safe.

... Read more »

x-arduino - 7.95 kB - 01/30/2019 at 02:50


  • 1 × Arduino Nano 5v
  • 4 × Logic level N channel power mosfet
  • 4 × 3 Ohm 10W resistor I used nichrome wire, bu power resistors would be better..
  • 1 × 4 digit LED display (optional)
  • 1 × Hookup wire

View all 8 components

  • Schematic for Discharger

    KSUdoubleE11/06/2019 at 18:44 4 comments

  • Resistance is futile, or small at least.

    Daren Schwenke02/13/2019 at 20:25 0 comments

    The cells have some internal resistance as well, usually on the order of 0.2 Ohms or so.  Sometimes a lot higher.

    The higher it is, the more the cell wastes power and heats up during charging and discharging.

    I went looking and I believe I can measure the internal cell resistance with my current rig, but it will require some code changes.  It basically involves shutting off the load resistor, measuring the voltage, turning it on 100%, measuring the voltage drop inline with my known resistor, and then calculating the missing resistance.  You have to do this quickly so you can negate the cell discharging during the measurement.

    The code currently doesn't handle intermittent discharging as it relies on a constant rate being kept from one cycle to the next and so this would throw off the numbers.  

    On the todo list.

  • Theory becomes fact.

    Daren Schwenke02/08/2019 at 21:23 0 comments

    I inadvertently confirmed today that if you plug in a cell backwards you indeed do need to buy yourself a new Nano.  :)   Still works, but voltage calibration is way off and seems to bleed between channels.  I messed up the ADC for sure.

    In other news, I built a 10 slot 1A charger so I can charge the cells now at least as fast as I can discharge them.  Looks good and works well, but two of my charger modules were DOA so that is waiting to become a Project for now.


    Replaced the Nano.  Everything else survived.

    Also got the replacement USB charger modules in today, and put them in.  Cell charger project complete.


  • Everything old is new again.

    Daren Schwenke02/06/2019 at 18:54 0 comments

    Still continuing to cycle the cells a second time.  Still all going up in mAh value, save one which went down 30mAh.

    10 cells left to do.

    Ordered some Li-ion charger PCB and 18650 battery holders from Amazon.  Both were 10 for $9, and will let me charge 10 at a time, at 1A.  That should give me some more options for cycling cells I'm questioning, without being so darn slow.

    <EDIT>  Cell charger done.   I wish I had done that way sooner... </EDIT>

    Also built a cell welder and tested it.

    Works well, but you have to be careful to keep the pulse duration short, as shown on my test cell here where I burned through.

  • Balancing - Brute force fail, website success.

    Daren Schwenke02/05/2019 at 20:05 0 comments

    While I'm waiting for all my cells to cycle a second time, I've been messing around with some scripts for sorting the cells.

    I started to write a little python script to calculate all the possible combinations of the cells, to basically randomly seek cell groups of 5 which most evenly match them.

    import itertools
    files = open("cells.txt")
    cells = []
    for line in files:
    perm_iter = itertools.permutations(cells)
    for item in perm_iter:
        groups = itertools.izip(*[itertools.islice(item, i, None, 5) for i in range(5)])
        print list( itertools.imap(sum,groups) )

    I never got beyond printing them, because from what I can tell, this would take until the heat death of the universe to finish.  In 10 minutes it tried only the combinations for the first 2 groups.  The results are returning in lexicographical order as well, so even randomly stumbling upon the right answer would take nearly until the end.

    I also tried just iterating through the list, with just dumb grouping of the strongest with the weakest and meeting in the middle.  That was fast, but since the cell values were not linear... not perfect.

    I think I'll need to be a bit more directed in my search.  I'm sure there is something in between that will work.  Just gotta find it.  Or I could just do an acceptable job manually in about 5 minutes, but this is more fun.

    Feel free to offer suggestions on a script to generate my matched sets of 5.  :)


    I posed this question at the local hackerspace Facebook page, and Daniel Near suggested this:

    You paste your list of capacities as a CSV, enter the serial and parallel configuration desired, and...

    That is just perfect.  One less thing to do.


  • Cell recovery and cycling.

    Daren Schwenke02/04/2019 at 01:12 0 comments

    Cycling the cells at least twice seems to be key to getting a stable capacity value.

    This is likely due to some of them being at 2.8v when I got them.  That's below the maximum recommended discharge voltage of 3.0v and likely due to them sitting in a discharged state for an extended period of time before they arrived at my desk.  

    Although the majority seem to have recovered fine from this, it took 2 cycles to bring them back up to their new maximum capacity.  I'm sure they all lost some capacity in the process, but they are still usable.

    I fully cycled all the low scoring cells at least twice and most recovered about 100mAh of capacity in the process.

    For kicks, I tried cycling a few a third time.  This resulted in a maximum 25mAh gain, and two even lost a few mAh.  Twice seems to be the number.


    I've been moving on up from worst to best cycling them all a second time.  The second cycle improvement numbers show no sign of stopping.  The latest two cells went from 1974 to 2130 and 1976 to 2113.  I'm going to have to do them all for my own sanity.

    I need a good high amp charger so I can do them in parallel, or at this rate cycling them all again with my 2 cell desktop charger will take 168 hours.  Ooof.

    You can charge pretty much as many cells as you want in parallel.  I'm not sure I fully understand how to do the charging properly though.  What I read so far is... start out at constant current or 0.5-1.0C, at some point switch to constant voltage when you hit 4.20-4.25V, and then stop the charge when charge current drops to < 3% of C.  Now how to do that in hardware...


  • All the knobs go to 11.

    Daren Schwenke02/01/2019 at 03:25 0 comments

    I was down to the last 6 remaining cells to test.  Charged, and in the process of discharging.. almost done.

    Then the power went out.  I was testing a cell welder.  Word of advice.... Don't run a space heater on the same circuit as your home-brew cell welder.  Duh...

    So I charged those cells all the way back up, and discharged them again.  Unfortunately I remembered the approximate capacity numbers from when it terminated.

    They are all coming in at about 200 mAh higher on the second cycle than they would have on the first.  I noticed this earlier on some of the other low-scoring cells also...

    <EDIT>  Ok, not all of them are increasing, so I'm a little less paranoid now.  I'll probably still complete this task.

    EDIT again... Two only increased slightly.  Two others went up by 100mAh.  Cycling more of them has resulted in all the low scoring cells going up 10-200mAh on the second cycle.. Too many variables....  I should just cycle all of them again and be done with it.


    This is not a problem with the capacity meter.  However, it likely means I will need to cycle about 1/3 of the cells again to make sure they are back to their actual capacity.  Now that I'm charging them in my two slot desk charger, and not all at once (temporarily wired into the BMS with a huge power supply), that is going to take forever.

    But... I gotta do it.  Doing it.

  • The bad cell black hole.

    Daren Schwenke01/31/2019 at 19:32 0 comments

    A curious thing has happened on a few cells.  They would start discharging normally, then disappear.

    Well, not physically, although that would be a lot more exciting.  Sadly, no fireworks since I built this version of the discharger.

    They dropped into a logic area I didn't account for.  What that is, I have yet to look for.  But I know the display stops updating for them, and when I take them out the cell voltage is lower than the ending voltage.  

    Given I just started the discharge, those cells are obviously toast, but they should be sitting in 'Done'.  

    I missed something.

    Looking at it.

  • Logging and startup current fixes.

    Daren Schwenke01/30/2019 at 02:50 0 comments

    I rearranged the start sequence and serial logging so it makes more sense while starting up.

    I also eliminated the bug where discharging starts at 100% load.  You can now set the start PWM level.

    int Start_PWM = 200; // Starting value for PWM before current control kicks in. 0-255

    While I was at it, I attributed the original article in the source.

    New source is up.

  • Credit, where it is due.

    Daren Schwenke01/29/2019 at 20:54 0 comments

    I started with someone else's code and wiring first.  I went back and found that project, so I could include it here now.

    There is not much in the original code that has stayed the same, but starting with something working was a head start. I still need to attribute it yet.

    • The math was simplified, fully switched to integers, and then largely switched back as I was just being anal about using so many floats.  Works fine, why mess with it.
    • A logical state now controls operational state.  This prevents cells from restarting a cycle by recovering, and clears the associated math bits when it does restart one.
    • Display and serial code was gutted and re-written.
    • PWM current control was added.
    • Converted to do 4 channels.
    • The hardware was stripped down to just what was needed, but was basically already exactly the way I would have done it.  The original is no safer, and does little better at protecting the Nano.  It also sacrifices half the ADC resolution to do it.  Minimal it is.  :)

View all 14 project logs

Enjoy this project?



KSUdoubleE wrote 10/24/2019 at 14:44 point

Nice!  I am running this right now.  Just a couple of suggestions on the hand drawn schematic.  The symbol is correct, but it looks like the S and D identifiers are swapped?  Also, D9 controls the PWM for analog inputs A0/A1.  Thanks for posting this project

  Are you sure? yes | no

Daren Schwenke wrote 10/24/2019 at 16:02 point

Bah.  You are right, they are swapped.  If you want to take the time to generate a proper schematic, I'll add you as a contributor..  :)

  Are you sure? yes | no

KSUdoubleE wrote 11/05/2019 at 22:59 point

It's the least I can do, I'll toss something together.

  Are you sure? yes | no

jno wrote 09/25/2019 at 11:17 point

Hello, can I ask how you avoid to get parasitic voltage on Analog pins where there is no battery ? For example If batteries pins are A0, A1, A2 : when I have no battery, all parasitic voltages are < 1.5V . But if i plug only 1 battery, for example on A0, I get high parasitic both on A1 & A2 (A1 is near A0 !), so the program manage it like if there is a battery. Did I miss something ? Tks !

  Are you sure? yes | no

Daren Schwenke wrote 11/06/2019 at 22:01 point

I don't get that effect.  It may just be down to the particular Nano I am using.  I'm sure adding some high value resistors (10k-100k) would eliminate the issue without affecting the measurement too much.

I did have a little issue with the ADC lines floating when not connected to anything and the mosfet was just left open.  I solved that in software later on by adding a brief period of the mosfet being on every cycle.

  Are you sure? yes | no

furkosborks1 wrote 02/19/2019 at 04:36 point

Can I ask how did you managed to fit all components ?

Display segments requires 7 digital pin

Display power requires 4 digital pin 

Arduino have 12 digital pins but you also add 4 MOSFETs  so in my calculation you used 15 digital pin while arduino only has 12 what is your secret ?

Also could you send me the circuit diagram ? 

By the way I really like your circuit style , you build it with spare parts but I notice something in your circuit current seem to be too high of course fans will solve the heating problem but if I understand correctly in high current battery capacity numbers lower than usual .

  Are you sure? yes | no

Daren Schwenke wrote 02/21/2019 at 07:33 point

Display is 2 pins.  It's not exactly I2C, but is really close to I2C.  You can pretend it is I2C.

If you allowed the nichrome wire to heat, it would alter the value.  Yes.  Keep it within 20 degrees of ambient and you can ignore this.

The circuit diagram is literally the drawing I posted,  times 4. A mosfet, a resistor, and hook to the Arduino in three spots.  The spots to hook are in the code, as arrays.  Position 0 in the three arrays are for cell 1.  Position 1 in the three arrays are for cell 2, and so on.  The drawing:

Later I added the display, but those 2 pins I think you can figure out.

  Are you sure? yes | no

Daren Schwenke wrote 10/24/2019 at 21:31 point

If there ever is a circuit diagram, it will show up here.  :)

The ~1A discharge rate used here is a good trade-off.  Not so high as to cause excessive cell heating, but not so low as to have you waiting hours to get your metrics.  

The usual discharge curves start to get a lot shorter when you exceed 2C.  The 1A rate used here is ~0.5C discharge rate for these cells.  These are not high discharge rate cells either, so the curve would probably be worse.  In practice, the mountain board will probably be drawing 1-2C from each cell.

  Are you sure? yes | no

Dan Maloney wrote 01/28/2019 at 16:14 point

Pretty slick. Are the 10 ohm load resistors just the lengths of wire I see next to the cells on the perfboard?

  Are you sure? yes | no

Daren Schwenke wrote 01/28/2019 at 16:45 point

3 ohms, and yes.  

At the lower cutoff voltage of 3.0V, my PWM has then scaled back up to 100% duty cycle to maintain the desired 1A discharge rate.

If you got an actual resistor, use it.  Nichrome is a PTC metal and so you *have* to keep it cool.  If you don't, the resistance value will change and throw off the current measurement. 

  Are you sure? yes | no

Dan Maloney wrote 01/28/2019 at 17:46 point

D'oh! 3 ohm, 10 watt. Gotcha!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates