![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Temperature calibration control program
main.cpp
- Committer:
- justinbuckland
- Date:
- 2019-06-24
- Revision:
- 0:147db0900012
- Child:
- 1:68515313ce3e
File content as of revision 0:147db0900012:
#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); }