First working, tested and calibrated unit

Dependencies:   mbed USBDevice

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