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

Dependencies:   mbed

main.cpp

Committer:
AlexStokoe
Date:
2018-09-24
Revision:
0:c54aeef9c92d

File content as of revision 0:c54aeef9c92d:

#include "mbed.h"

// thermal cycling settings
#define N_CYCLES             1     // number of thermal cycles (ramp-hold-ramp-hold)
#define R_SETPOINT_LOW  0.9800     // heater resistance at low temp R60
#define T_LOW_RAMP       10000     // low temperature ramp time (ms)
#define T_LOW_HOLD         500     // low temperature hold time (ms)
#define R_SETPOINT_HIGH    1.1     // heater resistance at high temp R95
#define T_HIGH_RAMP      10000     // high temperaure ramp time (ms)
#define T_HIGH_HOLD      10000     // high temperature time (ms)
#define T_HIGH_START      0000     // 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       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 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);

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, "$%1.6f$\n",rAcc/nAcc); // 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,"$r$\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);
    }

    // loop forever
    while(1) {
        
        
        // hold at HIGH temperature
        endTime = endTime + T_HIGH_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);     
}