code for extended logging of resistance at a set set point temp

Dependencies:   mbed

Committer:
AlexStokoe
Date:
Mon Sep 24 09:21:06 2018 +0000
Revision:
0:c54aeef9c92d
code for running extended time stability logging tests;

Who changed what in which revision?

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