This circuit is a battery characterizer that applies a fixed load to a charged NiCad or NiMH cell and measures milliamp-hour capacity as it discharges.
There is no single load that can be applied to a battery to measure milliamp-hours. It depends on the battery type, it’s intended application, etc. This device is simply one methodology that gives me a relative idea of the performance of NiCad and NiMH batteries in my drawer. Discharge is approximately 200mA which is approximately 0.1C for AA size cells or packs constructed with AA size cells.
When NuMH¹ batteries come into being, I’ll update this device to handle those too.
- Up to five cells can be characterized at one time
- To avoid total discharge the load is disconnected when test stops
- Determines internal resistance and accumulated milliamp-hours.
- Power: 8-16VDC at ~100mA
- Sampling: once per minute
- Load 0.1C (~200mA)
Connect an 8-16VDC power supply to the battery characterizer.
Insert the cell(s) or connect the battery pack to be tested. After a charged cell is inserted in a socket, the unit waits for the voltage to stabilize (to avoid false measurements during first contact,) then the internal resistance is measured for later display when the cell test is complete. Thereafter, the cell is placed in TEST mode, the load is turned on, and milliamp-hours are accumulated. When the cell voltage falls below the cutoff voltage (1.0V per cell,) TEST mode is terminated and the load is turned off. DONE mode thereafter displays the total milliamp-hours and starting internal resistance until the cell is removed from the socket.
Socket #5 is designed for multiple-cell packs. The number of cells is calculated from the initial measured charged voltage and is in turn used to calculate the proper cutoff voltage by dividing by the nominal 1.2V per-cell voltage.
/**************************************************************************** BCHAR18.C This is a battery characterizer for NiMH and NiCD cells. Four 5V ADC inputs (1.2V cells) and one 8V input (3.6 or 4.8V cells) collect samples. Control and display is done via two pushbuttons and an LCD display. Menus and results are viewed on the display. WORKING CODE Next: put in overvoltage sense --------- +5--20-|Vdd | +5---1-|Mclr | Gnd---8-|Vss | Gnd--19-|Vss | 4MHz--10-|Xtal | 4MHz---9-|Xtal | | | | | SOCKET 1 --2-|AN0 B4|-24----load 0 FET gate SOCKET 2 --3-|AN1 B3|-24----load 1 FET gate SOCKET 3 --4-|AN2 B2|-23----load 2 FET gate SOCKET 4 --5-|AN3 B1|-22----load 3 FET gate SOCKET 5 --7-|AN4 B0|-21----load 4 FET gate | | SW 1 ----28-|B7 | | | | | --------- | C2|-13--11-|D4 | | C3|-14--12-|D5 | | C5|-16--13-|D6 | | C4|-15--14-|D7 | | | | |-3--20K pot (contrast) | C1|-12---6-|EN | | C0|-11---4-|RS | | | | | | | +5-2-| | | | Gnd-1-| | | 18F252 | Gnd-5-| | | | | DISPLAY | --------- --------- */ #include < 18f252.h > #device *=16 ADC=10 /* allow RAM addresses over 255 */ #include < jonsinc.h > #fuses XT, NOPROTECT, NOOSCSEN, BROWNOUT, NOWDT, BORV20, PUT, NOSTVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB //============================================================= // crystal frequency (Hz) #define CRYSTAL_FREQ 4000000 // actual power supply voltage (volts) #define VDD 5.02 // cell nominal voltage (volts) #define CELL_NOM_VOLTAGE 1.2 // voltage at which mAh accumlation stops (volts) #define CUTOFF_VOLTAGE 1.0 // actual load resistances (ohms) #define LOAD_0_OHMS 4.9 #define LOAD_1_OHMS 4.9 #define LOAD_2_OHMS 4.9 #define LOAD_3_OHMS 4.9 #define LOAD_4_OHMS 19.5 // actual FET RDS(on) resistance (ohms) #define FET_RDS_OHMS 0.17 // actual scaling resistors R1 and R2 for channel 5 (ohms) #define R1 5350 #define R2 10220 // display time for logo screens (normally 750 mS) #define LOGO_TIME 750 // wait time for which voltage is displayed after a cell is inserted into a socket (seconds) #define INITIAL_DELAY 2 // wait time after which display goes into rolling status mode (seconds) #define STATUS_DELAY 10 // screen cycle time when in rolling status mode (seconds) #define SCREEN_CYCLE_DELAY 2 // screen cycle time when in cell detail mode (mS) #define DETAIL_CYCLE_DELAY 1500 // restart IRQ timer at adjusted value for 1-second accuracy (0-255, higher makes shorter IRQ tick) #define IRQ_RESTART_TICK 3 // time at cutoff voltage required to end test (seconds, normally 60) #define AUTOSTOP_TIME 60 // button time after which unit will display cell details (31mS interrupt counts, normally 16, ~= 0.5 second) #define BUTTON_DETAIL_TIME 16 // button time after which unit will reset (31mS interrupt counts, normally 128, ~= 4 seconds) #define BUTTON_RESET_TIME 128 // round to nearest 10's or 100's #define ROUNDNUM 100 // socket definitions #define SOCKET_1 0 #define SOCKET_5 4 // overvoltage definitions #define CH_1_4_OVERVOLTAGE 2.0 #define CH_5_OVERVOLTAGE 6.0 //============================================================= // LCD STUFF #define LCD_D0 PIN_C2 #define LCD_D1 PIN_C3 #define LCD_D2 PIN_C5 #define LCD_D3 PIN_C4 #define LCD_EN PIN_C1 #define LCD_RS PIN_C0 #define LOAD_0 PIN_B4 #define LOAD_1 PIN_B3 #define LOAD_2 PIN_B2 #define LOAD_3 PIN_B1 #define LOAD_4 PIN_B0 #define BUTTON PIN_B7 #define OHM_SYM 0xF4 #define FIRST_LINE 0 #define CLEAR_DISP 0x01 #define CELL_STATE_READY 'R' #define CELL_STATE_TEST 'T' #define CELL_STATE_DONE 'D' #define FMULT ( float ) R1 / ( float ) ( R1 + R2 ) // sample interval is normally 60 seconds #define SAMPLE_INTERVAL_SEC 60 #use delay ( clock=CRYSTAL_FREQ ) #use standard_io ( A ) #use standard_io ( B ) #use standard_io ( C ) separate void DelayMs ( long cDelay ); // prototype statements separate long Round ( float fNum, int cNearest ); float ReadAdc ( unsigned int cChannel ); void LoadControl ( char cChannel, char cState ); void LCD_Init ( void ); void LCD_SetPosition ( unsigned int cX ); void LCD_PutChar ( unsigned int cX ); void LCD_PutCmd ( unsigned int cX ); void LCD_PulseEnable ( void ); void LCD_SetData ( unsigned int cX ); static char cCellDetailWanted, cSwitchCount, cInitialDelayCount; static char cInterruptCount1s, cInterruptScreenCycleCount; static long iInterruptStatusCount, iRunMinutes [ 5 ]; static char cSocket, cSocketDisp, cY, cSkip, cStatusMode; static char cLogging [ 5 ], cAutoStopCount [ 5 ], cCellCount [ 5 ]; static char cSampleCount [ 5 ], cCellPresent [ 5 ]; static char cSocketState [ 5 ], cSampleFlag [ 5 ], cIntResCount [ 5 ]; static float fIntRes [ 5 ], fLoadRes [ 5 ], fAccumMa [ 5 ]; static float fCutoffVoltage [ 5 ], fMultiplier [ 5 ], fOverVoltage [ 5 ]; static float fStartVoltageUnloaded [ 5 ], fStartVoltageLoaded [ 5 ]; static float fPresentVoltage [ 5 ]; //************************************************************************
For more detail: BATTERY CHARACTERIZER using PIC18F252
Current Project / Post can also be found using:
- pic based battery charger circuit