Used for calibration consumables

Dependencies:   mbed MODSERIAL FastPWM ADS8568_ADC

main.cpp

Committer:
justinbuckland
Date:
2018-07-31
Revision:
4:694f0e328a52
Parent:
3:447b0de4295a
Child:
5:67e4ee9a00dc

File content as of revision 4:694f0e328a52:

#include "mbed.h"

// 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);            // 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
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;

void logFile(void) {
    rAcc = rAcc + r;
    nAcc++;
    if (eTime > logTime) {
       // trigger camera 
       camTrig = 1;
       wait_us(CAM_TRIG);
       camTrig = 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];
             
    //send convert signal to channels
    convt = CH_AC;
    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];   
    }            
    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;
        }
        // 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

    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 on
    gLED = 1;  // microprocessor power on
    
    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);
    }

    // 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);
        
        // 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);     
}