Heater files
Dependents: LEX-Demo-Firmware-Logging LEX-Demo-Firmware-Logging
Heater.cpp@18:f5d26d3d532f, 2019-07-28 (annotated)
- Committer:
- omatthews
- Date:
- Sun Jul 28 11:49:57 2019 +0000
- Revision:
- 18:f5d26d3d532f
- Parent:
- 17:0bfed0e96927
- Child:
- 19:fccdd7127f94
Added in consts
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 | 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 | 18:f5d26d3d532f | 21 | Heater::Heater(const int i_port, const int v_port, FastPWM * drive, const float corr_grad, const float corr_int, float R_ref) |
omatthews | 8:5da71ae16115 | 22 | :R_ref(R_ref),i_port(i_port),v_port(v_port),drive(drive),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 | 18:f5d26d3d532f | 69 | //Avoid integral windup by limiting integral error past actuation saturation |
omatthews | 17:0bfed0e96927 | 70 | if (error*Kp > WIND_UP_LIMIT) {error_integrated += WIND_UP_LIMIT/Kp;} |
omatthews | 17:0bfed0e96927 | 71 | else if (error*Kp < -WIND_UP_LIMIT) {error_integrated -= WIND_UP_LIMIT/Kp;} |
omatthews | 17:0bfed0e96927 | 72 | else {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 | 18:f5d26d3d532f | 97 | wait_ms(WAIT_DELAY); //Wait before reading again |
omatthews | 0:4e33cc8171f4 | 98 | } |
omatthews | 1:4435d407d827 | 99 | } |
omatthews | 1:4435d407d827 | 100 | |
omatthews | 0:4e33cc8171f4 | 101 | |
omatthews | 18:f5d26d3d532f | 102 | void Heater::ramp_R(const int ramp_time, const float R_final, const float R_start) |
omatthews | 7:59ece353eea2 | 103 | { |
omatthews | 18:f5d26d3d532f | 104 | //Ramps the heater from R_start to R_final for the given hold time |
omatthews | 18:f5d26d3d532f | 105 | // in: int hold_time - is the time in ms to hold the reference |
omatthews | 18:f5d26d3d532f | 106 | // float R_final - is the final R_ref value |
omatthews | 18:f5d26d3d532f | 107 | // float R_start - is the initial R_ref value |
omatthews | 18:f5d26d3d532f | 108 | |
omatthews | 8:5da71ae16115 | 109 | int time = timer.read_ms(); |
omatthews | 8:5da71ae16115 | 110 | int start_time = time; |
omatthews | 7:59ece353eea2 | 111 | int end_time = start_time + ramp_time; |
omatthews | 7:59ece353eea2 | 112 | float ramp_rate = (R_final - R_start)/ramp_time; |
omatthews | 7:59ece353eea2 | 113 | |
omatthews | 8:5da71ae16115 | 114 | while (time < end_time) |
omatthews | 7:59ece353eea2 | 115 | { |
omatthews | 8:5da71ae16115 | 116 | Set_R_ref(R_start + ramp_rate * (time - start_time)); |
omatthews | 7:59ece353eea2 | 117 | hold(1); |
omatthews | 8:5da71ae16115 | 118 | time = timer.read_ms(); |
omatthews | 7:59ece353eea2 | 119 | } |
omatthews | 8:5da71ae16115 | 120 | |
omatthews | 7:59ece353eea2 | 121 | } |
omatthews | 7:59ece353eea2 | 122 | |
omatthews | 18:f5d26d3d532f | 123 | void Heater::ramp_T(const int ramp_time, const float T_final, const float T_start) |
omatthews | 7:59ece353eea2 | 124 | { |
omatthews | 18:f5d26d3d532f | 125 | //Ramps the heater from T_start to T_final for the given hold time |
omatthews | 18:f5d26d3d532f | 126 | // in: int hold_time - is the time in ms to hold the reference |
omatthews | 18:f5d26d3d532f | 127 | // float T_final - is the final T_ref value |
omatthews | 18:f5d26d3d532f | 128 | // float T_start - is the initial T_ref value |
omatthews | 7:59ece353eea2 | 129 | ramp_R(ramp_time, T_to_R(T_final), T_to_R(T_start)); |
omatthews | 7:59ece353eea2 | 130 | } |
omatthews | 18:f5d26d3d532f | 131 | |
omatthews | 18:f5d26d3d532f | 132 | |
omatthews | 18:f5d26d3d532f | 133 | |
omatthews | 7:59ece353eea2 | 134 | void Heater::Set_R_ref(float R) {R_ref = R;} |
omatthews | 7:59ece353eea2 | 135 | void Heater::Set_T_ref(float T_ref) {R_ref = T_to_R(T_ref);} |
omatthews | 16:cd837b230b09 | 136 | void Heater::Set_D(float D) {drive->write(D);} |
omatthews | 0:4e33cc8171f4 | 137 | |
omatthews | 18:f5d26d3d532f | 138 | int Heater::Get_i() const {return curr;} |
omatthews | 18:f5d26d3d532f | 139 | int Heater::Get_v() const {return v;} |
omatthews | 2:7f15386fcc90 | 140 | |
omatthews | 18:f5d26d3d532f | 141 | float Heater::Get_R() const {return R;} |
omatthews | 18:f5d26d3d532f | 142 | float Heater::Get_T() const {return R_to_T(R);} |
omatthews | 0:4e33cc8171f4 | 143 | |
omatthews | 16:cd837b230b09 | 144 | void Heater::turn_on () {*drive = 1;} |
omatthews | 1:4435d407d827 | 145 | |
omatthews | 16:cd837b230b09 | 146 | void Heater::turn_off () {*drive = 0;} |