Sets ticks directly for heater test

Heater.cpp

Committer:
seoirsem
Date:
2019-08-12
Revision:
23:65a9f9d85a3a
Parent:
22:2d34a03ae57e

File content as of revision 23:65a9f9d85a3a:

/*------------------------------------------------------------------------------
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 Timer timer;
extern DigitalIn adc_busy;
extern MODSERIAL pc;  
extern int log_count;
extern float R_avg;
extern DigitalOut led_0;

    
Heater::Heater(const int i_port, const int v_port, FastPWM * drive, FastPWM * guard, const float intercept, const float slope, float R_ref)
    :i_port(i_port),v_port(v_port),drive(drive),guard(guard),intercept(intercept),slope(slope) {}

void Heater::output()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;
    //float error_prev = error;
    
    double drive_prev = drive->read();     //Store previous value of drive
    //drive->period_ticks(15);         //Set period to 1us for the measurement
    //guard->period_ticks(15);
    *drive = 1.0f;              //Turn the driver on for the measurement
    //led_0 = 1;
    wait_us(MEAS_DELAY);        //Wait for ADC to settle
    //led_0 = 0;
    adc.start_conversion(ALL_CH);
    //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
    //drive->period_ticks(1000);         //Reset the period to what it was
    //guard->period_ticks(1000);


    //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;
    //error_diff = (error - error_prev)/WAIT_DELAY;
    
    //Avoid integral windup by limiting error past actuation saturation (actuator does saturate for any negative error, but  to ensure integrated error can decrease, the limit has been set to the negative of the positive limit
    //if (error*Kp > WIND_UP_LIMIT) {error_integrated += WIND_UP_LIMIT/Kp;}
    //else if (error*Kp < -WIND_UP_LIMIT) {error_integrated -= WIND_UP_LIMIT/Kp;}
    if (abs(error) < WIND_UP_LIMIT) {error_integrated += error;}
    if (error_integrated < -0.0) {error_integrated = -0.0;}

}


void Heater::hold(const 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;
    while (timer.read_ms() < end_time)
    {
        read();
        drive->period_ticks(floor((double) (Kp * (error + error_integrated/Ti))));
        guard->period_ticks((double) (Kp * GUARD_PWM_RATIO * (error + error_integrated/Ti)));
        //Output the error every LOG_LIM reads

        log_count++;
        if (log_count >= LOG_LIM)
        {
        log_count = 0;
        output();
        }
        wait_ms(WAIT_DELAY);    //Wait before reading again  
    }
}


void Heater::ramp_R(const int ramp_time, const float R_final, const float R_start)
{
    //Ramps the heater from R_start to R_final for the given hold time
    //  in: int hold_time - is the time in ms to hold the reference
    //      float R_final - is the final R_ref value
    //      float R_start - is the initial R_ref value

    int time = timer.read_ms();
    int start_time = time;
    int end_time = start_time + ramp_time;
    float ramp_rate = (R_final - R_start)/ramp_time;
    
    while (time < end_time)
    {
        Set_R_ref(R_start + ramp_rate * (time - start_time));
        hold(1);
        time = timer.read_ms();
    }
    
}


void Heater::Set_R_ref(float R)
{
    R_ref = R;
    error_integrated = 0;
}
   
float Heater::Get_R() const {return R;}


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