Heater files
Dependents: LEX-Demo-Firmware-Logging LEX-Demo-Firmware-Logging
Heater.cpp
- Committer:
- omatthews
- Date:
- 2019-07-28
- Revision:
- 18:f5d26d3d532f
- Parent:
- 17:0bfed0e96927
- Child:
- 19:fccdd7127f94
File content as of revision 18:f5d26d3d532f:
/*------------------------------------------------------------------------------ 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; Heater::Heater(const int i_port, const int v_port, FastPWM * drive, const float corr_grad, const 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) {} // Convert from R to T using the linear relationship - T = R * corr_grad + corr_int float Heater::R_to_T(const float R) const {return R*corr_grad + corr_int;} float Heater::T_to_R(const float T) const {return (T - corr_int)/corr_grad;} 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_us(1); //Set period to 1us for the measurement *drive = 1.0f; //Turn the driver on for the measurement wait_us(MEAS_DELAY); //Wait for ADC to settle adc.start_conversion(ALL_CH); //Incremental back off until ADC is free while(adc_busy == 1) { wait_us(1); i++; } drive->write(drive_prev); //Reset the duty cycle back to what it was drive->period_us(PWM_PERIOD); //Reset the period 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; //error_diff = (error - error_prev)/WAIT_DELAY; //Avoid integral windup by limiting integral error past actuation saturation 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;} else {error_integrated += error;} //Output the error every LOG_LIM reads log_count++; if (log_count >= LOG_LIM) { log_count = 0; output(); } } 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->write((double) (Kp * (error + error_integrated/Ti))); 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::ramp_T(const int ramp_time, const float T_final, const float T_start) { //Ramps the heater from T_start to T_final for the given hold time // in: int hold_time - is the time in ms to hold the reference // float T_final - is the final T_ref value // float T_start - is the initial T_ref value 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);} void Heater::Set_D(float D) {drive->write(D);} int Heater::Get_i() const {return curr;} int Heater::Get_v() const {return v;} float Heater::Get_R() const {return R;} float Heater::Get_T() const {return R_to_T(R);} void Heater::turn_on () {*drive = 1;} void Heater::turn_off () {*drive = 0;}