PNI
/
BatteryESRTester
First working, tested and calibrated unit
main.cpp
- Committer:
- JoeMiller
- Date:
- 2017-03-22
- Revision:
- 0:197cfa57c3c7
- Child:
- 1:0d88cfafe20e
File content as of revision 0:197cfa57c3c7:
/* 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 }