Heater for threaded program

Dependents:   LEX_Threaded_Programming

Committer:
omatthews
Date:
Wed Aug 07 16:37:10 2019 +0000
Revision:
23:947850bbf325
Parent:
20:2d34a03ae57e
Child:
25:09a315a59956
Updated gains

Who changed what in which revision?

UserRevisionLine numberNew contents of line
omatthews 0:4e33cc8171f4 1 /*------------------------------------------------------------------------------
omatthews 0:4e33cc8171f4 2 Library code file for interface to Heater
omatthews 0:4e33cc8171f4 3 Date: 16/07/2018
omatthews 0:4e33cc8171f4 4
omatthews 0:4e33cc8171f4 5
omatthews 0:4e33cc8171f4 6 ------------------------------------------------------------------------------*/
omatthews 1:4435d407d827 7 #include "mbed.h"
omatthews 1:4435d407d827 8 #include "MODSERIAL.h"
omatthews 0:4e33cc8171f4 9 #include "Heater.h"
omatthews 0:4e33cc8171f4 10 #include "ADS8568_ADC.h"
omatthews 0:4e33cc8171f4 11
omatthews 0:4e33cc8171f4 12 extern ADS8568_ADC adc;
omatthews 0:4e33cc8171f4 13 extern Timer timer;
omatthews 1:4435d407d827 14 extern DigitalIn adc_busy;
omatthews 1:4435d407d827 15 extern MODSERIAL pc;
omatthews 11:785a0329f802 16 extern int log_count;
omatthews 11:785a0329f802 17 extern float R_avg;
omatthews 20:2d34a03ae57e 18 extern DigitalOut led_0;
omatthews 0:4e33cc8171f4 19
omatthews 0:4e33cc8171f4 20
omatthews 19:fccdd7127f94 21 Heater::Heater(const int i_port, const int v_port, FastPWM * drive, FastPWM * guard, const float corr_grad, const float corr_int, float R_ref)
omatthews 19:fccdd7127f94 22 :R_ref(R_ref),i_port(i_port),v_port(v_port),drive(drive),guard(guard),corr_grad(corr_grad),corr_int(corr_int) {}
omatthews 7:59ece353eea2 23
omatthews 0:4e33cc8171f4 24
omatthews 18:f5d26d3d532f 25 // Convert from R to T using the linear relationship - T = R * corr_grad + corr_int
omatthews 18:f5d26d3d532f 26 float Heater::R_to_T(const float R) const {return R*corr_grad + corr_int;}
omatthews 18:f5d26d3d532f 27 float Heater::T_to_R(const float T) const {return (T - corr_int)/corr_grad;}
omatthews 18:f5d26d3d532f 28
omatthews 18:f5d26d3d532f 29 void Heater::output()const
omatthews 11:785a0329f802 30 {
omatthews 18:f5d26d3d532f 31 //Prints the current state to the terminal
omatthews 17:0bfed0e96927 32 pc.printf("%d,%f,%f,%f,%f,%f\n",timer.read_ms(),R_ref,R,error,error_integrated,drive->read());
omatthews 11:785a0329f802 33 }
omatthews 0:4e33cc8171f4 34
omatthews 2:7f15386fcc90 35 void Heater::read()
omatthews 0:4e33cc8171f4 36 {
omatthews 1:4435d407d827 37 //Reads R and then resets the drive back to its previous value
omatthews 17:0bfed0e96927 38
omatthews 1:4435d407d827 39 int i = 0;
omatthews 18:f5d26d3d532f 40 //float error_prev = error;
omatthews 17:0bfed0e96927 41
omatthews 17:0bfed0e96927 42 double drive_prev = drive->read(); //Store previous value of drive
omatthews 20:2d34a03ae57e 43 //drive->period_ticks(15); //Set period to 1us for the measurement
omatthews 20:2d34a03ae57e 44 //guard->period_ticks(15);
omatthews 18:f5d26d3d532f 45 *drive = 1.0f; //Turn the driver on for the measurement
omatthews 20:2d34a03ae57e 46 //led_0 = 1;
omatthews 7:59ece353eea2 47 wait_us(MEAS_DELAY); //Wait for ADC to settle
omatthews 20:2d34a03ae57e 48 //led_0 = 0;
omatthews 1:4435d407d827 49 adc.start_conversion(ALL_CH);
omatthews 18:f5d26d3d532f 50 //Incremental back off until ADC is free
omatthews 1:4435d407d827 51 while(adc_busy == 1)
omatthews 1:4435d407d827 52 {
omatthews 1:4435d407d827 53 wait_us(1);
omatthews 1:4435d407d827 54 i++;
omatthews 18:f5d26d3d532f 55 }
omatthews 20:2d34a03ae57e 56 drive->write(0); //Reset the duty cycle back to what it was
omatthews 20:2d34a03ae57e 57 //drive->period_ticks(1000); //Reset the period to what it was
omatthews 20:2d34a03ae57e 58 //guard->period_ticks(1000);
omatthews 17:0bfed0e96927 59
omatthews 18:f5d26d3d532f 60
omatthews 18:f5d26d3d532f 61 //Get voltage, current and R values from the ADC conversion
omatthews 0:4e33cc8171f4 62 adc.read_channels();
omatthews 7:59ece353eea2 63 curr = adc.read_channel_result(i_port);
omatthews 7:59ece353eea2 64 v = adc.read_channel_result(v_port);
omatthews 18:f5d26d3d532f 65
omatthews 17:0bfed0e96927 66 if (curr > 0) {R = (float)v/curr;} //Avoid dividing by 0
omatthews 12:8a048f111140 67
omatthews 18:f5d26d3d532f 68 //Get error values
omatthews 18:f5d26d3d532f 69
omatthews 17:0bfed0e96927 70 error = R_ref - R;
omatthews 18:f5d26d3d532f 71 //error_diff = (error - error_prev)/WAIT_DELAY;
omatthews 14:f266bf960b8d 72
omatthews 19:fccdd7127f94 73 //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
omatthews 19:fccdd7127f94 74 //if (error*Kp > WIND_UP_LIMIT) {error_integrated += WIND_UP_LIMIT/Kp;}
omatthews 19:fccdd7127f94 75 //else if (error*Kp < -WIND_UP_LIMIT) {error_integrated -= WIND_UP_LIMIT/Kp;}
omatthews 20:2d34a03ae57e 76 if (abs(error) < WIND_UP_LIMIT) {error_integrated += error;}
omatthews 23:947850bbf325 77 if (error_integrated < 0.0) {error_integrated = 0.0;}
omatthews 20:2d34a03ae57e 78
omatthews 0:4e33cc8171f4 79 }
omatthews 0:4e33cc8171f4 80
omatthews 2:7f15386fcc90 81
omatthews 2:7f15386fcc90 82
omatthews 2:7f15386fcc90 83
omatthews 18:f5d26d3d532f 84 void Heater::hold(const int hold_time)
omatthews 0:4e33cc8171f4 85 {
omatthews 7:59ece353eea2 86 //Holds the heater at R_ref for the given hold time
omatthews 7:59ece353eea2 87 // in: int hold_time - is the time in ms to hold the reference
omatthews 7:59ece353eea2 88
omatthews 0:4e33cc8171f4 89 int end_time = timer.read_ms() + hold_time;
omatthews 1:4435d407d827 90 while (timer.read_ms() < end_time)
omatthews 0:4e33cc8171f4 91 {
omatthews 2:7f15386fcc90 92 read();
omatthews 17:0bfed0e96927 93 drive->write((double) (Kp * (error + error_integrated/Ti)));
omatthews 19:fccdd7127f94 94 guard->write((double) (Kp * GUARD_PWM_RATIO * (error + error_integrated/Ti)));
omatthews 20:2d34a03ae57e 95 //Output the error every LOG_LIM reads
omatthews 20:2d34a03ae57e 96
omatthews 20:2d34a03ae57e 97 log_count++;
omatthews 20:2d34a03ae57e 98 if (log_count >= LOG_LIM)
omatthews 20:2d34a03ae57e 99 {
omatthews 20:2d34a03ae57e 100 log_count = 0;
omatthews 20:2d34a03ae57e 101 output();
omatthews 20:2d34a03ae57e 102 }
omatthews 18:f5d26d3d532f 103 wait_ms(WAIT_DELAY); //Wait before reading again
omatthews 0:4e33cc8171f4 104 }
omatthews 1:4435d407d827 105 }
omatthews 1:4435d407d827 106
omatthews 0:4e33cc8171f4 107
omatthews 18:f5d26d3d532f 108 void Heater::ramp_R(const int ramp_time, const float R_final, const float R_start)
omatthews 7:59ece353eea2 109 {
omatthews 18:f5d26d3d532f 110 //Ramps the heater from R_start to R_final for the given hold time
omatthews 18:f5d26d3d532f 111 // in: int hold_time - is the time in ms to hold the reference
omatthews 18:f5d26d3d532f 112 // float R_final - is the final R_ref value
omatthews 18:f5d26d3d532f 113 // float R_start - is the initial R_ref value
omatthews 18:f5d26d3d532f 114
omatthews 8:5da71ae16115 115 int time = timer.read_ms();
omatthews 8:5da71ae16115 116 int start_time = time;
omatthews 7:59ece353eea2 117 int end_time = start_time + ramp_time;
omatthews 7:59ece353eea2 118 float ramp_rate = (R_final - R_start)/ramp_time;
omatthews 7:59ece353eea2 119
omatthews 8:5da71ae16115 120 while (time < end_time)
omatthews 7:59ece353eea2 121 {
omatthews 8:5da71ae16115 122 Set_R_ref(R_start + ramp_rate * (time - start_time));
omatthews 7:59ece353eea2 123 hold(1);
omatthews 8:5da71ae16115 124 time = timer.read_ms();
omatthews 7:59ece353eea2 125 }
omatthews 8:5da71ae16115 126
omatthews 7:59ece353eea2 127 }
omatthews 7:59ece353eea2 128
omatthews 18:f5d26d3d532f 129 void Heater::ramp_T(const int ramp_time, const float T_final, const float T_start)
omatthews 7:59ece353eea2 130 {
omatthews 18:f5d26d3d532f 131 //Ramps the heater from T_start to T_final for the given hold time
omatthews 18:f5d26d3d532f 132 // in: int hold_time - is the time in ms to hold the reference
omatthews 18:f5d26d3d532f 133 // float T_final - is the final T_ref value
omatthews 18:f5d26d3d532f 134 // float T_start - is the initial T_ref value
omatthews 7:59ece353eea2 135 ramp_R(ramp_time, T_to_R(T_final), T_to_R(T_start));
omatthews 7:59ece353eea2 136 }
omatthews 18:f5d26d3d532f 137
omatthews 18:f5d26d3d532f 138
omatthews 18:f5d26d3d532f 139
omatthews 19:fccdd7127f94 140 void Heater::Set_R_ref(float R)
omatthews 19:fccdd7127f94 141 {
omatthews 19:fccdd7127f94 142 R_ref = R;
omatthews 19:fccdd7127f94 143 error_integrated = 0;
omatthews 19:fccdd7127f94 144 }
omatthews 7:59ece353eea2 145 void Heater::Set_T_ref(float T_ref) {R_ref = T_to_R(T_ref);}
omatthews 16:cd837b230b09 146 void Heater::Set_D(float D) {drive->write(D);}
omatthews 0:4e33cc8171f4 147
omatthews 18:f5d26d3d532f 148 int Heater::Get_i() const {return curr;}
omatthews 18:f5d26d3d532f 149 int Heater::Get_v() const {return v;}
omatthews 2:7f15386fcc90 150
omatthews 18:f5d26d3d532f 151 float Heater::Get_R() const {return R;}
omatthews 18:f5d26d3d532f 152 float Heater::Get_T() const {return R_to_T(R);}
omatthews 0:4e33cc8171f4 153
omatthews 19:fccdd7127f94 154 void Heater::turn_on ()
omatthews 19:fccdd7127f94 155 {
omatthews 19:fccdd7127f94 156 *drive = 1;
omatthews 19:fccdd7127f94 157 *guard = GUARD_PWM_RATIO;
omatthews 19:fccdd7127f94 158 }
omatthews 1:4435d407d827 159
omatthews 19:fccdd7127f94 160 void Heater::turn_off ()
omatthews 19:fccdd7127f94 161 {
omatthews 19:fccdd7127f94 162 *drive = 0;
omatthews 19:fccdd7127f94 163 *guard = 0;
omatthews 19:fccdd7127f94 164 }