Heater for threaded program

Dependents:   LEX_Threaded_Programming_V3

Committer:
paullj
Date:
Thu Oct 03 09:59:56 2019 +0000
Revision:
40:2be211a07d09
Parent:
39:5dffedda7a0d
added hard-code option fro guard drive ratio (for debugging)

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 {
omatthews 30:055d856f05b5 15 drive->prescaler(1);
omatthews 30:055d856f05b5 16 guard->prescaler(1);
omatthews 30:055d856f05b5 17 drive->period_ticks(1000);
omatthews 30:055d856f05b5 18 guard->period_ticks(1000);
omatthews 30:055d856f05b5 19 }
omatthews 30:055d856f05b5 20
omatthews 2:7f15386fcc90 21 void Heater::read()
omatthews 0:4e33cc8171f4 22 {
omatthews 1:4435d407d827 23 //Reads R and then resets the drive back to its previous value
omatthews 30:055d856f05b5 24 int i = 0;
omatthews 17:0bfed0e96927 25 double drive_prev = drive->read(); //Store previous value of drive
justinbuckland 35:5acf01897ed6 26
justinbuckland 34:294adcc3e4b2 27 *drive = 1.0f; //Turn the driver on for the measurement
justinbuckland 34:294adcc3e4b2 28 wait_us(thermal.settling_time_us); //Wait for ADC to settle
justinbuckland 34:294adcc3e4b2 29 adc->start_conversion(ADC_CONV_ALL_CH);
justinbuckland 34:294adcc3e4b2 30
omatthews 18:f5d26d3d532f 31 //Incremental back off until ADC is free
omatthews 30:055d856f05b5 32 while(adc_busy == 1) {
omatthews 30:055d856f05b5 33 wait_us(1);
omatthews 30:055d856f05b5 34 i++;
omatthews 30:055d856f05b5 35 }
omatthews 25:09a315a59956 36
omatthews 20:2d34a03ae57e 37 drive->write(0); //Reset the duty cycle back to what it was
omatthews 18:f5d26d3d532f 38
omatthews 18:f5d26d3d532f 39 //Get voltage, current and R values from the ADC conversion
omatthews 31:7c6f05326c4d 40 adc->read_channels();
omatthews 31:7c6f05326c4d 41 curr = adc->read_channel_result(i_port);
omatthews 31:7c6f05326c4d 42 v = adc->read_channel_result(v_port);
omatthews 30:055d856f05b5 43
justinbuckland 35:5acf01897ed6 44 if (curr > 0) { //Avoid dividing by 0
justinbuckland 35:5acf01897ed6 45 R = (float)v/curr;
justinbuckland 35:5acf01897ed6 46 R = cal_a + cal_b*R; //Convert to Ohms
omatthews 30:055d856f05b5 47 }
justinbuckland 35:5acf01897ed6 48
justinbuckland 37:688dad0e1b76 49 //Get error and integrated error values
omatthews 17:0bfed0e96927 50 error = R_ref - R;
paullj 38:3a2778f1f90a 51 error_integrated += error * (float) thermal.thermal_control_loop_interval_ms;
omatthews 30:055d856f05b5 52
omatthews 25:09a315a59956 53 //Only allow positive integrated errors and limit change in integrated error
omatthews 30:055d856f05b5 54 //to help avoid integral windup
paullj 39:5dffedda7a0d 55 if (abs(error) > thermal.pid_wind_up_limit_ohm) error = error * thermal.pid_wind_up_limit_ohm / abs(error);
omatthews 0:4e33cc8171f4 56 }
omatthews 0:4e33cc8171f4 57
omatthews 25:09a315a59956 58 void Heater::update()
omatthews 7:59ece353eea2 59 {
omatthews 25:09a315a59956 60 //Update PWM from setpoint and resistance
paullj 39:5dffedda7a0d 61 double duty_cycle = thermal.pid_kp_mho * error;
paullj 39:5dffedda7a0d 62
paullj 39:5dffedda7a0d 63 if (thermal.pid_integral_time_ms > 0) // set integral time to zero to have no integral term
paullj 39:5dffedda7a0d 64 duty_cycle += thermal.pid_kp_mho * error_integrated/thermal.pid_integral_time_ms;
justinbuckland 36:a8130bd29349 65
paullj 39:5dffedda7a0d 66 if (duty_cycle > thermal.pid_pwm_limit)
paullj 39:5dffedda7a0d 67 duty_cycle = thermal.pid_pwm_limit;
paullj 39:5dffedda7a0d 68 else if (duty_cycle < 0)
paullj 39:5dffedda7a0d 69 duty_cycle = 0;
justinbuckland 36:a8130bd29349 70
omatthews 31:7c6f05326c4d 71 drive->write(duty_cycle);
omatthews 31:7c6f05326c4d 72 guard->write(duty_cycle * thermal.guard_drive_ratio);
paullj 40:2be211a07d09 73 // guard->write(duty_cycle * 0.26);
omatthews 7:59ece353eea2 74 }
omatthews 18:f5d26d3d532f 75
omatthews 30:055d856f05b5 76 void Heater::Set_ref(float R)
omatthews 19:fccdd7127f94 77 {
omatthews 19:fccdd7127f94 78 R_ref = R;
omatthews 19:fccdd7127f94 79 }
omatthews 30:055d856f05b5 80 void Heater::Set_D(float D)
omatthews 30:055d856f05b5 81 {
omatthews 25:09a315a59956 82 drive->write(D);
omatthews 26:f6c98b05ee85 83 guard->write(D*thermal.guard_drive_ratio);
paullj 40:2be211a07d09 84 // guard->write(D*0.26);
omatthews 30:055d856f05b5 85 }
omatthews 0:4e33cc8171f4 86
omatthews 31:7c6f05326c4d 87 int Heater::Get_D() const
omatthews 31:7c6f05326c4d 88 {
omatthews 31:7c6f05326c4d 89 return drive->read();
omatthews 31:7c6f05326c4d 90 }
omatthews 31:7c6f05326c4d 91
omatthews 30:055d856f05b5 92 int Heater::Get_i() const
omatthews 30:055d856f05b5 93 {
omatthews 30:055d856f05b5 94 return curr;
omatthews 30:055d856f05b5 95 }
omatthews 30:055d856f05b5 96 int Heater::Get_v() const
omatthews 30:055d856f05b5 97 {
omatthews 30:055d856f05b5 98 return v;
omatthews 30:055d856f05b5 99 }
omatthews 2:7f15386fcc90 100
omatthews 30:055d856f05b5 101 float Heater::Get_R() const
omatthews 30:055d856f05b5 102 {
omatthews 30:055d856f05b5 103 return R;
omatthews 30:055d856f05b5 104 }
omatthews 0:4e33cc8171f4 105
omatthews 31:7c6f05326c4d 106 float Heater::Get_R_ref() const
omatthews 31:7c6f05326c4d 107 {
omatthews 31:7c6f05326c4d 108 return R_ref;
omatthews 31:7c6f05326c4d 109 }
omatthews 31:7c6f05326c4d 110
omatthews 31:7c6f05326c4d 111 float Heater::Get_error() const
omatthews 31:7c6f05326c4d 112 {
omatthews 31:7c6f05326c4d 113 return error;
omatthews 31:7c6f05326c4d 114 }
omatthews 31:7c6f05326c4d 115
omatthews 31:7c6f05326c4d 116 float Heater::Get_error_integrated() const
omatthews 31:7c6f05326c4d 117 {
omatthews 31:7c6f05326c4d 118 return error_integrated;
omatthews 31:7c6f05326c4d 119 }
omatthews 31:7c6f05326c4d 120
omatthews 30:055d856f05b5 121 void Heater::turn_on ()
omatthews 19:fccdd7127f94 122 {
omatthews 19:fccdd7127f94 123 *drive = 1;
omatthews 26:f6c98b05ee85 124 *guard = thermal.guard_drive_ratio;
omatthews 19:fccdd7127f94 125 }
omatthews 1:4435d407d827 126
omatthews 30:055d856f05b5 127 void Heater::turn_off ()
omatthews 19:fccdd7127f94 128 {
omatthews 19:fccdd7127f94 129 *drive = 0;
omatthews 19:fccdd7127f94 130 *guard = 0;
omatthews 19:fccdd7127f94 131 }