ADC logging for temperature calibration
Dependencies: mbed MODSERIAL FastPWM ADS8568_ADC
Diff: main.cpp
- Revision:
- 4:694f0e328a52
- Parent:
- 3:447b0de4295a
- Child:
- 5:67e4ee9a00dc
--- a/main.cpp Tue Jul 31 09:18:58 2018 +0000 +++ b/main.cpp Tue Jul 31 17:25:41 2018 +0000 @@ -1,33 +1,86 @@ #include "mbed.h" -#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 +// thermal cycling settings +#define N_CYCLES 10 // number of thermal cycles (ramp-hold-ramp-hold) +#define R_SETPOINT_LOW 0.840 // heater resistance at low temp R60 +#define T_LOW_RAMP 0000 // low temperature ramp time (ms) +#define T_LOW_HOLD 2000 // low temperature hold time (ms) +#define R_SETPOINT_HIGH 0.860 // heater resistance at high temp R95 +#define T_HIGH_RAMP 0000 // high temperaure ramp time (ms) +#define T_HIGH_HOLD 2000 // high temperature time (ms) +#define T_HIGH_START 2000 // hotstart time(ms) + +// 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 2000 // heat or cool pulse width (us) +#define MEAS_DELAY 1000 // measurement delay after turning on FET (us) +#define CAM_TRIG 20 // camera trigger pulse width (us) +#define LOG_INTERVAL 100 // 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); -DigitalOut yLED(p27); -DigitalOut gLED(p28); -DigitalOut rLED(p26); +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 camTrig(p25); // 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 +SPI spi(p5, p6, p7); // mosi, miso, sclk +DigitalOut cs(p8); // chip select DigitalIn busy(p9); DigitalOut reset(p10); +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 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; -int drivetime_ms; + +void logFile(void) { + rAcc = rAcc + r; + nAcc++; + if (eTime > logTime) { + // trigger camera + camTrig = 1; + wait_us(CAM_TRIG); + camTrig = 0; -char outString[100]; + // 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; + } +} -int readChannels (char buffer[16], int values[8]){ +void readChannels (char buffer[16], int values[8]){ //simultaneously samples and reads into buffer short int val_array[8]; @@ -45,35 +98,70 @@ for (int i=0; i<8; i++){ val_array[i] = buffer[2*i]<<8 | buffer16[(2*i) + 1]; values [i] = val_array[i]; + } + r = (double)(val_array[5]-val_array[4])/(double)(val_array[1]-val_array[0]); +} + +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; } - - return 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 n_samples = 10000; - double r; - double r_max = 0; - double r_min = 1e10; - double r_sum = 0; - double r_sum2 = 0; - double r_mean; - double r_mean2; - double r_sd; - double r_cv; + int endTime = 0; rLED = 0; yLED = 0; gLED = 0; drive = 0; - drivetime_ms = 1; pc.baud(115200); - pc.printf("Test start\r\n"); - //Reset ADC sequence + reset = 1; wait_ms(1); reset = 0; @@ -84,46 +172,50 @@ spi.set_default_write_value(0x00); cs = 1; - rLED = 1; - yLED = 0; - gLED = 1; - - sprintf(outString, "I1SIG, I1REF, V1POS, V1NEG, R\r\n"); - pc.printf("%s", outString); + rLED = 1; // thermal cycling in progress + yLED = 0; // heater on + gLED = 1; // microprocessor power on - for (int x=0; x<n_samples; x++) { - drive = 1; - yLED = 1; - wait_ms(drivetime_ms); - readChannels (buffer16, val_array); - drive = 0; - yLED = 0; - - r = (double)(val_array[5]-val_array[4])/(double)(val_array[1]-val_array[0]); - if (r < r_min) { r_min = r; } - if (r > r_max) { r_max = r; } - r_sum = r_sum + r; - r_sum2 = r_sum2 + (r*r); + sprintf(outString," iCycle, Time(ms), r, rSet\n"); + pc.printf("%s", outString); + fprintf(fp, outString); + + timer.start(); + + // optional hot start: additional HIGH temperature time at start + if (T_HIGH_START > 0) { + endTime = T_HIGH_START; + rSet = R_SETPOINT_HIGH; + tempControl(endTime); + } - sprintf(outString, "%5d\t %5d\t %5d\t %5d\t %f\r\n", val_array[0], val_array[1], val_array[4], val_array[5], r); - pc.printf("%s", outString); - wait_ms(1000); + // thermocycle loop + for (iCycle = 0; iCycle < N_CYCLES; iCycle++ ) { + + // ramp up to HIGH temperature + endTime = endTime + T_HIGH_RAMP; + tempControlRamp(R_SETPOINT_LOW, R_SETPOINT_HIGH, endTime); + + // hold at HIGH temperature + endTime = endTime + T_HIGH_HOLD; + rSet = R_SETPOINT_HIGH; + tempControl(endTime); - } - - r_mean = r_sum/n_samples; - r_mean2 = r_sum2/n_samples; - r_sd = sqrt(r_mean2-(r_mean*r_mean)); - r_cv = r_sd/r_mean; - -// pc.printf("Statistics:\r\n"); -// pc.printf("n_samples : %d\r\n", n_samples); -// pc.printf("r_mean : %f\r\n", r_mean); -// pc.printf("r_min : %f\r\n", r_min); -// pc.printf("r_max : %f\r\n", r_max); -// pc.printf("r_sd : %f\r\n", r_sd); -// pc.printf("r_cv : %f\r\n", r_cv); - - rLED = 0; - - } + // ramp down to LOW temperature + endTime = endTime + T_LOW_RAMP; + tempControlRamp(R_SETPOINT_HIGH, R_SETPOINT_LOW, endTime); + + // hold at LOW temperature + endTime = endTime + T_LOW_HOLD; + rSet = R_SETPOINT_LOW; + 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); +}