ADC logging with demo drive board for calibration

Dependencies:   mbed MODSERIAL FastPWM ADS8568_ADC

Revision:
4:694f0e328a52
Parent:
3:447b0de4295a
Child:
5:67e4ee9a00dc
--- a/main.cpp	Tue Jul 31 09:18:58 2018 +0000
+++ b/main.cpp	Tue Jul 31 17:25:41 2018 +0000
@@ -1,33 +1,86 @@
 #include "mbed.h"
 
-#define CH_A 1     // value of convst bus to read channel A only
-#define CH_AC 5     // value of convst bus to read channels A and C
-#define CH_ABCD 15 // value of convst bus to read all chanels simultaneously
+// thermal cycling settings
+#define N_CYCLES           10     // number of thermal cycles (ramp-hold-ramp-hold)
+#define R_SETPOINT_LOW  0.840     // heater resistance at low temp R60
+#define T_LOW_RAMP       0000     // low temperature ramp time (ms)
+#define T_LOW_HOLD       2000     // low temperature hold time (ms)
+#define R_SETPOINT_HIGH 0.860     // heater resistance at high temp R95
+#define T_HIGH_RAMP      0000     // high temperaure ramp time (ms)
+#define T_HIGH_HOLD      2000     // high temperature time (ms)
+#define T_HIGH_START     2000     // hotstart time(ms)
+
+// temperature measurement settings
+#define N_SAMPLES           1     // number of samples to acquire for I and V measurements
+#define N_ROLL_AVG         10     // rolling average for R values
+#define PULSE_WIDTH      2000     // heat or cool pulse width (us)
+#define MEAS_DELAY       1000     // measurement delay after turning on FET (us)
+#define CAM_TRIG           20     // camera trigger pulse width (us)
+#define LOG_INTERVAL      100     // log file interval (ms)
+
+// ADC channels to read
+#define CH_A                1     // value of convst bus to read channel A only
+#define CH_AC               5     // value of convst bus to read channels A and C
+#define CH_ABCD            15     // value of convst bus to read all chanels simultaneously
 
 Serial pc(USBTX, USBRX); // tx, rx
 
-DigitalOut drive(p21);
-DigitalOut yLED(p27);
-DigitalOut gLED(p28);
-DigitalOut rLED(p26);
+DigitalOut drive(p21);            // drive FET
+DigitalOut yLED(p27);             // yellow LED (drive on)
+DigitalOut gLED(p28);             // green LED (power on)
+DigitalOut rLED(p26);             // red LED (thermocycling in progress)
+DigitalOut camTrig(p25);          // trigger camera
 
 AnalogIn battVolt(p19);
 AnalogIn auxVolt(p20);
 
 BusOut convt(p11, p12, p13, p14);
-SPI spi(p5, p6, p7); // mosi, miso, sclk
-DigitalOut cs(p8);  //chip select
+SPI spi(p5, p6, p7);              // mosi, miso, sclk
+DigitalOut cs(p8);                // chip select
 DigitalIn busy(p9);
 DigitalOut reset(p10);
 
+Timer timer;
+LocalFileSystem local("local");
+
+FILE *fp = fopen("/local/TEST_LOG.csv", "w");  // Open "test_log" on the local file system for writing
+
+float r = 0;
+float rAvg = 0;
+float rAcc = 0;
+float rSet;
+
+int nAcc = 0;
+int eTime;
+int logTime = 0;
+int iCycle = 0;
+
+char outString[100];
+
 char buffer16[16];
 int val_array[8];
 const char dummy = 0;
-int drivetime_ms;
+
+void logFile(void) {
+    rAcc = rAcc + r;
+    nAcc++;
+    if (eTime > logTime) {
+       // trigger camera 
+       camTrig = 1;
+       wait_us(CAM_TRIG);
+       camTrig = 0;
 
-char outString[100];
+       // write data
+       sprintf(outString, "%10d,%10d,%10.6f,%10.6f\n", iCycle, eTime, rAcc/nAcc, rSet); // log data
+       pc.printf("%s",outString);
+       fprintf(fp, outString);
+       logTime = logTime + LOG_INTERVAL;
+       rAcc = 0;
+       nAcc = 0;
+    }
+}
 
