![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Temperature calibration control program
Diff: main.cpp
- 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); +}