Heater for threaded program

Dependents:   LEX_Threaded_Programming

Committer:
omatthews
Date:
Tue Jul 30 21:32:49 2019 +0000
Revision:
19:fccdd7127f94
Parent:
18:f5d26d3d532f
Child:
20:2d34a03ae57e
Child:
22:085b53e06065
Added guards

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 1:4435d407d827 18
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 18:f5d26d3d532f 43 drive->period_us(1); //Set period to 1us for the measurement
omatthews 18:f5d26d3d532f 44 *drive = 1.0f; //Turn the driver on for the measurement
omatthews 7:59ece353eea2 45 wait_us(MEAS_DELAY); //Wait for ADC to settle
omatthews 1:4435d407d827 46 adc.start_conversion(ALL_CH);
omatthews 18:f5d26d3d532f 47 //Incremental back off until ADC is free
omatthews 1:4435d407d827 48 while(adc_busy == 1)
omatthews 1:4435d407d827 49 {
omatthews 1:4435d407d827 50 wait_us(1);
omatthews 1:4435d407d827 51 i++;
omatthews 18:f5d26d3d532f 52 }
omatthews 18:f5d26d3d532f 53 drive->write(drive_prev); //Reset the duty cycle back to what it was
omatthews 18:f5d26d3d532f 54 drive->period_us(PWM_PERIOD); //Reset the period to what it was
omatthews 17:0bfed0e96927 55
omatthews 18:f5d26d3d532f 56
omatthews 18:f5d26d3d532f 57 //Get voltage, current and R values from the ADC conversion
omatthews 0:4e33cc8171f4 58 adc.read_channels();
omatthews 7:59ece353eea2 59 curr = adc.read_channel_result(i_port);
omatthews 7:59ece353eea2 60 v = adc.read_channel_result(v_port);
omatthews 18:f5d26d3d532f 61
omatthews 17:0bfed0e96927 62 if (curr > 0) {R = (float)v/curr;} //Avoid dividing by 0
omatthews 12:8a048f111140 63
omatthews 18:f5d26d3d532f 64 //Get error values
omatthews 18:f5d26d3d532f 65
omatthews 17:0bfed0e96927 66 error = R_ref - R;
omatthews 18:f5d26d3d532f 67 //error_diff = (error - error_prev)/WAIT_DELAY;
omatthews 14:f266bf960b8d 68
omatthews 19:fccdd7127f94 69 //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 70 //if (error*Kp > WIND_UP_LIMIT) {error_integrated += WIND_UP_LIMIT/Kp;}
omatthews 19:fccdd7127f94 71 //else if (error*Kp < -WIND_UP_LIMIT) {error_integrated -= WIND_UP_LIMIT/Kp;}
omatthews 19:fccdd7127f94 72 if (error < WIND_UP_LIMIT && error > -WIND_UP_LIMIT) {error_integrated += error;}
omatthews 14:f266bf960b8d 73
omatthews 14:f266bf960b8d 74
omatthews 18:f5d26d3d532f 75 //Output the error every LOG_LIM reads
omatthews 11:785a0329f802 76 log_count++;
omatthews 18:f5d26d3d532f 77 if (log_count >= LOG_LIM)
omatthews 11:785a0329f802 78 {
omatthews 11:785a0329f802 79 log_count = 0;
omatthews 11:785a0329f802 80 output();
omatthews 11:785a0329f802 81 }
omatthews 0:4e33cc8171f4 82 }
omatthews 0:4e33cc8171f4 83
omatthews 2:7f15386fcc90 84
omatthews 2:7f15386fcc90 85
omatthews 2:7f15386fcc90 86
omatthews 18:f5d26d3d532f 87 void Heater::hold(const int hold_time)
omatthews 0:4e33cc8171f4 88 {
omatthews 7:59ece353eea2 89 //Holds the heater at R_ref for the given hold time
omatthews 7:59ece353eea2 90 // in: int hold_time - is the time in ms to hold the reference
omatthews 7:59ece353eea2 91
omatthews 0:4e33cc8171f4 92 int end_time = timer.read_ms() + hold_time;
omatthews 1:4435d407d827 93 while (timer.read_ms() < end_time)
omatthews 0:4e33cc8171f4 94 {
omatthews 2:7f15386fcc90 95 read();
omatthews 17:0bfed0e96927 96 drive->write((double) (Kp * (error + error_integrated/Ti)));
omatthews 19:fccdd7127f94 97 guard->write((double) (Kp * GUARD_PWM_RATIO * (error + error_integrated/Ti)));
omatthews 18:f5d26d3d532f 98 wait_ms(WAIT_DELAY); //Wait before reading again
omatthews 0:4e33cc8171f4 99 }
omatthews 1:4435d407d827 100 }
omatthews 1:4435d407d827 101
omatthews 0:4e33cc8171f4 102
omatthews 18:f5d26d3d532f 103 void Heater::ramp_R(const int ramp_time, const float R_final, const float R_start)
omatthews 7:59ece353eea2 104 {
omatthews 18:f5d26d3d532f 105 //Ramps the heater from R_start to R_final for the given hold time
omatthews 18:f5d26d3d532f 106 // in: int hold_time - is the time in ms to hold the reference
omatthews 18:f5d26d3d532f 107 // float R_final - is the final R_ref value
omatthews 18:f5d26d3d532f 108 // float R_start - is the initial R_ref value
omatthews 18:f5d26d3d532f 109
omatthews 8:5da71ae16115 110 int time = timer.read_ms();
omatthews 8:5da71ae16115 111 int start_time = time;
omatthews 7:59ece353eea2 112 int end_time = start_time + ramp_time;
omatthews 7:59ece353eea2 113 float ramp_rate = (R_final - R_start)/ramp_time;
omatthews 7:59ece353eea2 114
omatthews 8:5da71ae16115 115 while (time < end_time)
omatthews 7:59ece353eea2 116 {
omatthews 8:5da71ae16115 117 Set_R_ref(R_start + ramp_rate * (time - start_time));
omatthews 7:59ece353eea2 118 hold(1);
omatthews 8:5da71ae16115 119 time = timer.read_ms();
omatthews 7:59ece353eea2 120 }
omatthews 8:5da71ae16115 121
omatthews 7:59ece353eea2 122 }
omatthews 7:59ece353eea2 123
omatthews 18:f5d26d3d532f 124 void Heater::ramp_T(const int ramp_time, const float T_final, const float T_start)
omatthews 7:59ece353eea2 125 {
omatthews 18:f5d26d3d532f 126 //Ramps the heater from T_start to T_final for the given hold time
omatthews 18:f5d26d3d532f 127 // in: int hold_time - is the time in ms to hold the reference
omatthews 18:f5d26d3d532f 128 // float T_final - is the final T_ref value
omatthews 18:f5d26d3d532f 129 // float T_start - is the initial T_ref value
omatthews 7:59ece353eea2 130 ramp_R(ramp_time, T_to_R(T_final), T_to_R(T_start));
omatthews 7:59ece353eea2 131 }
omatthews 18:f5d26d3d532f 132
omatthews 18:f5d26d3d532f 133
omatthews 18:f5d26d3d532f 134
omatthews 19:fccdd7127f94 135 void Heater::Set_R_ref(float R)
omatthews 19:fccdd7127f94 136 {
omatthews 19:fccdd7127f94 137 R_ref = R;
omatthews 19:fccdd7127f94 138 error_integrated = 0;
omatthews 19:fccdd7127f94 139 }
omatthews 7:59ece353eea2 140 void Heater::Set_T_ref(float T_ref) {R_ref = T_to_R(T_ref);}
omatthews 16:cd837b230b09 141 void Heater::Set_D(float D) {drive->write(D);}
omatthews 0:4e33cc8171f4 142
omatthews 18:f5d26d3d532f 143 int Heater::Get_i() const {return curr;}
omatthews 18:f5d26d3d532f 144 int Heater::Get_v() const {return v;}
omatthews 2:7f15386fcc90 145
omatthews 18:f5d26d3d532f 146 float Heater::Get_R() const {return R;}
omatthews 18:f5d26d3d532f 147 float Heater::Get_T() const {return R_to_T(R);}
omatthews 0:4e33cc8171f4 148
omatthews 19:fccdd7127f94 149 void Heater::turn_on ()
omatthews 19:fccdd7127f94 150 {
omatthews 19:fccdd7127f94 151 *drive = 1;
omatthews 19:fccdd7127f94 152 *guard = GUARD_PWM_RATIO;
omatthews 19:fccdd7127f94 153 }
omatthews 1:4435d407d827 154
omatthews 19:fccdd7127f94 155 void Heater::turn_off ()
omatthews 19:fccdd7127f94 156 {
omatthews 19:fccdd7127f94 157 *drive = 0;
omatthews 19:fccdd7127f94 158 *guard = 0;
omatthews 19:fccdd7127f94 159 }