-int readChannels (char buffer[16], int values[8]){
+void readChannels (char buffer[16], int values[8]){
     //simultaneously samples and reads into buffer
     short int val_array[8];
              
@@ -45,35 +98,70 @@
     for (int i=0; i<8; i++){
         val_array[i] = buffer[2*i]<<8 | buffer16[(2*i) + 1];
         values [i] = val_array[i];   
+    }            
+    r = (double)(val_array[5]-val_array[4])/(double)(val_array[1]-val_array[0]);
+}
+    
+void tempControl(int endTime){
+    eTime = timer.read_ms();
+    while (eTime < endTime) {
+        yLED = 1;
+        drive = 1;
+        wait_us(MEAS_DELAY);                         // wait for heater current to stabilise
+        readChannels (buffer16, val_array);          // read ADC channels and update r
+        rAvg = ((N_ROLL_AVG-1)*rAvg + r)/N_ROLL_AVG; // calculate rolling average r
+        // printf("hold r: %8.4f\r\n",r);
+        if (rAvg > rSet) {
+            drive = 0; // turn off heater if setpoint resistance is exceeded  
+            yLED = 0;
         }
-            
-    return 0;
-    }
+        // printf("set r: %8.4f\r\n",r);
+           
+        logFile();
+        wait_us(PULSE_WIDTH);  //wait until pulse_width (us) has elapsed  
+        eTime = timer.read_ms();
+     }    
+}
+
+void tempControlRamp(float setStartR, float setEndR, int endTime){
+    float setRate;
+    int startTime;
     
+    startTime = timer.read_ms();
+    setRate = (setEndR - setStartR)/(endTime - startTime);
+    eTime = startTime;
+    while (eTime < endTime) {
+        rSet = setStartR + setRate*(eTime - startTime);
+        yLED = 1;
+        drive = 1;
+        wait_us(MEAS_DELAY); // wait for heater current to stabilise
+        readChannels (buffer16, val_array);          // read ADC channels and update r
+        rAvg = ((N_ROLL_AVG-1)*rAvg + r)/N_ROLL_AVG; // measure r
+        if (rAvg > rSet) {
+            drive = 0; // turn off heater if setpoint resistance is exceeded  
+            yLED = 0;
+        }
+        // printf("ramp r: %8.4f\r\n",r);
+
+        logFile();
+        wait_us(PULSE_WIDTH);  //wait until pulse_width (us) has elapsed  
+        eTime = timer.read_ms();
+    }    
+}
+
 
 int main() {
-    int n_samples = 10000;
-    double r;
-    double r_max = 0;
-    double r_min = 1e10;
-    double r_sum = 0;
-    double r_sum2 = 0;
-    double r_mean;
-    double r_mean2;
-    double r_sd;
-    double r_cv;
+    int endTime = 0;
      
     rLED = 0;
     yLED = 0;
     gLED = 0;
     
     drive = 0;
-    drivetime_ms = 1;
        
     pc.baud(115200);
-    pc.printf("Test start\r\n");
-    
     //Reset ADC sequence
+
     reset = 1;
     wait_ms(1);
     reset = 0;
@@ -84,46 +172,50 @@
     spi.set_default_write_value(0x00);
     cs = 1;
 
-    rLED = 1;
-    yLED = 0;
-    gLED = 1;
-    
-    sprintf(outString, "I1SIG, I1REF, V1POS, V1NEG,        R\r\n");
-    pc.printf("%s", outString);
+    rLED = 1;  // thermal cycling in progress
+    yLED = 0;  // heater on
+    gLED = 1;  // microprocessor power on
     
-    for (int x=0; x<n_samples; x++) {
-        drive = 1;
-        yLED = 1;
-        wait_ms(drivetime_ms);
-        readChannels (buffer16, val_array);
-        drive = 0;
-        yLED = 0;
-        
-        r = (double)(val_array[5]-val_array[4])/(double)(val_array[1]-val_array[0]);
-        if (r < r_min) { r_min = r; }
-        if (r > r_max) { r_max = r; }
-        r_sum = r_sum + r;
-        r_sum2 = r_sum2 + (r*r);
+    sprintf(outString,"    iCycle,  Time(ms),         r,      rSet\n");  
+    pc.printf("%s", outString);
+    fprintf(fp, outString);
+  
+    timer.start();
+    
+    // optional hot start: additional HIGH temperature time at start
+    if (T_HIGH_START > 0) {
+          endTime = T_HIGH_START;
+          rSet = R_SETPOINT_HIGH;
+          tempControl(endTime);
+    }
 
-        sprintf(outString, "%5d\t %5d\t %5d\t %5d\t %f\r\n", val_array[0], val_array[1], val_array[4], val_array[5], r);
-        pc.printf("%s", outString); 
-        wait_ms(1000);
+    // thermocycle loop
+    for (iCycle = 0; iCycle < N_CYCLES; iCycle++ ) {
+        
+        // ramp up to HIGH temperature
+        endTime = endTime + T_HIGH_RAMP;
+        tempControlRamp(R_SETPOINT_LOW, R_SETPOINT_HIGH, endTime);
+        
+        // hold at HIGH temperature
+        endTime = endTime + T_HIGH_HOLD;
+        rSet = R_SETPOINT_HIGH;
+        tempControl(endTime);
         
-        }
-
-    r_mean = r_sum/n_samples;
-    r_mean2 = r_sum2/n_samples;
-    r_sd = sqrt(r_mean2-(r_mean*r_mean));
-    r_cv = r_sd/r_mean;
-
-//    pc.printf("Statistics:\r\n"); 
-//    pc.printf("n_samples : %d\r\n", n_samples); 
-//    pc.printf("r_mean    : %f\r\n", r_mean); 
-//    pc.printf("r_min     : %f\r\n", r_min); 
-//    pc.printf("r_max     : %f\r\n", r_max); 
-//    pc.printf("r_sd      : %f\r\n", r_sd); 
-//    pc.printf("r_cv      : %f\r\n", r_cv);  
-
-    rLED = 0;
-    
- }
+        // ramp down to LOW temperature
+        endTime = endTime + T_LOW_RAMP;
+        tempControlRamp(R_SETPOINT_HIGH, R_SETPOINT_LOW, endTime);
+        
+        // hold at LOW temperature
+        endTime = endTime + T_LOW_HOLD;
+        rSet = R_SETPOINT_LOW;
+        tempControl(endTime);
+        
+    }        
+  
+    // extinguish rLED (thermocycling complete), ensure heater is off and close log file for access
+    drive = 0;
+    rLED = 0; 
+    logTime = 0;
+    logFile();
+    fclose(fp);     
+}