Heater for threaded program

Dependents:   LEX_Threaded_Programming

Committer:
omatthews
Date:
Thu Jul 25 16:20:01 2019 +0000
Revision:
17:0bfed0e96927
Parent:
16:cd837b230b09
Child:
18:f5d26d3d532f
Working pretty well

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
omatthews 0:4e33cc8171f4 12 extern ADS8568_ADC adc;
omatthews 0:4e33cc8171f4 13 extern float scale_factors[8];
omatthews 0:4e33cc8171f4 14 extern Timer timer;
omatthews 1:4435d407d827 15 extern DigitalIn adc_busy;
omatthews 1:4435d407d827 16 extern MODSERIAL pc;
omatthews 11:785a0329f802 17 extern int log_count;
omatthews 11:785a0329f802 18 extern float R_avg;
omatthews 1:4435d407d827 19
omatthews 0:4e33cc8171f4 20
omatthews 0:4e33cc8171f4 21
omatthews 17:0bfed0e96927 22 Heater::Heater(int i_port, int v_port, FastPWM * drive, float corr_grad, float corr_int, float R_ref)
omatthews 8:5da71ae16115 23 :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 24
omatthews 7:59ece353eea2 25 float Heater::R_to_T(float R) {return R*corr_grad + corr_int;}
omatthews 7:59ece353eea2 26 float Heater::T_to_R(float T) {return (T - corr_int)/corr_grad;}
omatthews 0:4e33cc8171f4 27
omatthews 11:785a0329f802 28 void Heater::output()
omatthews 11:785a0329f802 29 {
omatthews 17:0bfed0e96927 30 pc.printf("%d,%f,%f,%f,%f,%f\n",timer.read_ms(),R_ref,R,error,error_integrated,drive->read());
omatthews 11:785a0329f802 31 }
omatthews 0:4e33cc8171f4 32
omatthews 2:7f15386fcc90 33 void Heater::read()
omatthews 0:4e33cc8171f4 34 {
omatthews 1:4435d407d827 35 //Reads R and then resets the drive back to its previous value
omatthews 17:0bfed0e96927 36
omatthews 1:4435d407d827 37 int i = 0;
omatthews 17:0bfed0e96927 38 float error_prev = error;
omatthews 17:0bfed0e96927 39
omatthews 17:0bfed0e96927 40 double drive_prev = drive->read(); //Store previous value of drive
omatthews 17:0bfed0e96927 41 drive->period_us(1); //Time_on seems to have a precision of us. Larger period => more precise control
omatthews 17:0bfed0e96927 42 *drive = 1.0f;
omatthews 7:59ece353eea2 43 wait_us(MEAS_DELAY); //Wait for ADC to settle
omatthews 1:4435d407d827 44 adc.start_conversion(ALL_CH);
omatthews 1:4435d407d827 45 while(adc_busy == 1)
omatthews 1:4435d407d827 46 {
omatthews 1:4435d407d827 47 wait_us(1);
omatthews 1:4435d407d827 48 i++;
omatthews 1:4435d407d827 49 }
omatthews 16:cd837b230b09 50 drive->write(drive_prev);
omatthews 17:0bfed0e96927 51 drive->period_us(PWM_PERIOD); //Time_on seems to have a precision of us. Larger period => more precise control
omatthews 17:0bfed0e96927 52
omatthews 0:4e33cc8171f4 53 adc.read_channels();
omatthews 10:0e16d8430d66 54
omatthews 8:5da71ae16115 55
omatthews 8:5da71ae16115 56 //pc.printf("conversion took %d us\n", i );
omatthews 7:59ece353eea2 57 //i=0;
omatthews 1:4435d407d827 58
omatthews 7:59ece353eea2 59 curr = adc.read_channel_result(i_port);
omatthews 7:59ece353eea2 60 v = adc.read_channel_result(v_port);
omatthews 7:59ece353eea2 61 if (v<0) {pc.printf("v is %d",v);}
omatthews 17:0bfed0e96927 62 if (curr > 0) {R = (float)v/curr;} //Avoid dividing by 0
omatthews 17:0bfed0e96927 63 //R_avg = (((N_ROLL_AVG - 1) * R_avg) + R)/N_ROLL_AVG;
omatthews 12:8a048f111140 64
omatthews 17:0bfed0e96927 65 error = R_ref - R;
omatthews 17:0bfed0e96927 66 error_diff = (error - error_prev)/WAIT_DELAY;
omatthews 14:f266bf960b8d 67
omatthews 14:f266bf960b8d 68 //Avoid integral windup by limiting error past actuation saturation (actuator does saturate for any negative error, but to ensure integrated error can decrease, the limit has been set to the negative of the positive limit
omatthews 17:0bfed0e96927 69 if (error*Kp > WIND_UP_LIMIT) {error_integrated += WIND_UP_LIMIT/Kp;}
omatthews 17:0bfed0e96927 70 else if (error*Kp < -WIND_UP_LIMIT) {error_integrated -= WIND_UP_LIMIT/Kp;}
omatthews 17:0bfed0e96927 71 else {error_integrated += error;}
omatthews 14:f266bf960b8d 72
omatthews 14:f266bf960b8d 73
omatthews 12:8a048f111140 74
omatthews 11:785a0329f802 75 log_count++;
omatthews 17:0bfed0e96927 76 if (log_count > 100)
omatthews 11:785a0329f802 77 {
omatthews 11:785a0329f802 78 log_count = 0;
omatthews 11:785a0329f802 79 output();
omatthews 11:785a0329f802 80 }
omatthews 0:4e33cc8171f4 81 }
omatthews 0:4e33cc8171f4 82
omatthews 2:7f15386fcc90 83
omatthews 2:7f15386fcc90 84
omatthews 2:7f15386fcc90 85
omatthews 0:4e33cc8171f4 86 void Heater::hold(int hold_time)
omatthews 0:4e33cc8171f4 87 {
omatthews 7:59ece353eea2 88 //Holds the heater at R_ref for the given hold time
omatthews 7:59ece353eea2 89 // in: int hold_time - is the time in ms to hold the reference
omatthews 7:59ece353eea2 90
omatthews 0:4e33cc8171f4 91 int end_time = timer.read_ms() + hold_time;
omatthews 1:4435d407d827 92 while (timer.read_ms() < end_time)
omatthews 0:4e33cc8171f4 93 {
omatthews 2:7f15386fcc90 94 read();
omatthews 12:8a048f111140 95
omatthews 17:0bfed0e96927 96 drive->write((double) (Kp * (error + error_integrated/Ti)));
omatthews 12:8a048f111140 97 wait_ms(WAIT_DELAY); //Minimum duty cycle of 1%
omatthews 14:f266bf960b8d 98 //pc.printf("%f,%f,%f\n",error,error_integrated,drive.read());
omatthews 12:8a048f111140 99
omatthews 8:5da71ae16115 100
omatthews 0:4e33cc8171f4 101 }
omatthews 1:4435d407d827 102 }
omatthews 1:4435d407d827 103
omatthews 0:4e33cc8171f4 104
omatthews 7:59ece353eea2 105 void Heater::ramp_R(int ramp_time, float R_final, float R_start)
omatthews 7:59ece353eea2 106 {
omatthews 8:5da71ae16115 107 int time = timer.read_ms();
omatthews 8:5da71ae16115 108 int start_time = time;
omatthews 7:59ece353eea2 109 int end_time = start_time + ramp_time;
omatthews 7:59ece353eea2 110 float ramp_rate = (R_final - R_start)/ramp_time;
omatthews 7:59ece353eea2 111
omatthews 8:5da71ae16115 112 while (time < end_time)
omatthews 7:59ece353eea2 113 {
omatthews 8:5da71ae16115 114 Set_R_ref(R_start + ramp_rate * (time - start_time));
omatthews 7:59ece353eea2 115 hold(1);
omatthews 8:5da71ae16115 116 time = timer.read_ms();
omatthews 7:59ece353eea2 117 }
omatthews 8:5da71ae16115 118
omatthews 7:59ece353eea2 119 }
omatthews 7:59ece353eea2 120
omatthews 7:59ece353eea2 121 void Heater::ramp_T(int ramp_time, float T_final, float T_start)
omatthews 7:59ece353eea2 122 {
omatthews 7:59ece353eea2 123 ramp_R(ramp_time, T_to_R(T_final), T_to_R(T_start));
omatthews 7:59ece353eea2 124 }
omatthews 7:59ece353eea2 125 void Heater::Set_R_ref(float R) {R_ref = R;}
omatthews 7:59ece353eea2 126 void Heater::Set_T_ref(float T_ref) {R_ref = T_to_R(T_ref);}
omatthews 16:cd837b230b09 127
omatthews 16:cd837b230b09 128 void Heater::Set_D(float D) {drive->write(D);}
omatthews 0:4e33cc8171f4 129
omatthews 2:7f15386fcc90 130 int Heater::Get_i() {return curr;}
omatthews 2:7f15386fcc90 131 int Heater::Get_v() {return v;}
omatthews 2:7f15386fcc90 132
omatthews 0:4e33cc8171f4 133 float Heater::Get_R() {return R;}
omatthews 7:59ece353eea2 134 float Heater::Get_T() {return R_to_T(R);}
omatthews 0:4e33cc8171f4 135
omatthews 16:cd837b230b09 136 void Heater::turn_on () {*drive = 1;}
omatthews 1:4435d407d827 137
omatthews 16:cd837b230b09 138 void Heater::turn_off () {*drive = 0;}