Heater for threaded program

Dependents:   LEX_Threaded_Programming_V3

Heater.cpp

Committer:
intrinseca
Date:
2019-08-28
Revision:
29:dd66aa2a4925
Parent:
28:88d9088ddb8a

File content as of revision 29:dd66aa2a4925:

/*------------------------------------------------------------------------------
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 Timer timer; //remove this dependency

extern ADS8568_ADC adc; //inject
extern DigitalIn adc_busy; //inject
extern MODSERIAL pc;  //parameter of the log function

extern FastPWM drive_1; //inject the ones you want
extern FastPWM drive_2;

extern FastPWM guard_1;
extern FastPWM guard_2;

//add parameter for i and v port

Heater::Heater(const memspcr_ThermalConfiguration & thermal)
    :thermal(thermal)
{
    if (thermal.selected_heater == memspcr_ThermalConfiguration_Heater_MAIN) {
        i_port = 0;
        v_port = 1;
        drive = & drive_1;
        guard = & guard_1;
    } else if (thermal.selected_heater == memspcr_ThermalConfiguration_Heater_LYSIS) {
        i_port = 2;
        v_port = 3;
        drive = & drive_2;
        guard = & guard_2;
    } else pc.printf("Please select the desired heater channel");
    drive->prescaler(1);
    guard->prescaler(1);
    drive->period_ticks(1000);
    guard->period_ticks(1000);
}



void Heater::log()const
{
    //Prints the current state to the terminal
    pc.printf("%d,%f,%f,%f,%f,%f\n",timer.read_ms(),R_ref,R,error,error_integrated,drive->read());
}

void Heater::read()
{
    //Reads R and then resets the drive back to its previous value
    int i = 0;
    double drive_prev = drive->read();     //Store previous value of drive
    *drive = 1.0f;              //Turn the driver on for the measurement
    wait_us(thermal.adc_settling_time_us);        //Wait for ADC to settle
    adc.start_conversion(15);

    //Incremental back off until ADC is free
    while(adc_busy == 1) {
        wait_us(1);
        i++;
    }

    drive->write(0);       //Reset the duty cycle back to what it was

    //Get voltage, current and R values from the ADC conversion
    adc.read_channels();
    curr = adc.read_channel_result(i_port);
    v = adc.read_channel_result(v_port);

    if (curr > 0) {
        R = (float)v/curr;   //Avoid dividing by 0
    }

    //Get error values

    error = R_ref - R;

    //Only allow positive integrated errors and limit change in integrated error
    //to help avoid integral windup

    if (abs(error) < WIND_UP_LIMIT) {
        error_integrated += error;
    }
    if (error_integrated < 0.0) {
        error_integrated = 0.0;
    }
}




void Heater::update()
{
    //Update PWM from setpoint and resistance
    drive->write((double) (thermal.adc_settling_time_us * (error + error_integrated/thermal.pid_integral_time)));
    guard->write((double) (thermal.adc_settling_time_us * thermal.guard_drive_ratio * (error + error_integrated/thermal.pid_integral_time)));

}



void Heater::Set_ref(float R)
{
    R_ref = R;
}
void Heater::Set_D(float D)
{
    drive->write(D);
    guard->write(D*thermal.guard_drive_ratio);
}

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

float Heater::Get_R() const
{
    return R;
}

void Heater::turn_on ()
{
    *drive = 1;
    *guard = thermal.guard_drive_ratio;
}

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