DIY Arduino Battery Capacity Tester - V1.0




Introduction: DIY Arduino Battery Capacity Tester - V1.0

About: I am a DIY hobbyist by passion and a Power Engineer by profession. Most of my works are related to Solar Energy and Arduino.

[ Play Video ]

I have salvaged so many old lap-top batteries ( 18650 ) to reuse them in my solar projects. It is very difficult to identify the good cells in the battery pack. Earlier in one of my Power Bank Instructable, I told, you how to identify good cells by measuring their voltages, but this method is not at all reliable. So I really wanted a way to measure each cell's exact capacity instead of their voltages.

Support me On Patreon:

If you enjoy my work here on Instructables, consider joining my Patreon, it will be a great help for me to make more interesting projects in the future.

Patreon Link:

Update on 30.10.2019

You can see my new version

A few weeks ago, I have started the project from the basics. This version is a really simple one, which is based on Ohms Law. The accuracy of the tester won’t be 100% perfect, but it does give reasonable results that can be used and compared with other batteries, so you can easily identify good cells in an old battery pack.

During my work, I realized, that there are a lot of things that can be improved. In the future, I will try to implement those things. But for the time being, I am happy with it. I hope this little tester will be useful, so I am sharing it with you all.

Note: Please dispose of the bad batteries properly.

Disclaimer: Please note that you are working with a Li-Ion battery which is highly explosive and dangerous. I cannot be held responsible for any loss of property, damage, or loss of life if it comes to that. This tutorial was written for those who have knowledge of rechargeable lithium-ion technology. Please do not attempt this if you are a novice. Stay Safe.

Step 1: Parts and Tools Required :

Parts Required :

1. Arduino Nano (Gear Best / Banggood )

2. 0.96" OLED Display ( Amazon / Banggood )

3. MOSFET - IRLZ44 ( Amazon )

4.Resistors ( 4 x 10K , 1/4W ) ( Amazon / Banggood )

5. Power Resistor ( 10R, 10W ) ( Amazon )

6. Screw Terminals ( 3 Nos) ( Amazon / Banggood )

7.Buzzer ( Amazon / Banggood )

8.Prototype Board ( Amazon / Banggood )

9. 18650 Battery Holder ( Amazon )

10. 18650 Battery ( GearBest / Banggood )

11. Spacers ( Amazon / Banggood )

Tools Required :

1. Wire Cutter / Stripper ( Gear Best )

2.Soldering Iron ( Amazon / Banggood )

Instrument Used :

IMAX Balance Charger ( Gearbest / Banggood )

Infrared Thermometer Gun ( Amazon /Gearbest)

Step 2: Schematic and Working

Schematic :

To understand the schematic easily, I have drawn it on a perforated board also. The positions of the components and wiring are similar to my actual board. The only exceptions are the buzzer and OLED display. In the actual board, they are inside but in the schematic, they are lying outside.

The design is very simple which is based on Arduino Nano. An OLED display is used to display the battery parameters.3 screw terminals are used for connecting battery and the load resistance. A buzzer is used for giving different alerts. Two voltage dividers circuit is used to monitor the voltages across the load resistance. The function of the MOSFET is to connect or disconnect the load resistance with the battery.

Working :

Arduino checks the battery condition, if the battery is good, give the command to switch ON the MOSFET. It allows current to pass from the positive terminal of the battery, through the resistor, and the MOSFET then completes the path back to the negative terminal. This discharges the battery over a period of time. Arduino measures the voltage across the load resistor and then divided by the resistance to find out the discharge current. Multiplied this by the time to obtain the milliamp-hour ( capacity ) value.

Step 3: Voltage,Current and Capacity Measurement

Voltage Measurement

We have to find the voltage across the load resistor. The voltages are measured by using two voltage divider circuits. It consists of two resistors with values 10k each. The output from the divider is connected to Arduino analog pin A0 and A1.

Arduino analog pin can measure voltage up to 5V, in our case the maximum voltage is 4.2V (fully charged). Then you may ask, why I am using two dividers unnecessarily. The reason is that my future plan is to use the same tester for the multi-chemistry battery. So this design can be adapted easily to achieve my goal.

Current Measurement :

Current (I) = Voltage ( V ) - Voltage drop across the MOSFET / Resistance (R)

Note: I am assuming the voltage drop across the MOSFET is negligible.

