Temperature calibration control program

Dependencies:   mbed

Committer:
justinbuckland
Date:
Tue Jun 25 11:45:10 2019 +0000
Revision:
1:68515313ce3e
Parent:
0:147db0900012
5 resistance setpoint steps for calibration

Who changed what in which revision?

UserRevisionLine numberNew contents of line
justinbuckland 0:147db0900012 1 #include "mbed.h"
justinbuckland 0:147db0900012 2
justinbuckland 1:68515313ce3e 3 // select heater
justinbuckland 1:68515313ce3e 4 #define HEATER 1 // inner heater = 1, outer heater = 2
justinbuckland 0:147db0900012 5
justinbuckland 1:68515313ce3e 6 // temperature calibration settings
justinbuckland 1:68515313ce3e 7 #define N_STEPS 5 // number of temperature calibration points
justinbuckland 1:68515313ce3e 8 #define R_SET_START 1.900 // heater resistance at lowest temp
justinbuckland 1:68515313ce3e 9 #define R_SET_STEP 0.100 // heater resistance at highest temp
justinbuckland 1:68515313ce3e 10 #define T_HOLD 100000 // temperature hold time (ms)
justinbuckland 0:147db0900012 11
justinbuckland 0:147db0900012 12 // temperature measurement settings
justinbuckland 0:147db0900012 13 #define N_SAMPLES 1 // number of samples to acquire for I and V measurements
justinbuckland 0:147db0900012 14 #define N_ROLL_AVG 10 // rolling average for R values
justinbuckland 0:147db0900012 15 #define PULSE_WIDTH 5000 // heat or cool pulse width (us)
justinbuckland 0:147db0900012 16 #define MEAS_DELAY 50 // measurement delay after turning on FET (us)
justinbuckland 0:147db0900012 17 #define CAM_TRIG 20 // camera trigger pulse width (us)
justinbuckland 1:68515313ce3e 18 #define LOG_INTERVAL 1000 // log file interval (ms)
justinbuckland 0:147db0900012 19
justinbuckland 0:147db0900012 20 // ADC channels to read
justinbuckland 0:147db0900012 21 #define CH_A 1 // value of convst bus to read channel A only
justinbuckland 0:147db0900012 22 #define CH_AC 5 // value of convst bus to read channels A and C
justinbuckland 0:147db0900012 23 #define CH_ABCD 15 // value of convst bus to read all chanels simultaneously
justinbuckland 0:147db0900012 24
justinbuckland 0:147db0900012 25 Serial pc(USBTX, USBRX); // tx, rx
justinbuckland 0:147db0900012 26
justinbuckland 0:147db0900012 27 DigitalOut drive(p21); // drive FET
justinbuckland 0:147db0900012 28 DigitalOut yLED(p27); // yellow LED (drive on)
justinbuckland 0:147db0900012 29 DigitalOut gLED(p28); // green LED (power on)
justinbuckland 0:147db0900012 30 DigitalOut rLED(p26); // red LED (thermocycling in progress)
justinbuckland 0:147db0900012 31 DigitalOut mbedIO(p25); // MBED IO
justinbuckland 0:147db0900012 32 DigitalOut camTrig(p24); // trigger camera
justinbuckland 0:147db0900012 33
justinbuckland 0:147db0900012 34 AnalogIn battVolt(p19);
justinbuckland 0:147db0900012 35 AnalogIn auxVolt(p20);
justinbuckland 0:147db0900012 36
justinbuckland 0:147db0900012 37 BusOut convt(p11, p12, p13, p14);
justinbuckland 0:147db0900012 38 SPI spi(p5, p6, p7); // mosi, miso, sclk
justinbuckland 0:147db0900012 39 DigitalOut cs(p8); // chip select
justinbuckland 0:147db0900012 40 DigitalIn busy(p9);
justinbuckland 0:147db0900012 41 DigitalOut reset(p10);
justinbuckland 0:147db0900012 42 DigitalIn userButton(p16);
justinbuckland 0:147db0900012 43 Timer timer;
justinbuckland 0:147db0900012 44 LocalFileSystem local("local");
justinbuckland 0:147db0900012 45
justinbuckland 0:147db0900012 46 FILE *fp = fopen("/local/TEST_LOG.csv", "w"); // Open "test_log" on the local file system for writing
justinbuckland 0:147db0900012 47
justinbuckland 0:147db0900012 48 float r = 0;
justinbuckland 0:147db0900012 49 float r1 = 0;
justinbuckland 0:147db0900012 50 float r2 = 0;
justinbuckland 0:147db0900012 51 float rAvg = 0;
justinbuckland 0:147db0900012 52 float rAcc = 0;
justinbuckland 0:147db0900012 53 float rSet;
justinbuckland 0:147db0900012 54
justinbuckland 0:147db0900012 55 int nAcc = 0;
justinbuckland 0:147db0900012 56 int eTime;
justinbuckland 0:147db0900012 57 int logTime = 0;
justinbuckland 0:147db0900012 58 int iCycle = 0;
justinbuckland 0:147db0900012 59
justinbuckland 0:147db0900012 60 char outString[100];
justinbuckland 0:147db0900012 61
justinbuckland 0:147db0900012 62 char buffer16[16];
justinbuckland 0:147db0900012 63 int val_array[8];
justinbuckland 0:147db0900012 64 const char dummy = 0;
justinbuckland 0:147db0900012 65
justinbuckland 0:147db0900012 66 void logFile(void) {
justinbuckland 0:147db0900012 67 rAcc = rAcc + r;
justinbuckland 0:147db0900012 68 nAcc++;
justinbuckland 0:147db0900012 69 if (eTime > logTime) {
justinbuckland 0:147db0900012 70 // trigger camera
justinbuckland 0:147db0900012 71 camTrig = 1;
justinbuckland 0:147db0900012 72 mbedIO = 1;
justinbuckland 0:147db0900012 73 wait_us(CAM_TRIG);
justinbuckland 0:147db0900012 74 camTrig = 0;
justinbuckland 0:147db0900012 75 mbedIO = 0;
justinbuckland 0:147db0900012 76
justinbuckland 0:147db0900012 77 // write data
justinbuckland 0:147db0900012 78 sprintf(outString, "%10d,%10d,%10.6f,%10.6f\n", iCycle, eTime, rAcc/nAcc, rSet); // log data
justinbuckland 0:147db0900012 79 pc.printf("%s",outString);
justinbuckland 0:147db0900012 80 fprintf(fp, outString);
justinbuckland 0:147db0900012 81 logTime = logTime + LOG_INTERVAL;
justinbuckland 0:147db0900012 82 rAcc = 0;
justinbuckland 0:147db0900012 83 nAcc = 0;
justinbuckland 0:147db0900012 84 }
justinbuckland 0:147db0900012 85 }
justinbuckland 0:147db0900012 86
justinbuckland 0:147db0900012 87 void readChannels (char buffer[16], int values[8]){
justinbuckland 0:147db0900012 88 //simultaneously samples and reads into buffer
justinbuckland 0:147db0900012 89 short int val_array[8];
justinbuckland 0:147db0900012 90 double i1, v1, i2, v2;
justinbuckland 0:147db0900012 91
justinbuckland 0:147db0900012 92 //send convert signal to channels
justinbuckland 0:147db0900012 93 convt = CH_ABCD;
justinbuckland 0:147db0900012 94 wait_us(1);
justinbuckland 0:147db0900012 95 convt = 0;
justinbuckland 0:147db0900012 96
justinbuckland 0:147db0900012 97 //SPI(like) data transfer
justinbuckland 0:147db0900012 98 cs = 0;
justinbuckland 0:147db0900012 99 spi.write(&dummy, 1, buffer, 16);
justinbuckland 0:147db0900012 100 cs=1;
justinbuckland 0:147db0900012 101
justinbuckland 0:147db0900012 102 //loop over bytes to add channel voltage values
justinbuckland 0:147db0900012 103 for (int i=0; i<8; i++){
justinbuckland 0:147db0900012 104 val_array[i] = buffer[2*i]<<8 | buffer16[(2*i) + 1];
justinbuckland 0:147db0900012 105 values [i] = val_array[i];
justinbuckland 0:147db0900012 106 }
justinbuckland 0:147db0900012 107 i1 = (double) (val_array[0]-val_array[1]);
justinbuckland 0:147db0900012 108 i2 = (double) (val_array[2]-val_array[1]);
justinbuckland 0:147db0900012 109 v1 = (double) (val_array[4]-val_array[5]);
justinbuckland 0:147db0900012 110 v2 = (double) (val_array[6]-val_array[7]);
justinbuckland 0:147db0900012 111
justinbuckland 0:147db0900012 112 // update values if no division by zero (to avoid NaN if PSU is off)
justinbuckland 0:147db0900012 113 if (i1 > 0) r1 = v1/i1;
justinbuckland 0:147db0900012 114 if (i2 > 0) r2 = v2/i2;
justinbuckland 0:147db0900012 115
justinbuckland 0:147db0900012 116 // select heater (inner or outer)
justinbuckland 1:68515313ce3e 117 if (HEATER == 1) r = r1;
justinbuckland 1:68515313ce3e 118 if (HEATER == 2) r = r2;
justinbuckland 0:147db0900012 119 }
justinbuckland 0:147db0900012 120
justinbuckland 0:147db0900012 121 void tempControl(int endTime){
justinbuckland 0:147db0900012 122 eTime = timer.read_ms();
justinbuckland 0:147db0900012 123 while (eTime < endTime) {
justinbuckland 0:147db0900012 124 yLED = 1;
justinbuckland 0:147db0900012 125 drive = 1;
justinbuckland 0:147db0900012 126 wait_us(MEAS_DELAY); // wait for heater current to stabilise
justinbuckland 0:147db0900012 127 readChannels (buffer16, val_array); // read ADC channels and update r
justinbuckland 0:147db0900012 128 rAvg = ((N_ROLL_AVG-1)*rAvg + r)/N_ROLL_AVG; // calculate rolling average r
justinbuckland 0:147db0900012 129 // printf("hold r: %8.4f\r\n",r);
justinbuckland 0:147db0900012 130 if (rAvg > rSet) {
justinbuckland 0:147db0900012 131 drive = 0; // turn off heater if setpoint resistance is exceeded
justinbuckland 0:147db0900012 132 yLED = 0;
justinbuckland 0:147db0900012 133 }
justinbuckland 0:147db0900012 134 // printf("set r: %8.4f\r\n",r);
justinbuckland 0:147db0900012 135
justinbuckland 0:147db0900012 136 logFile();
justinbuckland 0:147db0900012 137 wait_us(PULSE_WIDTH); //wait until pulse_width (us) has elapsed
justinbuckland 0:147db0900012 138 eTime = timer.read_ms();
justinbuckland 0:147db0900012 139 }
justinbuckland 0:147db0900012 140 }
justinbuckland 0:147db0900012 141
justinbuckland 0:147db0900012 142 void tempControlRamp(float setStartR, float setEndR, int endTime){
justinbuckland 0:147db0900012 143 float setRate;
justinbuckland 0:147db0900012 144 int startTime;
justinbuckland 0:147db0900012 145
justinbuckland 0:147db0900012 146
justinbuckland 0:147db0900012 147 startTime = timer.read_ms();
justinbuckland 0:147db0900012 148 setRate = (setEndR - setStartR)/(endTime - startTime);
justinbuckland 0:147db0900012 149 eTime = startTime;
justinbuckland 0:147db0900012 150 while (eTime < endTime) {
justinbuckland 0:147db0900012 151 rSet = setStartR + setRate*(eTime - startTime);
justinbuckland 0:147db0900012 152 yLED = 1;
justinbuckland 0:147db0900012 153 drive = 1;
justinbuckland 0:147db0900012 154 wait_us(MEAS_DELAY); // wait for heater current to stabilise
justinbuckland 0:147db0900012 155 readChannels (buffer16, val_array); // read ADC channels and update r
justinbuckland 0:147db0900012 156 rAvg = ((N_ROLL_AVG-1)*rAvg + r)/N_ROLL_AVG; // measure r
justinbuckland 0:147db0900012 157 if (rAvg > rSet) {
justinbuckland 0:147db0900012 158 drive = 0; // turn off heater if setpoint resistance is exceeded
justinbuckland 0:147db0900012 159 yLED = 0;
justinbuckland 0:147db0900012 160 }
justinbuckland 0:147db0900012 161 // printf("ramp r: %8.4f\r\n",r);
justinbuckland 0:147db0900012 162
justinbuckland 0:147db0900012 163 logFile();
justinbuckland 0:147db0900012 164 wait_us(PULSE_WIDTH); //wait until pulse_width (us) has elapsed
justinbuckland 0:147db0900012 165 eTime = timer.read_ms();
justinbuckland 0:147db0900012 166 }
justinbuckland 0:147db0900012 167 }
justinbuckland 0:147db0900012 168
justinbuckland 0:147db0900012 169
justinbuckland 0:147db0900012 170 int main() {
justinbuckland 0:147db0900012 171 int endTime = 0;
justinbuckland 1:68515313ce3e 172 int iStep = 0;
justinbuckland 0:147db0900012 173
justinbuckland 0:147db0900012 174 rLED = 0;
justinbuckland 0:147db0900012 175 yLED = 0;
justinbuckland 0:147db0900012 176 gLED = 0;
justinbuckland 0:147db0900012 177
justinbuckland 0:147db0900012 178 drive = 0;
justinbuckland 0:147db0900012 179
justinbuckland 0:147db0900012 180 pc.baud(115200);
justinbuckland 0:147db0900012 181
justinbuckland 0:147db0900012 182 sprintf(outString," iCycle, Time(ms), r, rSet\n");
justinbuckland 0:147db0900012 183 pc.printf("%s", outString);
justinbuckland 0:147db0900012 184 fprintf(fp, outString);
justinbuckland 0:147db0900012 185
justinbuckland 0:147db0900012 186 reset = 1;
justinbuckland 0:147db0900012 187 wait_ms(1);
justinbuckland 0:147db0900012 188 reset = 0;
justinbuckland 0:147db0900012 189
justinbuckland 0:147db0900012 190 //set SPI serial to 2MHz, 16 bit data transfer, mode 2 (clock normally high, data preceeding clock cycle)
justinbuckland 0:147db0900012 191 spi.format(8,2);
justinbuckland 0:147db0900012 192 spi.frequency(2000000);
justinbuckland 0:147db0900012 193 spi.set_default_write_value(0x00);
justinbuckland 0:147db0900012 194 cs = 1;
justinbuckland 0:147db0900012 195
justinbuckland 0:147db0900012 196 rLED = 1; // thermal cycling in progress
justinbuckland 0:147db0900012 197 yLED = 0; // heater off
justinbuckland 0:147db0900012 198 gLED = 1; // microprocessor power on
justinbuckland 0:147db0900012 199
justinbuckland 0:147db0900012 200 timer.start();
justinbuckland 0:147db0900012 201
justinbuckland 1:68515313ce3e 202 while (iStep < N_STEPS) {
justinbuckland 1:68515313ce3e 203 endTime = endTime + T_HOLD;
justinbuckland 1:68515313ce3e 204 rSet = R_SET_START + R_SET_STEP*iStep;
justinbuckland 1:68515313ce3e 205 tempControl(endTime);
justinbuckland 1:68515313ce3e 206 iStep++;
justinbuckland 0:147db0900012 207 }
justinbuckland 1:68515313ce3e 208
justinbuckland 0:147db0900012 209 // extinguish rLED (thermocycling complete), ensure heater is off and close log file for access
justinbuckland 0:147db0900012 210 drive = 0;
justinbuckland 0:147db0900012 211 rLED = 0;
justinbuckland 0:147db0900012 212 logTime = 0;
justinbuckland 0:147db0900012 213 logFile();
justinbuckland 0:147db0900012 214 fclose(fp);
justinbuckland 0:147db0900012 215 }