Heater for threaded program

Dependents:   LEX_Threaded_Programming_V3

Committer:
justinbuckland
Date:
Mon Mar 09 15:26:53 2020 +0000
Revision:
49:35fd40559960
Parent:
48:cd2a9b799e89
Child:
50:ad9a1eb063b3
no change

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
justinbuckland 35:5acf01897ed6 12 Heater::Heater(const int i_port, const int v_port, const float cal_a, const float cal_b, FastPWM * drive, FastPWM * guard, ADS8568_ADC * adc, DigitalIn adc_busy, const memspcr_ThermalConfiguration & thermal)
justinbuckland 35:5acf01897ed6 13 :thermal(thermal), i_port(i_port), v_port(v_port), cal_a(cal_a), cal_b(cal_b), drive(drive), guard(guard), adc(adc), adc_busy(adc_busy)
omatthews 30:055d856f05b5 14 {
justinbuckland 42:166d9bc7675e 15 //Set up PWM
omatthews 30:055d856f05b5 16 drive->prescaler(1);
omatthews 30:055d856f05b5 17 guard->prescaler(1);
omatthews 30:055d856f05b5 18 drive->period_ticks(1000);
omatthews 30:055d856f05b5 19 guard->period_ticks(1000);
justinbuckland 42:166d9bc7675e 20
justinbuckland 42:166d9bc7675e 21 //Initialise values for averaging resistance
justinbuckland 42:166d9bc7675e 22 n_acc = 0;
justinbuckland 42:166d9bc7675e 23 R_acc = 0;
justinbuckland 46:47c394467c66 24 R_smooth = 0;
justinbuckland 45:5f588512529b 25 R2_acc = 0;
omatthews 30:055d856f05b5 26 }
omatthews 30:055d856f05b5 27
omatthews 2:7f15386fcc90 28 void Heater::read()
omatthews 0:4e33cc8171f4 29 {
omatthews 1:4435d407d827 30 //Reads R and then resets the drive back to its previous value
omatthews 30:055d856f05b5 31 int i = 0;
omatthews 17:0bfed0e96927 32 double drive_prev = drive->read(); //Store previous value of drive
justinbuckland 35:5acf01897ed6 33
justinbuckland 44:e358867319f6 34 *drive = 1.0f; //Turn the driver on for the measurement
justinbuckland 44:e358867319f6 35 wait_us(thermal.settling_time_us); //Wait for ADC to settle
justinbuckland 34:294adcc3e4b2 36 adc->start_conversion(ADC_CONV_ALL_CH);
justinbuckland 34:294adcc3e4b2 37
omatthews 18:f5d26d3d532f 38 //Incremental back off until ADC is free
omatthews 30:055d856f05b5 39 while(adc_busy == 1) {
omatthews 30:055d856f05b5 40 wait_us(1);
omatthews 30:055d856f05b5 41 i++;
omatthews 30:055d856f05b5 42 }
omatthews 25:09a315a59956 43
justinbuckland 44:e358867319f6 44 drive->write(0); //Reset the duty cycle back to what it was
omatthews 18:f5d26d3d532f 45
omatthews 18:f5d26d3d532f 46 //Get voltage, current and R values from the ADC conversion
omatthews 31:7c6f05326c4d 47 adc->read_channels();
omatthews 31:7c6f05326c4d 48 curr = adc->read_channel_result(i_port);
omatthews 31:7c6f05326c4d 49 v = adc->read_channel_result(v_port);
omatthews 30:055d856f05b5 50
justinbuckland 35:5acf01897ed6 51 if (curr > 0) { //Avoid dividing by 0
justinbuckland 35:5acf01897ed6 52 R = (float)v/curr;
justinbuckland 35:5acf01897ed6 53 R = cal_a + cal_b*R; //Convert to Ohms
omatthews 30:055d856f05b5 54 }
justinbuckland 42:166d9bc7675e 55
justinbuckland 45:5f588512529b 56 // Calculate accumulated resistance values for R_avg and R_var output
justinbuckland 46:47c394467c66 57 R_smooth = R_SMOOTH_FACTOR*R_smooth + (1-R_SMOOTH_FACTOR)*R;
justinbuckland 42:166d9bc7675e 58 R_acc = R_acc + R;
justinbuckland 46:47c394467c66 59 R2_acc = R2_acc + R*R;
justinbuckland 42:166d9bc7675e 60 n_acc ++;
justinbuckland 35:5acf01897ed6 61
omatthews 0:4e33cc8171f4 62 }
omatthews 0:4e33cc8171f4 63
omatthews 25:09a315a59956 64 void Heater::update()
omatthews 7:59ece353eea2 65 {
justinbuckland 44:e358867319f6 66
justinbuckland 41:b1602c68abcd 67 //Get error
justinbuckland 48:cd2a9b799e89 68 //error = R_ref - R; // use single reading R values
justinbuckland 48:cd2a9b799e89 69 error = R_ref - R_smooth; // use smoothed R values
justinbuckland 41:b1602c68abcd 70
omatthews 25:09a315a59956 71 //Update PWM from setpoint and resistance
paullj 39:5dffedda7a0d 72 double duty_cycle = thermal.pid_kp_mho * error;
justinbuckland 41:b1602c68abcd 73
justinbuckland 48:cd2a9b799e89 74 //Integral term (if used)
justinbuckland 48:cd2a9b799e89 75 if (thermal.pid_integral_time_ms > 0) { // set integral time to zero to have no integral term
justinbuckland 49:35fd40559960 76 // if (abs(error) > thermal.pid_wind_up_limit_ohm) error = error * thermal.pid_wind_up_limit_ohm / abs(error); // don't use pid_wind_up_limit
justinbuckland 41:b1602c68abcd 77 error_integrated += error * (float) thermal.thermal_control_loop_interval_ms;
paullj 39:5dffedda7a0d 78 duty_cycle += thermal.pid_kp_mho * error_integrated/thermal.pid_integral_time_ms;
justinbuckland 48:cd2a9b799e89 79 }
justinbuckland 44:e358867319f6 80
justinbuckland 49:35fd40559960 81 if (duty_cycle > thermal.pid_pwm_limit) {
paullj 39:5dffedda7a0d 82 duty_cycle = thermal.pid_pwm_limit;
justinbuckland 49:35fd40559960 83 error_integrated = 0; // zero error_integrated if system is outside linear control range
justinbuckland 49:35fd40559960 84 }
justinbuckland 49:35fd40559960 85 else if (duty_cycle < 0) {
paullj 39:5dffedda7a0d 86 duty_cycle = 0;
justinbuckland 49:35fd40559960 87 error_integrated = 0; // zero error_integrated if system is outside linear control range
justinbuckland 49:35fd40559960 88 }
justinbuckland 36:a8130bd29349 89
omatthews 31:7c6f05326c4d 90 drive->write(duty_cycle);
justinbuckland 44:e358867319f6 91 guard->write(duty_cycle * thermal.guard_drive_ratio);
omatthews 7:59ece353eea2 92 }
omatthews 18:f5d26d3d532f 93
omatthews 30:055d856f05b5 94 void Heater::Set_ref(float R)
omatthews 19:fccdd7127f94 95 {
omatthews 19:fccdd7127f94 96 R_ref = R;
omatthews 19:fccdd7127f94 97 }
omatthews 30:055d856f05b5 98 void Heater::Set_D(float D)
omatthews 30:055d856f05b5 99 {
omatthews 25:09a315a59956 100 drive->write(D);
omatthews 26:f6c98b05ee85 101 guard->write(D*thermal.guard_drive_ratio);
omatthews 30:055d856f05b5 102 }
omatthews 0:4e33cc8171f4 103
justinbuckland 42:166d9bc7675e 104 float Heater::Get_D() const
omatthews 31:7c6f05326c4d 105 {
omatthews 31:7c6f05326c4d 106 return drive->read();
omatthews 31:7c6f05326c4d 107 }
omatthews 31:7c6f05326c4d 108
omatthews 30:055d856f05b5 109 int Heater::Get_i() const
omatthews 30:055d856f05b5 110 {
omatthews 30:055d856f05b5 111 return curr;
omatthews 30:055d856f05b5 112 }
omatthews 30:055d856f05b5 113 int Heater::Get_v() const
omatthews 30:055d856f05b5 114 {
omatthews 30:055d856f05b5 115 return v;
omatthews 30:055d856f05b5 116 }
omatthews 2:7f15386fcc90 117
omatthews 30:055d856f05b5 118 float Heater::Get_R() const
omatthews 30:055d856f05b5 119 {
omatthews 30:055d856f05b5 120 return R;
omatthews 30:055d856f05b5 121 }
omatthews 0:4e33cc8171f4 122
justinbuckland 42:166d9bc7675e 123 float Heater::Get_R_avg()
justinbuckland 42:166d9bc7675e 124 {
justinbuckland 42:166d9bc7675e 125 R_avg = R_acc / (float) n_acc;
justinbuckland 42:166d9bc7675e 126 return R_avg;
justinbuckland 42:166d9bc7675e 127 }
justinbuckland 42:166d9bc7675e 128
justinbuckland 45:5f588512529b 129 float Heater::Get_R_var() // need to call Get_R_avg to calculate R_var before calling this function
justinbuckland 45:5f588512529b 130 {
justinbuckland 47:06a9691d0a7b 131 R_var = R2_acc / (float) n_acc - R_avg * R_avg;
justinbuckland 47:06a9691d0a7b 132 R_acc = 0;
justinbuckland 47:06a9691d0a7b 133 R2_acc = 0;
justinbuckland 47:06a9691d0a7b 134 n_acc = 0;
justinbuckland 45:5f588512529b 135 return R_var;
justinbuckland 45:5f588512529b 136 }
justinbuckland 45:5f588512529b 137
omatthews 31:7c6f05326c4d 138 float Heater::Get_R_ref() const
omatthews 31:7c6f05326c4d 139 {
omatthews 31:7c6f05326c4d 140 return R_ref;
omatthews 31:7c6f05326c4d 141 }
omatthews 31:7c6f05326c4d 142
omatthews 31:7c6f05326c4d 143 float Heater::Get_error() const
omatthews 31:7c6f05326c4d 144 {
omatthews 31:7c6f05326c4d 145 return error;
omatthews 31:7c6f05326c4d 146 }
omatthews 31:7c6f05326c4d 147
omatthews 31:7c6f05326c4d 148 float Heater::Get_error_integrated() const
omatthews 31:7c6f05326c4d 149 {
omatthews 31:7c6f05326c4d 150 return error_integrated;
omatthews 31:7c6f05326c4d 151 }
omatthews 31:7c6f05326c4d 152
omatthews 30:055d856f05b5 153 void Heater::turn_on ()
omatthews 19:fccdd7127f94 154 {
omatthews 19:fccdd7127f94 155 *drive = 1;
omatthews 26:f6c98b05ee85 156 *guard = thermal.guard_drive_ratio;
omatthews 19:fccdd7127f94 157 }
omatthews 1:4435d407d827 158
omatthews 30:055d856f05b5 159 void Heater::turn_off ()
omatthews 19:fccdd7127f94 160 {
omatthews 19:fccdd7127f94 161 *drive = 0;
omatthews 19:fccdd7127f94 162 *guard = 0;
omatthews 19:fccdd7127f94 163 }