Here, V = Voltage across the load resistor and R = 10 Ohm

The result obtained is in amperes. Multiply 1000 to convert it into milliamperes.

So maximum discharge current = 4.2 / 10 = 0.42A = 420mA

Capacity Measurement :

Stored Charge ( Q ) = Current ( I ) x Time (T ).

We have already calculated the current, the only unknown in the above equation is time. The millis() function in Arduino can be used to measure the elapsed time.

Step 4: Selecting ​Load Resistor

The selection of load resistor depends on the amount of discharge current we need. Suppose you want to discharge the battery @ 500mA, then the resistor value is

Resistance ( R ) = Max Battery Voltage / Discharge Current = 4.2 /0.5 = 8.4 Ohm

The resistor needs to dissipate a bit of power, so size does matter in this case.

Heat dissipated = I^2 x R = 0.5^2 x 8.4 =2.1 Watt

By keeping some margin you can choose 5W. If you want more safety use 10W.

I used 10 Ohm, 10W resistor instead of 8.4 Ohm because it was in my stock at that time.

Step 5: Selecting the MOSFET

Here MOSFET acts like a switch. The digital output from the Arduino pin D2 controls the switch. When 5V (HIGH) signal is fed to the gate of the MOSFET, it allows current to pass from the positive terminal of the battery, through the resistor, and the MOSFET then completes the path back to the negative terminal. This discharges the battery over a period of time. So the MOSFET should be chosen in such a way that it can handle maximum discharge current without overheating.

I used an n-channel logic level power MOSFET-IRLZ44. The L shows that it is a logic level MOSFET. A logic level MOSFET means that it is designed to turn on fully from the logic level of a microcontroller. The standard MOSFET (IRF series etc) is designed to run from 10V.

If you use an IRF series MOSFET, then it will not fully turn ON by applying 5V from Arduino. I mean the MOSFET will not carry the rated current. To tuned ON these MOSFETs you need an additional circuit to boost the gate voltage.

So I will recommend using a logic-level MOSFET, not necessarily IRLZ44. You can use any other MOSFET also.

Step 6: OLED Display

To display the Battery Voltage,discharge current and capacity, I used a 0.96" OLED display.It has 128x64 resolution and uses I2C bus to communicate with the Arduino. Two pins SCL (A5), SDA (A4) in Arduino Uno are used for communication.

I am using U8glib library to display the parameters.First you have to download the U8glib library .Then installed it.

If you want to get started in to OLED display and Arduino , click here

The connections should be as follows

Arduino --> OLED

5V --->Vcc


A4----> SDA

A5----> SCL

Step 7: Buzzer for Warning

To provide different warning or alert, a piezo buzzer is used.The different alerts are

1. Battery Low Voltage

2.Battery High Voltage

3. No Battery

The buzzer have two terminals, the longer one is positive and the shorter leg is negative.The sticker on the new buzzer have also " + " marked to to indicate the positive terminal.

The connections should be as follows

Arduino --> Buzzer

D9--> Positive terminal

GND--> Negative terminal

In the Arduino Sketch, I have used a separate function beep() which sends the PWM signal to the buzzer, waits for a small delay, then turns it off, then has another small delay. Thus, it beeps once.

Step 8: Making the Circuit

In the previous steps, I have explained the function of each of the components in the circuit. Before jump to make the final board, test the circuit on a bread board first.If the circuit works perfectly on the bread board,then move to solder the components on the protype board.

I used 7cm X 5cm prototype board.

Mounting the Nano : First cut two rows of female header pin with 15 pins in each.I used a diagonal nipper to cut the headers.Then solder the header pins.Be sure the distance between the two rails fits the arduino nano.

Mounting OLED Display : Cut a female header with 4pins. Then solder it as shown in picture.

Mounting the terminals and components : Solder the remaining components as shown in pictures

Wiring : Make the wiring as per schematic.I used colored wires to make the wiring, so that I can identify them easily.

Step 9: Mounting the Standoffs

After soldering and wiring,mount the standoffs at 4 corners.It will provide sufficient clearance to the soldering joints and wires from the ground.

Step 10: Software

The software doing the following tasks

1. Measure voltages

Taking 100 ADC samples , adding them and averaging the result.This is done to reduce the noise.

2. Check the battery condition to give alert or start the discharge cycle


i) Low-V! : If the battery voltage is below the lowest discharge level ( 2.9V for Li Ion )

