Heater for threaded program

Dependents:   LEX_Threaded_Programming

Heater.cpp

Committer:
omatthews
Date:
2019-07-18
Revision:
4:29ffcc7b410e
Parent:
3:313711a66929
Child:
5:21442d9d19c5
Child:
6:71d9c10fca4a

File content as of revision 4:29ffcc7b410e:

/*------------------------------------------------------------------------------
Library code file for interface to Heater
Date: 16/07/2018


------------------------------------------------------------------------------*/
#include "mbed.h"
#include "MODSERIAL.h"
#include "Heater.h"
#include "ADS8568_ADC.h"

extern ADS8568_ADC adc;
extern float scale_factors[8];
extern Timer timer;
extern DigitalIn adc_busy;
extern MODSERIAL pc;  


    
Heater::Heater(int i_port, int v_port, DigitalOut drive, float corr_grad, float corr_int, float R_ref)
    :R_ref(R_ref),i_port(i_port),v_port(v_port),drive(drive),corr_grad(corr_grad),corr_int(corr_int) {}

float Heater::R_to_T(float R) {return R*corr_grad + corr_int;}
float Heater::T_to_R(float T) {return (T - corr_int)/corr_grad;}


void Heater::read()
{
    //Reads R and then resets the drive back to its previous value
   
    int i = 0;
    int drive_prev = drive;     //Store previous value of drive
    drive = 1;
    wait_us(50);        //Wait for ADC to settle
    adc.start_conversion(ALL_CH);
    while(adc_busy == 1)
        {
            wait_us(1);
            i++;
        }
    drive = drive_prev;
    adc.read_channels();
            
    //pc.printf("conversion took %d us\n", i );
    //i=0;
    
    curr = adc.read_channel_result(i_port);
    v = adc.read_channel_result(v_port);
    if (v<0) {pc.printf("v is %d",v);}
    if (curr > 0) {R = (float)v/curr;}        //Avoid dividing by 0
}




void Heater::hold(int hold_time)
{
    //Holds the heater at R_ref for the given hold time
    //  in: int hold_time - is the time in ms to hold the reference
    
    int end_time = timer.read_ms() + hold_time;
    float R_avg = 0;
    while (timer.read_ms() < end_time)
    {
        read();
        R_avg = ((N_ROLL_AVG-1)*R_avg + R)/N_ROLL_AVG;      //Enable rolling average
        if (R_avg > R_ref)
        {
            drive = 0;
            wait_us(100);  //Minimum duty cycle of 10%
        }
        else
        {
            drive = 1;
            //wait_us(20); //Shorter wait time as there is no cost for checking
        }
        
    }
}


void Heater::ramp_R(int ramp_time, float R_final, float R_start)
{
    int start_time = timer.read_ms();
    int end_time = start_time + ramp_time;
    float ramp_rate = (R_final - R_start)/ramp_time;
    
    while (int time = timer.read_ms() < end_time)
    {
        Set_R_ref(R_start + ramp_rate * (time - start_time)/(end_time - start_time));
        hold(1);
    }
}
    
void Heater::ramp_T(int ramp_time, float T_final, float T_start) 
{
    ramp_R(ramp_time, T_to_R(T_final), T_to_R(T_start));
}
void Heater::Set_R_ref(float R) {R_ref = R;}
void Heater::Set_T_ref(float T_ref) {R_ref = T_to_R(T_ref);}

int Heater::Get_i() {return curr;}
int Heater::Get_v() {return v;}

float Heater::Get_R() {return R;}
float Heater::Get_T() {return R_to_T(R);}

void Heater::turn_on () {drive = 1;}

void Heater::turn_off () {drive = 0;}