Temperature calibration control program

Dependencies:   mbed

Revision:
0:147db0900012
Child:
1:68515313ce3e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jun 24 08:48:22 2019 +0000
@@ -0,0 +1,258 @@
+#include "mbed.h"
+
+// thermal cycling settings
+#define N_CYCLES            40     // number of thermal cycles (ramp-hold-ramp-hold)
+#define R_SETPOINT_LOW    2.129     // heater resistance at low temp
+#define T_LOW_RAMP           0     // low temperature ramp time (ms)
+#define T_LOW_HOLD       30000     // low temperature hold time (ms)
+#define R_SETPOINT_MID    2.211    // heater resistance at mid temp 
+#define T_MID_RAMP           0     // mid temperature ramp time (ms)
+#define T_MID_HOLD           0     // mid temperature hold time (ms)
+#define R_SETPOINT_HIGH   2.35   // heater resistance at high temp 
+#define T_HIGH_RAMP          0     // high temperaure ramp time (ms)
+#define T_HIGH_HOLD      10000     // high temperature time (ms)
+#define T_HIGH_START     60000     // hotstart time(ms)
+#define R_LYSE            1.99     // lyse temperature setpoint
+#define T_LYSE               0     // lyse time (ms)
+#define R_RT              2.3     // RT temperature setpoint
+#define T_RT            300000     // RT time (ms)
+#define T_FLUIDICS           0     // nominal time for fluidics post lyse
+#define T_HOLD           60000
+#define T_RAMP           15000
+
+#define T_FORM_DSNA          0     // form dsna post thermocycling
+#define R_FORM_DSNA        2.8     // temperature to form dsna post thermocycling
+
+#define T_MELT_CURVE     50000     // melt curve ramp time
+#define R_MELT_LOW        1.82     // low end melt curve temperature
+#define R_MELT_HIGH       2.08     // high end melt curve temperature
+
+// 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       5000     // heat or cool pulse width (us)
+#define MEAS_DELAY          50     // measurement delay after turning on FET (us)
+#define CAM_TRIG            20     // camera trigger pulse width (us)
+#define LOG_INTERVAL       500     // 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);            // 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 mbedIO(p25);           // MBED IO
+DigitalOut camTrig(p24);          // 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
+DigitalIn busy(p9);
+DigitalOut reset(p10);
+DigitalIn userButton(p16);
+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 r1 = 0;
+float r2 = 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;
+
+void logFile(void) {
+    rAcc = rAcc + r;
+    nAcc++;
+    if (eTime > logTime) {
+       // trigger camera 
+       camTrig = 1;
+       mbedIO = 1;
+       wait_us(CAM_TRIG);
+       camTrig = 0;
+       mbedIO = 0;
+
+       // 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;
+    }
+}
+
+void readChannels (char buffer[16], int values[8]){
+    //simultaneously samples and reads into buffer
+    short int val_array[8];
+    double i1, v1, i2, v2;
+             
+    //send convert signal to channels
+    convt = CH_ABCD;
+    wait_us(1);
+    convt = 0;
+                
+    //SPI(like) data transfer
+    cs = 0;
+    spi.write(&dummy, 1, buffer, 16);
+    cs=1;
+       
+    //loop over bytes to add channel voltage values
+    for (int i=0; i<8; i++){
+        val_array[i] = buffer[2*i]<<8 | buffer16[(2*i) + 1];
+        values [i] = val_array[i];   
+    }
+    i1 = (double) (val_array[0]-val_array[1]);
+    i2 = (double) (val_array[2]-val_array[1]);
+    v1 = (double) (val_array[4]-val_array[5]);
+    v2 = (double) (val_array[6]-val_array[7]);
+              
+    // update values if no division by zero (to avoid NaN if PSU is off)
+    if (i1 > 0) r1 = v1/i1;
+    if (i2 > 0) r2 = v2/i2;
+        
+    // select heater (inner or outer)
+    r = r1; // r1 is inner, r21 is outer
+}
+    
+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;
+        }
+        // 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 endTime = 0;
+     
+    rLED = 0;
+    yLED = 0;
+    gLED = 0;
+    
+    drive = 0;
+       
+    pc.baud(115200);
+    //Reset ADC sequence
+    
+    sprintf(outString,"    iCycle,  Time(ms),         r,      rSet\n");  
+    pc.printf("%s", outString);
+    fprintf(fp, outString);
+
+ //   while(userButton == 0)
+ //  {
+ //       wait_ms(1);
+ //   };
+        
+        
+    reset = 1;
+    wait_ms(1);
+    reset = 0;
+    
+    //set SPI serial to 2MHz, 16 bit data transfer, mode 2 (clock normally high, data preceeding clock cycle) 
+    spi.format(8,2);
+    spi.frequency(2000000);
+    spi.set_default_write_value(0x00);
+    cs = 1;
+
+    rLED = 1;  // thermal cycling in progress
+    yLED = 0;  // heater off
+    gLED = 1;  // microprocessor power on
+    
+  
+    timer.start();
+
+    if (T_HOLD > 0) {
+          endTime = endTime + T_HOLD;
+          rSet = R_SETPOINT_LOW;
+          tempControl(endTime);
+    }   
+    if (T_RAMP > 0) {
+          endTime = endTime + T_RAMP;
+          tempControlRamp(R_SETPOINT_LOW, R_SETPOINT_MID, endTime);
+            
+    }
+    if (T_HOLD > 0) {
+          endTime = endTime + T_HOLD;
+          rSet = R_SETPOINT_MID;
+          tempControl(endTime);
+    }
+    if (T_RAMP > 0) {
+          endTime = endTime + T_RAMP;
+          tempControlRamp(R_SETPOINT_MID, R_SETPOINT_HIGH, endTime);
+            
+    }
+    if (T_HOLD > 0) {
+          endTime = endTime + T_HOLD;
+          rSet = R_SETPOINT_HIGH;
+          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);     
+}