ii) High-V! : If the battery voltage is above the fully charged condition

iii) No Battery! : If the battery holder is empty

Discharge Cycle

If the battery voltage is within the low voltage ( 2.9V )and high voltag (4.3V),discharge cycle start.Calculate the current and capacity as explained earlier.

3. Display the parameters on the OLED

4. Data logging on serial monitor

Download the Arduino Code attached below.

Step 11: Exporting Serial Data and Plotting on Excel Sheet

To test the circuit, first I charged a good Samsung 18650battery using my IMAX Charger. Then put the battery into my new tester. To analyze the entire discharge process, I export the serial data to a spreadsheet. Then I plotted the discharge curve. The result is really awesome. I used a software named PLX-DAQ to do it. You can download it here.

You can go through this tutorial to learn how to use PLX-DAQ. It is very simple.

Note: It works only in Windows.

Step 12: Conclusion

After few testing I conclude that the tester result is quite reasonable.The result is 50 to 70mAh away from a branded battery capacity tester result.By using a IR temperature Gun, I measured the temperature rise in the load resistor also,the maximum value is 51 deg C.

In this design the discharge current is not constant, it depends on battery voltage.So the discharge curve plotted is not similar to the discharge curve given in the battery manufacture data sheet.It only support a single Li Ion Battery.

So in my future version I will try solve the above short comings in the V1.0.

Credit : I would like to give credit to Adam Welch, whose project on YouTube was inspired me to start this project.You can watch his YouTube video.

Please suggest any improvements.Raise a comments if any mistakes or errors.

Hope my tutorial is helpful.If you like it,don't forget to share :)

Subscribe for more DIY projects. Thank You.

Maker Olympics Contest 2016

Participated in the
Maker Olympics Contest 2016

29 People Made This Project!


  • For the Home Contest

    For the Home Contest
  • Game Design: Student Design Challenge

    Game Design: Student Design Challenge
  • Make It Bridge

    Make It Bridge



Question 2 years ago on Introduction

can i use higher rated power resistor instead of load resistor? FOR EXEMPLE DECADE BOX?


3 years ago

How can i measure 12V battery And what changes in circuit And code plsss help me


Reply 3 years ago

The Arduino analog in pins have a readable range of 0-5V, so you will need to make sure you never connect the pin to higher than 5V. This is done with a potential divider. If you used 20k and 10k divider, read across the 10k and it will never exceed 4V, hence is suitable to be read by the Arduino. Then you will need to change the variables and math in the code to account for this. Also be sure that the currents in your circuit are suitable, they will be greater with your 12V battery.


Question 3 years ago on Step 10

Hi! Works perfect! Removed resistors, changed a few rows in the program also for that. But the problem I found - not working when disconnected from my PC, have no idea.... With only external Arduino power - starts process and stops at 50mah, sometimes 100mah.... Programmed 328P only separate, same issue. Any idea why is it so?


Question 3 years ago

How to log data?


Question 3 years ago

Hi. Is it possible just to meassure the voltage of a 18650 battery using any of the analog pins? Do I still need a voltage divier? Since Arduino can measure up to 5V I don't think it is necessary, but just want to make sure. Thanks!


Answer 3 years ago

You are right. You can directly hook up to the analog pin


5 years ago

Hi; I don't have 10 Ohm, 10W resistor. Can I use 10 Ohm, 11W resistor instead? Or should I use 2 pcs 10 Ohm, 5W resistors with parallel connection? I want to use 11W resistor if the results won't change.



Reply 3 years ago

Merhaba 11w kullanmak herhangi bir fark yaratmayacaktir.
W=i.v idi 1amper verceegimizi düşünürsek ve pilde max4.2v degerimiz var bu durumda yaklaşık en az 5wattlik bir direnç bu iş için ideal olacaktır.
Daha yukarı wattli bir direnç daha dayanıklı olacaktır:) ben de dirençi alırken sordum 10 11 arası ne fark var diye ohmlari aynı ise devre üzerinde bir fark olmaz dediler.
Bu arada siz yaptınız ve kullanabildiğiniz mi?
Ben sürekli high voltage uyarısı alıyorum://
Bağlantıları mi yapamadım anlamadım:/


Reply 3 years ago

