Heater for threaded program
Dependents: LEX_Threaded_Programming_V3
Heater.cpp@33:52ab0641f2e6, 2019-09-19 (annotated)
- Committer:
- paullj
- Date:
- Thu Sep 19 16:13:30 2019 +0000
- Revision:
- 33:52ab0641f2e6
- Parent:
- 31:7c6f05326c4d
- Child:
- 34:294adcc3e4b2
Updated memspcr.pb.h and memspcr.pb.c as well as increase buffer size
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 | |
omatthews | 31:7c6f05326c4d | 12 | |
omatthews | 30:055d856f05b5 | 13 | |
omatthews | 31:7c6f05326c4d | 14 | Heater::Heater(const int i_port, const int v_port, FastPWM * drive, FastPWM * guard, ADS8568_ADC * adc, DigitalIn adc_busy, const memspcr_ThermalConfiguration & thermal) |
omatthews | 31:7c6f05326c4d | 15 | :thermal(thermal), i_port(i_port), v_port(v_port), drive(drive), guard(guard), adc(adc), adc_busy(adc_busy) |
omatthews | 30:055d856f05b5 | 16 | { |
omatthews | 30:055d856f05b5 | 17 | drive->prescaler(1); |
omatthews | 30:055d856f05b5 | 18 | guard->prescaler(1); |
omatthews | 30:055d856f05b5 | 19 | drive->period_ticks(1000); |
omatthews | 30:055d856f05b5 | 20 | guard->period_ticks(1000); |
omatthews | 30:055d856f05b5 | 21 | } |
omatthews | 30:055d856f05b5 | 22 | |
omatthews | 7:59ece353eea2 | 23 | |
omatthews | 2:7f15386fcc90 | 24 | void Heater::read() |
omatthews | 0:4e33cc8171f4 | 25 | { |
omatthews | 1:4435d407d827 | 26 | //Reads R and then resets the drive back to its previous value |
omatthews | 30:055d856f05b5 | 27 | int i = 0; |
omatthews | 17:0bfed0e96927 | 28 | double drive_prev = drive->read(); //Store previous value of drive |
omatthews | 18:f5d26d3d532f | 29 | *drive = 1.0f; //Turn the driver on for the measurement |
paullj | 33:52ab0641f2e6 | 30 | wait_us(thermal.settling_time_us); //Wait for ADC to settle |
omatthews | 31:7c6f05326c4d | 31 | adc->start_conversion(15); |
omatthews | 25:09a315a59956 | 32 | |
omatthews | 18:f5d26d3d532f | 33 | //Incremental back off until ADC is free |
omatthews | 30:055d856f05b5 | 34 | while(adc_busy == 1) { |
omatthews | 30:055d856f05b5 | 35 | wait_us(1); |
omatthews | 30:055d856f05b5 | 36 | i++; |
omatthews | 30:055d856f05b5 | 37 | } |
omatthews | 25:09a315a59956 | 38 | |
omatthews | 20:2d34a03ae57e | 39 | drive->write(0); //Reset the duty cycle back to what it was |
omatthews | 18:f5d26d3d532f | 40 | |
omatthews | 18:f5d26d3d532f | 41 | //Get voltage, current and R values from the ADC conversion |
omatthews | 31:7c6f05326c4d | 42 | adc->read_channels(); |
omatthews | 31:7c6f05326c4d | 43 | curr = adc->read_channel_result(i_port); |
omatthews | 31:7c6f05326c4d | 44 | v = adc->read_channel_result(v_port); |
omatthews | 30:055d856f05b5 | 45 | |
omatthews | 30:055d856f05b5 | 46 | if (curr > 0) { |
omatthews | 30:055d856f05b5 | 47 | R = (float)v/curr; //Avoid dividing by 0 |
omatthews | 30:055d856f05b5 | 48 | } |
omatthews | 12:8a048f111140 | 49 | |
omatthews | 18:f5d26d3d532f | 50 | //Get error values |
omatthews | 30:055d856f05b5 | 51 | |
omatthews | 17:0bfed0e96927 | 52 | error = R_ref - R; |
omatthews | 30:055d856f05b5 | 53 | |
omatthews | 25:09a315a59956 | 54 | //Only allow positive integrated errors and limit change in integrated error |
omatthews | 30:055d856f05b5 | 55 | //to help avoid integral windup |
omatthews | 30:055d856f05b5 | 56 | |
omatthews | 30:055d856f05b5 | 57 | if (abs(error) > WIND_UP_LIMIT) {error = error * WIND_UP_LIMIT / abs(error);} |
omatthews | 25:09a315a59956 | 58 | |
omatthews | 30:055d856f05b5 | 59 | error_integrated += error; |
omatthews | 30:055d856f05b5 | 60 | |
omatthews | 30:055d856f05b5 | 61 | if (error_integrated < 0.0) { |
omatthews | 30:055d856f05b5 | 62 | error_integrated = 0.0; |
omatthews | 30:055d856f05b5 | 63 | } |
omatthews | 0:4e33cc8171f4 | 64 | } |
omatthews | 0:4e33cc8171f4 | 65 | |
omatthews | 2:7f15386fcc90 | 66 | |
omatthews | 2:7f15386fcc90 | 67 | |
omatthews | 2:7f15386fcc90 | 68 | |
omatthews | 25:09a315a59956 | 69 | void Heater::update() |
omatthews | 7:59ece353eea2 | 70 | { |
omatthews | 25:09a315a59956 | 71 | //Update PWM from setpoint and resistance |
paullj | 33:52ab0641f2e6 | 72 | double duty_cycle = (double) thermal.pid_kp_mho * (error + error_integrated/thermal.pid_integral_time_ms); |
omatthews | 31:7c6f05326c4d | 73 | if (duty_cycle > PWM_LIMIT) duty_cycle = PWM_LIMIT; |
omatthews | 31:7c6f05326c4d | 74 | drive->write(duty_cycle); |
omatthews | 31:7c6f05326c4d | 75 | guard->write(duty_cycle * thermal.guard_drive_ratio); |
omatthews | 7:59ece353eea2 | 76 | } |
omatthews | 18:f5d26d3d532f | 77 | |
omatthews | 18:f5d26d3d532f | 78 | |
omatthews | 30:055d856f05b5 | 79 | void Heater::Set_ref(float R) |
omatthews | 19:fccdd7127f94 | 80 | { |
omatthews | 19:fccdd7127f94 | 81 | R_ref = R; |
omatthews | 19:fccdd7127f94 | 82 | } |
omatthews | 30:055d856f05b5 | 83 | void Heater::Set_D(float D) |
omatthews | 30:055d856f05b5 | 84 | { |
omatthews | 25:09a315a59956 | 85 | drive->write(D); |
omatthews | 26:f6c98b05ee85 | 86 | guard->write(D*thermal.guard_drive_ratio); |
omatthews | 30:055d856f05b5 | 87 | } |
omatthews | 0:4e33cc8171f4 | 88 | |
omatthews | 31:7c6f05326c4d | 89 | int Heater::Get_D() const |
omatthews | 31:7c6f05326c4d | 90 | { |
omatthews | 31:7c6f05326c4d | 91 | return drive->read(); |
omatthews | 31:7c6f05326c4d | 92 | } |
omatthews | 31:7c6f05326c4d | 93 | |
omatthews | 30:055d856f05b5 | 94 | int Heater::Get_i() const |
omatthews | 30:055d856f05b5 | 95 | { |
omatthews | 30:055d856f05b5 | 96 | return curr; |
omatthews | 30:055d856f05b5 | 97 | } |
omatthews | 30:055d856f05b5 | 98 | int Heater::Get_v() const |
omatthews | 30:055d856f05b5 | 99 | { |
omatthews | 30:055d856f05b5 | 100 | return v; |
omatthews | 30:055d856f05b5 | 101 | } |
omatthews | 2:7f15386fcc90 | 102 | |
omatthews | 30:055d856f05b5 | 103 | float Heater::Get_R() const |
omatthews | 30:055d856f05b5 | 104 | { |
omatthews | 30:055d856f05b5 | 105 | return R; |
omatthews | 30:055d856f05b5 | 106 | } |
omatthews | 0:4e33cc8171f4 | 107 | |
omatthews | 31:7c6f05326c4d | 108 | float Heater::Get_R_ref() const |
omatthews | 31:7c6f05326c4d | 109 | { |
omatthews | 31:7c6f05326c4d | 110 | return R_ref; |
omatthews | 31:7c6f05326c4d | 111 | } |
omatthews | 31:7c6f05326c4d | 112 | |
omatthews | 31:7c6f05326c4d | 113 | float Heater::Get_error() const |
omatthews | 31:7c6f05326c4d | 114 | { |
omatthews | 31:7c6f05326c4d | 115 | return error; |
omatthews | 31:7c6f05326c4d | 116 | } |
omatthews | 31:7c6f05326c4d | 117 | |
omatthews | 31:7c6f05326c4d | 118 | float Heater::Get_error_integrated() const |
omatthews | 31:7c6f05326c4d | 119 | { |
omatthews | 31:7c6f05326c4d | 120 | return error_integrated; |
omatthews | 31:7c6f05326c4d | 121 | } |
omatthews | 31:7c6f05326c4d | 122 | |
omatthews | 30:055d856f05b5 | 123 | void Heater::turn_on () |
omatthews | 19:fccdd7127f94 | 124 | { |
omatthews | 19:fccdd7127f94 | 125 | *drive = 1; |
omatthews | 26:f6c98b05ee85 | 126 | *guard = thermal.guard_drive_ratio; |
omatthews | 19:fccdd7127f94 | 127 | } |
omatthews | 1:4435d407d827 | 128 | |
omatthews | 30:055d856f05b5 | 129 | void Heater::turn_off () |
omatthews | 19:fccdd7127f94 | 130 | { |
omatthews | 19:fccdd7127f94 | 131 | *drive = 0; |
omatthews | 19:fccdd7127f94 | 132 | *guard = 0; |
omatthews | 19:fccdd7127f94 | 133 | } |