First working, tested and calibrated unit

Dependencies:   mbed USBDevice

Committer:
JoeMiller
Date:
Wed Mar 22 17:05:11 2017 +0000
Revision:
0:197cfa57c3c7
Child:
1:0d88cfafe20e
Initial trial test complete

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JoeMiller 0:197cfa57c3c7 1 /* PULSED DISCHARGE BATTERY CAPACITY MEASUREMENT
JoeMiller 0:197cfa57c3c7 2
JoeMiller 0:197cfa57c3c7 3 Note: The design intent was to calibrate each board rather than designing
JoeMiller 0:197cfa57c3c7 4 and assembling precision analog circuits for each shield-board.
JoeMiller 0:197cfa57c3c7 5 Use compile directive switch "CAL" in this firmware to perform test to
JoeMiller 0:197cfa57c3c7 6 obtain calibration coeficients for each board. Place these obtained cal
JoeMiller 0:197cfa57c3c7 7 coefficients in the CALIBRATION CONSTANTS section
JoeMiller 0:197cfa57c3c7 8
JoeMiller 0:197cfa57c3c7 9 See ENG-1492 for more details and results
JoeMiller 0:197cfa57c3c7 10
JoeMiller 0:197cfa57c3c7 11 **** Be sure to set the approriate BOARDNUMBER before compiling ***********
JoeMiller 0:197cfa57c3c7 12
JoeMiller 0:197cfa57c3c7 13 */
JoeMiller 0:197cfa57c3c7 14
JoeMiller 0:197cfa57c3c7 15
JoeMiller 0:197cfa57c3c7 16 #include "mbed.h"
JoeMiller 0:197cfa57c3c7 17 #include "SDFileSystem.h"
JoeMiller 0:197cfa57c3c7 18
JoeMiller 0:197cfa57c3c7 19 Serial pc(SERIAL_TX, SERIAL_RX);
JoeMiller 0:197cfa57c3c7 20 AnalogOut DAC_Out(PA_4); // Connected to Gate of MOSFET
JoeMiller 0:197cfa57c3c7 21 AnalogIn VRin(PA_0); // for Current Measurement
JoeMiller 0:197cfa57c3c7 22 AnalogIn VBin(PA_1); // To measure battery Voltage
JoeMiller 0:197cfa57c3c7 23 DigitalOut LED(D4); // Activity indicator
JoeMiller 0:197cfa57c3c7 24 SDFileSystem sd(D11, D12, D13, D10, "sd"); // the pinout on the mbed Cool Components workshop board
JoeMiller 0:197cfa57c3c7 25
JoeMiller 0:197cfa57c3c7 26
JoeMiller 0:197cfa57c3c7 27 // BOARD SPECIFIC CALIBRATION CONSTANTS
JoeMiller 0:197cfa57c3c7 28 #define BOARDNUMBER 1
JoeMiller 0:197cfa57c3c7 29
JoeMiller 0:197cfa57c3c7 30 #if BOARDNUMBER == 1
JoeMiller 0:197cfa57c3c7 31 #define DAC100MA 35470
JoeMiller 0:197cfa57c3c7 32 #define I_SCALE 0.332386F
JoeMiller 0:197cfa57c3c7 33 #define V_SCALE 3.314950F
JoeMiller 0:197cfa57c3c7 34
JoeMiller 0:197cfa57c3c7 35
JoeMiller 0:197cfa57c3c7 36 #elif BOARDNUMBER == 2
JoeMiller 0:197cfa57c3c7 37 #define DAC100MA 35950
JoeMiller 0:197cfa57c3c7 38
JoeMiller 0:197cfa57c3c7 39 #elif BOARDNUMBER == 3
JoeMiller 0:197cfa57c3c7 40 #define DAC100MA 35950
JoeMiller 0:197cfa57c3c7 41
JoeMiller 0:197cfa57c3c7 42 #else
JoeMiller 0:197cfa57c3c7 43 #define DAC100MA 35950
JoeMiller 0:197cfa57c3c7 44
JoeMiller 0:197cfa57c3c7 45 #endif
JoeMiller 0:197cfa57c3c7 46
JoeMiller 0:197cfa57c3c7 47
JoeMiller 0:197cfa57c3c7 48
JoeMiller 0:197cfa57c3c7 49 // Parameters
JoeMiller 0:197cfa57c3c7 50 #define PULSEWIDTH 0.099f
JoeMiller 0:197cfa57c3c7 51 #define INTERVAL 0.599f
JoeMiller 0:197cfa57c3c7 52 #define SLEWRATE 100 //10 is good for active testing, 100 for debugging
JoeMiller 0:197cfa57c3c7 53 #define VBATTERY_MIN (3.00f)
JoeMiller 0:197cfa57c3c7 54 #define TERMINATION_CURRENT (0.067f)
JoeMiller 0:197cfa57c3c7 55 #define HYST (0.0001f) // temp comp hysteresis
JoeMiller 0:197cfa57c3c7 56 #define GAIN 10000 // temp comp gain
JoeMiller 0:197cfa57c3c7 57 char serial_inchar,waiting;
JoeMiller 0:197cfa57c3c7 58
JoeMiller 0:197cfa57c3c7 59 void OnSerial(void) // serial port interrupt used in calibration mode
JoeMiller 0:197cfa57c3c7 60 {
JoeMiller 0:197cfa57c3c7 61 serial_inchar = pc.getc();
JoeMiller 0:197cfa57c3c7 62 waiting = 0;
JoeMiller 0:197cfa57c3c7 63 printf("%c:%d",serial_inchar,serial_inchar);
JoeMiller 0:197cfa57c3c7 64 }
JoeMiller 0:197cfa57c3c7 65
JoeMiller 0:197cfa57c3c7 66
JoeMiller 0:197cfa57c3c7 67 int main() {
JoeMiller 0:197cfa57c3c7 68 float I,V,I_Target;
JoeMiller 0:197cfa57c3c7 69 uint16_t DAC_Value = DAC100MA;
JoeMiller 0:197cfa57c3c7 70 uint32_t count;
JoeMiller 0:197cfa57c3c7 71
JoeMiller 0:197cfa57c3c7 72 DAC_Out.write_u16(0);
JoeMiller 0:197cfa57c3c7 73
JoeMiller 0:197cfa57c3c7 74 pc.baud(115200);
JoeMiller 0:197cfa57c3c7 75 printf("Pulsed Battery Discharger\n\r");
JoeMiller 0:197cfa57c3c7 76 pc.attach(&OnSerial);
JoeMiller 0:197cfa57c3c7 77 LED = 0;
JoeMiller 0:197cfa57c3c7 78 wait(1);
JoeMiller 0:197cfa57c3c7 79 waiting = 1;
JoeMiller 0:197cfa57c3c7 80
JoeMiller 0:197cfa57c3c7 81
JoeMiller 0:197cfa57c3c7 82 // FILE *fp = fopen("/sd/sdtest.txt", "w");
JoeMiller 0:197cfa57c3c7 83 // if(fp == NULL) {
JoeMiller 0:197cfa57c3c7 84 // error("Could not open file for write\n");
JoeMiller 0:197cfa57c3c7 85 // }
JoeMiller 0:197cfa57c3c7 86
JoeMiller 0:197cfa57c3c7 87 #if 1 // 0 = Calibration Mode, 1= Discharge test mode
JoeMiller 0:197cfa57c3c7 88
JoeMiller 0:197cfa57c3c7 89 FILE *fp = fopen("/sd/BatteryLog.txt", "w");
JoeMiller 0:197cfa57c3c7 90 if(fp == NULL) {
JoeMiller 0:197cfa57c3c7 91 error("Could not open file for write\n");
JoeMiller 0:197cfa57c3c7 92 }
JoeMiller 0:197cfa57c3c7 93
JoeMiller 0:197cfa57c3c7 94 fprintf(fp, "I,V,count\n");
JoeMiller 0:197cfa57c3c7 95 printf("\n\rBattery Discharge Mode\n\r");
JoeMiller 0:197cfa57c3c7 96 I_Target = 0.100;
JoeMiller 0:197cfa57c3c7 97 do {
JoeMiller 0:197cfa57c3c7 98
JoeMiller 0:197cfa57c3c7 99 LED = 0;
JoeMiller 0:197cfa57c3c7 100 DAC_Out.write_u16(0);
JoeMiller 0:197cfa57c3c7 101 wait(INTERVAL);
JoeMiller 0:197cfa57c3c7 102 LED = 1;
JoeMiller 0:197cfa57c3c7 103 DAC_Out.write_u16(DAC_Value);
JoeMiller 0:197cfa57c3c7 104 wait(PULSEWIDTH);
JoeMiller 0:197cfa57c3c7 105 I = VRin.read()* I_SCALE;
JoeMiller 0:197cfa57c3c7 106 V = VBin.read()* V_SCALE;
JoeMiller 0:197cfa57c3c7 107
JoeMiller 0:197cfa57c3c7 108 fprintf(fp,"%1.3f,%1.2f,%d\n",I,V,++count);
JoeMiller 0:197cfa57c3c7 109 //printf("%1.3f,%1.2f,%d\n\r",I,V,count);
JoeMiller 0:197cfa57c3c7 110
JoeMiller 0:197cfa57c3c7 111
JoeMiller 0:197cfa57c3c7 112 // temperature compensation
JoeMiller 0:197cfa57c3c7 113 if (I < (I_Target - HYST)) {
JoeMiller 0:197cfa57c3c7 114 DAC_Value += (I_Target - I)*GAIN;
JoeMiller 0:197cfa57c3c7 115 }
JoeMiller 0:197cfa57c3c7 116 else if ( I > (I_Target + HYST)) {
JoeMiller 0:197cfa57c3c7 117 DAC_Value -= (I - I_Target)*GAIN;
JoeMiller 0:197cfa57c3c7 118 }
JoeMiller 0:197cfa57c3c7 119
JoeMiller 0:197cfa57c3c7 120
JoeMiller 0:197cfa57c3c7 121 // If battery Voltage goes below BATTERY_MIN then reduce current
JoeMiller 0:197cfa57c3c7 122 if (V < VBATTERY_MIN) {
JoeMiller 0:197cfa57c3c7 123 if (I_Target > ( TERMINATION_CURRENT - (2.0*HYST))) {
JoeMiller 0:197cfa57c3c7 124 I_Target -= 0.001;
JoeMiller 0:197cfa57c3c7 125 }
JoeMiller 0:197cfa57c3c7 126 }
JoeMiller 0:197cfa57c3c7 127
JoeMiller 0:197cfa57c3c7 128 } while (I > TERMINATION_CURRENT && waiting);
JoeMiller 0:197cfa57c3c7 129
JoeMiller 0:197cfa57c3c7 130 fclose(fp);
JoeMiller 0:197cfa57c3c7 131 DAC_Out.write_u16(0);
JoeMiller 0:197cfa57c3c7 132 printf("Done!\n\r");
JoeMiller 0:197cfa57c3c7 133 LED = 0;
JoeMiller 0:197cfa57c3c7 134
JoeMiller 0:197cfa57c3c7 135
JoeMiller 0:197cfa57c3c7 136
JoeMiller 0:197cfa57c3c7 137 #else
JoeMiller 0:197cfa57c3c7 138 //Perform Board Calibration
JoeMiller 0:197cfa57c3c7 139 printf("\n\rCalibration Mode\n\r");
JoeMiller 0:197cfa57c3c7 140 waiting = 1;
JoeMiller 0:197cfa57c3c7 141 while (pc.readable()) { // flush buffer
JoeMiller 0:197cfa57c3c7 142 serial_inchar = pc.getc();
JoeMiller 0:197cfa57c3c7 143 }
JoeMiller 0:197cfa57c3c7 144 printf("Set Vin to 3.20V then [press any key]\n\r");
JoeMiller 0:197cfa57c3c7 145 while(waiting == 1){
JoeMiller 0:197cfa57c3c7 146 wait(0.05);
JoeMiller 0:197cfa57c3c7 147 }
JoeMiller 0:197cfa57c3c7 148 printf("OK\n\r");
JoeMiller 0:197cfa57c3c7 149 wait(0.5);
JoeMiller 0:197cfa57c3c7 150 V = VBin.read();
JoeMiller 0:197cfa57c3c7 151
JoeMiller 0:197cfa57c3c7 152 printf("Setting Current to 100mA\n\r");
JoeMiller 0:197cfa57c3c7 153 printf("Use +, -, *, / to adjust, q to end\n\r");
JoeMiller 0:197cfa57c3c7 154
JoeMiller 0:197cfa57c3c7 155 DAC_Value = 35550;
JoeMiller 0:197cfa57c3c7 156 DAC_Out.write_u16(DAC_Value);
JoeMiller 0:197cfa57c3c7 157
JoeMiller 0:197cfa57c3c7 158 waiting = 1;
JoeMiller 0:197cfa57c3c7 159 do {
JoeMiller 0:197cfa57c3c7 160 while(waiting){wait(0.01);}
JoeMiller 0:197cfa57c3c7 161 printf("=%c",serial_inchar);
JoeMiller 0:197cfa57c3c7 162 switch (serial_inchar) {
JoeMiller 0:197cfa57c3c7 163 case '+':
JoeMiller 0:197cfa57c3c7 164 DAC_Value += 10;
JoeMiller 0:197cfa57c3c7 165 break;
JoeMiller 0:197cfa57c3c7 166 case '-':
JoeMiller 0:197cfa57c3c7 167 DAC_Value -= 10;
JoeMiller 0:197cfa57c3c7 168 break;
JoeMiller 0:197cfa57c3c7 169 case '*':
JoeMiller 0:197cfa57c3c7 170 DAC_Value += 100;
JoeMiller 0:197cfa57c3c7 171 break;
JoeMiller 0:197cfa57c3c7 172 case '/':
JoeMiller 0:197cfa57c3c7 173 DAC_Value -= 100;
JoeMiller 0:197cfa57c3c7 174 break;
JoeMiller 0:197cfa57c3c7 175 }
JoeMiller 0:197cfa57c3c7 176 DAC_Out.write_u16(DAC_Value);
JoeMiller 0:197cfa57c3c7 177 waiting = 1;
JoeMiller 0:197cfa57c3c7 178 } while (serial_inchar != 'q');
JoeMiller 0:197cfa57c3c7 179 I = VRin.read();
JoeMiller 0:197cfa57c3c7 180 DAC_Out.write_u16(0);
JoeMiller 0:197cfa57c3c7 181 printf("\n\rVIN VALUE: %f\n\rDACVALUE: %d\n\r,I in:%f\n\r",V,DAC_Value,I);
JoeMiller 0:197cfa57c3c7 182 printf("Cut/paste this calibration into the calibration section...\n\r\n\r");
JoeMiller 0:197cfa57c3c7 183 printf("#define DAC100MA %d\n\r",DAC_Value);
JoeMiller 0:197cfa57c3c7 184 printf("#define I_SCALE %fF\n\r",0.1/I);
JoeMiller 0:197cfa57c3c7 185 printf("#define V_SCALE %fF\n\r",3.2/V);
JoeMiller 0:197cfa57c3c7 186 printf("\n\r\n\r");
JoeMiller 0:197cfa57c3c7 187
JoeMiller 0:197cfa57c3c7 188
JoeMiller 0:197cfa57c3c7 189 // Validation test
JoeMiller 0:197cfa57c3c7 190 float test_I_SCALE = 0.1/I;
JoeMiller 0:197cfa57c3c7 191 float test_V_SCALE = 3.2/V;
JoeMiller 0:197cfa57c3c7 192 while(serial_inchar == 'q') {
JoeMiller 0:197cfa57c3c7 193 DAC_Out.write_u16(DAC_Value);
JoeMiller 0:197cfa57c3c7 194 wait(INTERVAL+PULSEWIDTH);
JoeMiller 0:197cfa57c3c7 195 I = VRin.read()* test_I_SCALE;
JoeMiller 0:197cfa57c3c7 196 V = VBin.read()* test_V_SCALE;
JoeMiller 0:197cfa57c3c7 197
JoeMiller 0:197cfa57c3c7 198 printf("%1.4f,%1.2f,%d\n\r",I,V,DAC_Value);
JoeMiller 0:197cfa57c3c7 199
JoeMiller 0:197cfa57c3c7 200 // temperature compensation
JoeMiller 0:197cfa57c3c7 201 if (I < (0.100 - HYST)) {
JoeMiller 0:197cfa57c3c7 202 DAC_Value += (0.1 - I)*GAIN;
JoeMiller 0:197cfa57c3c7 203 }
JoeMiller 0:197cfa57c3c7 204 else if ( I > (0.100 + HYST)) {
JoeMiller 0:197cfa57c3c7 205 DAC_Value -= (I - 0.1)*GAIN;;
JoeMiller 0:197cfa57c3c7 206 }
JoeMiller 0:197cfa57c3c7 207
JoeMiller 0:197cfa57c3c7 208 }
JoeMiller 0:197cfa57c3c7 209 DAC_Out.write_u16(0);
JoeMiller 0:197cfa57c3c7 210
JoeMiller 0:197cfa57c3c7 211 #endif
JoeMiller 0:197cfa57c3c7 212
JoeMiller 0:197cfa57c3c7 213 }