Heater for threaded program
Dependents: LEX_Threaded_Programming_V3
Heater.cpp@43:d34ac9d8648c, 2019-11-11 (annotated)
- Committer:
- justinbuckland
- Date:
- Mon Nov 11 08:29:51 2019 +0000
- Revision:
- 43:d34ac9d8648c
- Parent:
- 42:166d9bc7675e
- Child:
- 44:e358867319f6
no change
Who changed what in which revision?
User | Revision | Line number | New 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 | 43:d34ac9d8648c | 12 | #define GUARD_DUTY_CYCLE_REF 0.1 // start to reduce guard drive ratio at this duty cycle for main heater |
justinbuckland | 43:d34ac9d8648c | 13 | #define GUARD_DUTY_CYCLE_SLOPE 0.5 // slope for reducing guard drive ratio at increasing duty cycle for main heater |
justinbuckland | 43:d34ac9d8648c | 14 | |
justinbuckland | 35:5acf01897ed6 | 15 | 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 | 16 | :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 | 17 | { |
justinbuckland | 42:166d9bc7675e | 18 | //Set up PWM |
omatthews | 30:055d856f05b5 | 19 | drive->prescaler(1); |
omatthews | 30:055d856f05b5 | 20 | guard->prescaler(1); |
omatthews | 30:055d856f05b5 | 21 | drive->period_ticks(1000); |
omatthews | 30:055d856f05b5 | 22 | guard->period_ticks(1000); |
justinbuckland | 42:166d9bc7675e | 23 | |
justinbuckland | 42:166d9bc7675e | 24 | //Initialise values for averaging resistance |
justinbuckland | 42:166d9bc7675e | 25 | n_acc = 0; |
justinbuckland | 42:166d9bc7675e | 26 | R_acc = 0; |
omatthews | 30:055d856f05b5 | 27 | } |
omatthews | 30:055d856f05b5 | 28 | |
omatthews | 2:7f15386fcc90 | 29 | void Heater::read() |
omatthews | 0:4e33cc8171f4 | 30 | { |
omatthews | 1:4435d407d827 | 31 | //Reads R and then resets the drive back to its previous value |
omatthews | 30:055d856f05b5 | 32 | int i = 0; |
justinbuckland | 43:d34ac9d8648c | 33 | int guard_wait_us; |
justinbuckland | 43:d34ac9d8648c | 34 | int main_wait_us; |
justinbuckland | 43:d34ac9d8648c | 35 | |
omatthews | 17:0bfed0e96927 | 36 | double drive_prev = drive->read(); //Store previous value of drive |
justinbuckland | 35:5acf01897ed6 | 37 | |
justinbuckland | 43:d34ac9d8648c | 38 | guard_wait_us = (float)thermal.settling_time_us * thermal.guard_drive_ratio; |
justinbuckland | 43:d34ac9d8648c | 39 | main_wait_us = thermal.settling_time_us - guard_wait_us; |
justinbuckland | 43:d34ac9d8648c | 40 | |
justinbuckland | 43:d34ac9d8648c | 41 | *drive = 1.0f; //Turn the main heater on for the measurement |
justinbuckland | 43:d34ac9d8648c | 42 | |
justinbuckland | 43:d34ac9d8648c | 43 | wait_us(main_wait_us); //Wait for ADC to settle |
justinbuckland | 34:294adcc3e4b2 | 44 | adc->start_conversion(ADC_CONV_ALL_CH); |
justinbuckland | 34:294adcc3e4b2 | 45 | |
omatthews | 18:f5d26d3d532f | 46 | //Incremental back off until ADC is free |
omatthews | 30:055d856f05b5 | 47 | while(adc_busy == 1) { |
omatthews | 30:055d856f05b5 | 48 | wait_us(1); |
omatthews | 30:055d856f05b5 | 49 | i++; |
omatthews | 30:055d856f05b5 | 50 | } |
omatthews | 25:09a315a59956 | 51 | |
justinbuckland | 43:d34ac9d8648c | 52 | drive->write(0); //Set duty cycle to zero |
omatthews | 18:f5d26d3d532f | 53 | |
omatthews | 18:f5d26d3d532f | 54 | //Get voltage, current and R values from the ADC conversion |
omatthews | 31:7c6f05326c4d | 55 | adc->read_channels(); |
omatthews | 31:7c6f05326c4d | 56 | curr = adc->read_channel_result(i_port); |
omatthews | 31:7c6f05326c4d | 57 | v = adc->read_channel_result(v_port); |
omatthews | 30:055d856f05b5 | 58 | |
justinbuckland | 35:5acf01897ed6 | 59 | if (curr > 0) { //Avoid dividing by 0 |
justinbuckland | 35:5acf01897ed6 | 60 | R = (float)v/curr; |
justinbuckland | 35:5acf01897ed6 | 61 | R = cal_a + cal_b*R; //Convert to Ohms |
omatthews | 30:055d856f05b5 | 62 | } |
justinbuckland | 42:166d9bc7675e | 63 | |
justinbuckland | 42:166d9bc7675e | 64 | // Calcualate accumulated resistance values for R_avg output |
justinbuckland | 42:166d9bc7675e | 65 | R_acc = R_acc + R; |
justinbuckland | 42:166d9bc7675e | 66 | n_acc ++; |
justinbuckland | 35:5acf01897ed6 | 67 | |
omatthews | 0:4e33cc8171f4 | 68 | } |
omatthews | 0:4e33cc8171f4 | 69 | |
omatthews | 25:09a315a59956 | 70 | void Heater::update() |
omatthews | 7:59ece353eea2 | 71 | { |
justinbuckland | 41:b1602c68abcd | 72 | //Get error |
justinbuckland | 41:b1602c68abcd | 73 | error = R_ref - R; |
justinbuckland | 41:b1602c68abcd | 74 | |
omatthews | 25:09a315a59956 | 75 | //Update PWM from setpoint and resistance |
paullj | 39:5dffedda7a0d | 76 | double duty_cycle = thermal.pid_kp_mho * error; |
justinbuckland | 41:b1602c68abcd | 77 | |
justinbuckland | 41:b1602c68abcd | 78 | //Get integrated error |
paullj | 39:5dffedda7a0d | 79 | if (thermal.pid_integral_time_ms > 0) // set integral time to zero to have no integral term |
justinbuckland | 41:b1602c68abcd | 80 | if (abs(error) > thermal.pid_wind_up_limit_ohm) error = error * thermal.pid_wind_up_limit_ohm / abs(error); |
justinbuckland | 41:b1602c68abcd | 81 | error_integrated += error * (float) thermal.thermal_control_loop_interval_ms; |
paullj | 39:5dffedda7a0d | 82 | duty_cycle += thermal.pid_kp_mho * error_integrated/thermal.pid_integral_time_ms; |
justinbuckland | 43:d34ac9d8648c | 83 | |
paullj | 39:5dffedda7a0d | 84 | if (duty_cycle > thermal.pid_pwm_limit) |
paullj | 39:5dffedda7a0d | 85 | duty_cycle = thermal.pid_pwm_limit; |
paullj | 39:5dffedda7a0d | 86 | else if (duty_cycle < 0) |
paullj | 39:5dffedda7a0d | 87 | duty_cycle = 0; |
justinbuckland | 36:a8130bd29349 | 88 | |
justinbuckland | 43:d34ac9d8648c | 89 | //Reduce guard drive ratio to be lower at higher duty cycles: full value up to GUARD_DUTY_CYCLE_REF, then decreases with gradient GUARD_DUTY_CYCLE_SLOPE |
justinbuckland | 43:d34ac9d8648c | 90 | |
justinbuckland | 43:d34ac9d8648c | 91 | double guard_drive_ratio_factor = 1 + GUARD_DUTY_CYCLE_SLOPE*(1 - duty_cycle/GUARD_DUTY_CYCLE_REF); |
justinbuckland | 43:d34ac9d8648c | 92 | |
justinbuckland | 43:d34ac9d8648c | 93 | if (guard_drive_ratio_factor > 1) guard_drive_ratio_factor = 1; |
justinbuckland | 43:d34ac9d8648c | 94 | if (guard_drive_ratio_factor < 0) guard_drive_ratio_factor = 0; |
justinbuckland | 43:d34ac9d8648c | 95 | |
omatthews | 31:7c6f05326c4d | 96 | drive->write(duty_cycle); |
justinbuckland | 43:d34ac9d8648c | 97 | guard->write(duty_cycle * thermal.guard_drive_ratio * guard_drive_ratio_factor); |
omatthews | 7:59ece353eea2 | 98 | } |
omatthews | 18:f5d26d3d532f | 99 | |
omatthews | 30:055d856f05b5 | 100 | void Heater::Set_ref(float R) |
omatthews | 19:fccdd7127f94 | 101 | { |
omatthews | 19:fccdd7127f94 | 102 | R_ref = R; |
omatthews | 19:fccdd7127f94 | 103 | } |
omatthews | 30:055d856f05b5 | 104 | void Heater::Set_D(float D) |
omatthews | 30:055d856f05b5 | 105 | { |
omatthews | 25:09a315a59956 | 106 | drive->write(D); |
omatthews | 26:f6c98b05ee85 | 107 | guard->write(D*thermal.guard_drive_ratio); |
omatthews | 30:055d856f05b5 | 108 | } |
omatthews | 0:4e33cc8171f4 | 109 | |
justinbuckland | 42:166d9bc7675e | 110 | float Heater::Get_D() const |
omatthews | 31:7c6f05326c4d | 111 | { |
omatthews | 31:7c6f05326c4d | 112 | return drive->read(); |
omatthews | 31:7c6f05326c4d | 113 | } |
omatthews | 31:7c6f05326c4d | 114 | |
omatthews | 30:055d856f05b5 | 115 | int Heater::Get_i() const |
omatthews | 30:055d856f05b5 | 116 | { |
omatthews | 30:055d856f05b5 | 117 | return curr; |
omatthews | 30:055d856f05b5 | 118 | } |
omatthews | 30:055d856f05b5 | 119 | int Heater::Get_v() const |
omatthews | 30:055d856f05b5 | 120 | { |
omatthews | 30:055d856f05b5 | 121 | return v; |
omatthews | 30:055d856f05b5 | 122 | } |
omatthews | 2:7f15386fcc90 | 123 | |
omatthews | 30:055d856f05b5 | 124 | float Heater::Get_R() const |
omatthews | 30:055d856f05b5 | 125 | { |
omatthews | 30:055d856f05b5 | 126 | return R; |
omatthews | 30:055d856f05b5 | 127 | } |
omatthews | 0:4e33cc8171f4 | 128 | |
justinbuckland | 42:166d9bc7675e | 129 | float Heater::Get_R_avg() |
justinbuckland | 42:166d9bc7675e | 130 | { |
justinbuckland | 42:166d9bc7675e | 131 | R_avg = R_acc / (float) n_acc; |
justinbuckland | 42:166d9bc7675e | 132 | R_acc = 0; |
justinbuckland | 42:166d9bc7675e | 133 | n_acc = 0; |
justinbuckland | 42:166d9bc7675e | 134 | return R_avg; |
justinbuckland | 42:166d9bc7675e | 135 | } |
justinbuckland | 42:166d9bc7675e | 136 | |
omatthews | 31:7c6f05326c4d | 137 | float Heater::Get_R_ref() const |
omatthews | 31:7c6f05326c4d | 138 | { |
omatthews | 31:7c6f05326c4d | 139 | return R_ref; |
omatthews | 31:7c6f05326c4d | 140 | } |
omatthews | 31:7c6f05326c4d | 141 | |
omatthews | 31:7c6f05326c4d | 142 | float Heater::Get_error() const |
omatthews | 31:7c6f05326c4d | 143 | { |
omatthews | 31:7c6f05326c4d | 144 | return error; |
omatthews | 31:7c6f05326c4d | 145 | } |
omatthews | 31:7c6f05326c4d | 146 | |
omatthews | 31:7c6f05326c4d | 147 | float Heater::Get_error_integrated() const |
omatthews | 31:7c6f05326c4d | 148 | { |
omatthews | 31:7c6f05326c4d | 149 | return error_integrated; |
omatthews | 31:7c6f05326c4d | 150 | } |
omatthews | 31:7c6f05326c4d | 151 | |
omatthews | 30:055d856f05b5 | 152 | void Heater::turn_on () |
omatthews | 19:fccdd7127f94 | 153 | { |
omatthews | 19:fccdd7127f94 | 154 | *drive = 1; |
omatthews | 26:f6c98b05ee85 | 155 | *guard = thermal.guard_drive_ratio; |
omatthews | 19:fccdd7127f94 | 156 | } |
omatthews | 1:4435d407d827 | 157 | |
omatthews | 30:055d856f05b5 | 158 | void Heater::turn_off () |
omatthews | 19:fccdd7127f94 | 159 | { |
omatthews | 19:fccdd7127f94 | 160 | *drive = 0; |
omatthews | 19:fccdd7127f94 | 161 | *guard = 0; |
omatthews | 19:fccdd7127f94 | 162 | } |