PNI
/
BatteryESRTester
First working, tested and calibrated unit
Diff: main.cpp
- Revision:
- 0:197cfa57c3c7
- Child:
- 1:0d88cfafe20e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Mar 22 17:05:11 2017 +0000 @@ -0,0 +1,213 @@ +/* PULSED DISCHARGE BATTERY CAPACITY MEASUREMENT + +Note: The design intent was to calibrate each board rather than designing + and assembling precision analog circuits for each shield-board. + Use compile directive switch "CAL" in this firmware to perform test to + obtain calibration coeficients for each board. Place these obtained cal + coefficients in the CALIBRATION CONSTANTS section + + See ENG-1492 for more details and results + +**** Be sure to set the approriate BOARDNUMBER before compiling *********** + +*/ + + +#include "mbed.h" +#include "SDFileSystem.h" + +Serial pc(SERIAL_TX, SERIAL_RX); +AnalogOut DAC_Out(PA_4); // Connected to Gate of MOSFET +AnalogIn VRin(PA_0); // for Current Measurement +AnalogIn VBin(PA_1); // To measure battery Voltage +DigitalOut LED(D4); // Activity indicator +SDFileSystem sd(D11, D12, D13, D10, "sd"); // the pinout on the mbed Cool Components workshop board + + +// BOARD SPECIFIC CALIBRATION CONSTANTS +#define BOARDNUMBER 1 + +#if BOARDNUMBER == 1 +#define DAC100MA 35470 +#define I_SCALE 0.332386F +#define V_SCALE 3.314950F + + +#elif BOARDNUMBER == 2 + #define DAC100MA 35950 + +#elif BOARDNUMBER == 3 + #define DAC100MA 35950 + +#else + #define DAC100MA 35950 + +#endif + + + +// Parameters +#define PULSEWIDTH 0.099f +#define INTERVAL 0.599f +#define SLEWRATE 100 //10 is good for active testing, 100 for debugging +#define VBATTERY_MIN (3.00f) +#define TERMINATION_CURRENT (0.067f) +#define HYST (0.0001f) // temp comp hysteresis +#define GAIN 10000 // temp comp gain +char serial_inchar,waiting; + +void OnSerial(void) // serial port interrupt used in calibration mode +{ + serial_inchar = pc.getc(); + waiting = 0; + printf("%c:%d",serial_inchar,serial_inchar); +} + + +int main() { + float I,V,I_Target; + uint16_t DAC_Value = DAC100MA; + uint32_t count; + + DAC_Out.write_u16(0); + + pc.baud(115200); + printf("Pulsed Battery Discharger\n\r"); + pc.attach(&OnSerial); + LED = 0; + wait(1); + waiting = 1; + + +// FILE *fp = fopen("/sd/sdtest.txt", "w"); +// if(fp == NULL) { +// error("Could not open file for write\n"); +// } + +#if 1 // 0 = Calibration Mode, 1= Discharge test mode + + FILE *fp = fopen("/sd/BatteryLog.txt", "w"); + if(fp == NULL) { + error("Could not open file for write\n"); + } + + fprintf(fp, "I,V,count\n"); + printf("\n\rBattery Discharge Mode\n\r"); + I_Target = 0.100; + do { + + LED = 0; + DAC_Out.write_u16(0); + wait(INTERVAL); + LED = 1; + DAC_Out.write_u16(DAC_Value); + wait(PULSEWIDTH); + I = VRin.read()* I_SCALE; + V = VBin.read()* V_SCALE; + + fprintf(fp,"%1.3f,%1.2f,%d\n",I,V,++count); + //printf("%1.3f,%1.2f,%d\n\r",I,V,count); + + + // temperature compensation + if (I < (I_Target - HYST)) { + DAC_Value += (I_Target - I)*GAIN; + } + else if ( I > (I_Target + HYST)) { + DAC_Value -= (I - I_Target)*GAIN; + } + + + // If battery Voltage goes below BATTERY_MIN then reduce current + if (V < VBATTERY_MIN) { + if (I_Target > ( TERMINATION_CURRENT - (2.0*HYST))) { + I_Target -= 0.001; + } + } + + } while (I > TERMINATION_CURRENT && waiting); + + fclose(fp); + DAC_Out.write_u16(0); + printf("Done!\n\r"); + LED = 0; + + + +#else + //Perform Board Calibration + printf("\n\rCalibration Mode\n\r"); + waiting = 1; + while (pc.readable()) { // flush buffer + serial_inchar = pc.getc(); + } + printf("Set Vin to 3.20V then [press any key]\n\r"); + while(waiting == 1){ + wait(0.05); + } + printf("OK\n\r"); + wait(0.5); + V = VBin.read(); + + printf("Setting Current to 100mA\n\r"); + printf("Use +, -, *, / to adjust, q to end\n\r"); + + DAC_Value = 35550; + DAC_Out.write_u16(DAC_Value); + + waiting = 1; + do { + while(waiting){wait(0.01);} + printf("=%c",serial_inchar); + switch (serial_inchar) { + case '+': + DAC_Value += 10; + break; + case '-': + DAC_Value -= 10; + break; + case '*': + DAC_Value += 100; + break; + case '/': + DAC_Value -= 100; + break; + } + DAC_Out.write_u16(DAC_Value); + waiting = 1; + } while (serial_inchar != 'q'); + I = VRin.read(); + DAC_Out.write_u16(0); + printf("\n\rVIN VALUE: %f\n\rDACVALUE: %d\n\r,I in:%f\n\r",V,DAC_Value,I); + printf("Cut/paste this calibration into the calibration section...\n\r\n\r"); + printf("#define DAC100MA %d\n\r",DAC_Value); + printf("#define I_SCALE %fF\n\r",0.1/I); + printf("#define V_SCALE %fF\n\r",3.2/V); + printf("\n\r\n\r"); + + + // Validation test + float test_I_SCALE = 0.1/I; + float test_V_SCALE = 3.2/V; + while(serial_inchar == 'q') { + DAC_Out.write_u16(DAC_Value); + wait(INTERVAL+PULSEWIDTH); + I = VRin.read()* test_I_SCALE; + V = VBin.read()* test_V_SCALE; + + printf("%1.4f,%1.2f,%d\n\r",I,V,DAC_Value); + + // temperature compensation + if (I < (0.100 - HYST)) { + DAC_Value += (0.1 - I)*GAIN; + } + else if ( I > (0.100 + HYST)) { + DAC_Value -= (I - 0.1)*GAIN;; + } + + } + DAC_Out.write_u16(0); + +#endif + +} \ No newline at end of file