Merhaba, evet yaptım. Yorumlardan birisinde vardı, 2 adet ground bağlantısı eksik kalmış. Gönderdiğim görselde kırmızı ile yazdığım j6 ve k8 pinlerinin toprak bağlantılarını kontrol edin. Bende bu bağlantılardan sonra bahsettiğiniz aorun düzelmişti. Bu arada cevabınız için teşekkürler...


Reply 3 years ago

Ben çok teşekkür ederim. Yorumlara bakarken görmüştüm ama (cidden acemilik zor) ben sadece bir tane toprak bağladım ve gene aynı hatayı vermeye devam etmişti :). bir de fritzing şemasında toprağa bağlanmıyor ama diğer şemada toprak bağlantısı var. Acemi olunca vardır bir bildiği dedim geçtim ve hata verdi. :D
Sayenizde bugün tamamlayacağım. Çok teşekkür ederim, ayrıca elinize sağlık.


Reply 3 years ago

Önemli değil, umarım siz de sorunu çözersiniz. Bende de başlangıçta çalışmadı, bağlantıları kontrol etmek için ilk resimdeki şemayı çizip bağlantıları tek tek yazmıştım ama sonuçta o yorum sayesinde çözebildim :)

Bu arada bunu yazmak ne kadar doğru olur bilmiyorum ama pil kapasitesi ölçümü için ZB206 v1.3 sürümünü malum sitelerden birisinden satın aldım, çok başarılı buldum. Bunu da tavsiye edebilirim. Seçenek olarak aklınızda bulunsun istedim :) Ben de elektronik konusunda uzman değilim ama çok eğlenceli kesinlikle :)


Reply 3 years ago

Zb206'yı bilmiyordum başka versiyonları duydum ama malum ne zamana gelir diye ve birde belki kendim de yapabilirim diye buna yöneldim. Ancak bir tane de bundan alacağım.
Bu arada iki sorum olacak; bu pil testi düzeneğine aynı anda birden çok pil testini nasıl yaptırırız? Mesela 3 pili test etsin istiyorum ama tek arduino ile mevcut donanımı 3 ile çarpıp (yazılımı da 3kez tekrarlayıp portları da ona uygun değiştirsem ) düzeneği kursam hepsini tek ekrandan nasıl göstertebiliriz acaba? fikriniz var mı ?
Bir diğer sorum da j6 ve k8 normalde birbirine bağlı o bağlantıyı koparıp her birini ayrı ayrı mı topraklayacağım yoksa bağlantı kalacak ve her bir direnç çıkışını tek tek mi topraklayacağım.
Teşekkür ederim yeniden.


Reply 3 years ago

Zb206'nın güzel yanı istenilen akım miktarında deşarj yapabiliyor (yeterli soğutmayı yapmak şartıyla). Bir de buna benzer ucuz olan ZB2L3 var ama onu tavsiye etmiyorum, çünkü onda akımı ayarlamak için direnç miktarını değiştirmek lazım. ZB206'da bu işlemi kendisi hallediyor.

Arduino dışında tüm donanımlardan 3 adet gerekecek, analog portlar 3 pile yeter gibi görünüyor ama yazılımı güncellemek zor olabilir (şu anda tek pile ait veriler ekranda sürekli güncelleniyor. Birden fazla pil olursa ayrı bir alt yordam hazırlanıp, örneğin her pilin verisini 2 sn göster diğerine geç demek lazım. Buna benzer başka şeyler de çıkabilir tabii). Ayrıca kazara devrede gözden kaçan bir durum (pillerin artı ve eksi hatlarının aynı yola bağlanması gibi) soruna yol açabilir. Bence tek pille yola devam etmek en iyisi. Pratikte yapılabilir gibi görünüyor ama harcanan emek ve zamana değer mi değmez mi konusu tartışılır :)

J6 ve K8 arası bağlantıyı koparmaya gerek yok, sadece o hattı topraklamak yeterli. Zaten bağlantıyı koparsak da, koparmasak da her türlü toprak hattında birleşecekler. Bu nedenle koparmaya gerek yok.

Kolay gelsin,


6 years ago

UPDATE, Used different Oled and it is working. Reads high V, and No Battery, I would think if it is reading high V that it would start capacity test but just keeps beeping?


Reply 3 years ago

Hı i am also getting this mesaage . How did you solve the problem:((


Question 3 years ago

Hi! If i used 12V VRLA (battery), what the components should be added?


Reply 3 years ago

I want to try it out too :)