Heater files
Dependents: LEX-Demo-Firmware-Logging LEX-Demo-Firmware-Logging
Diff: Heater.cpp
- Revision:
- 18:f5d26d3d532f
- Parent:
- 17:0bfed0e96927
- Child:
- 19:fccdd7127f94
diff -r 0bfed0e96927 -r f5d26d3d532f Heater.cpp --- a/Heater.cpp Thu Jul 25 16:20:01 2019 +0000 +++ b/Heater.cpp Sun Jul 28 11:49:57 2019 +0000 @@ -10,7 +10,6 @@ #include "ADS8568_ADC.h" extern ADS8568_ADC adc; -extern float scale_factors[8]; extern Timer timer; extern DigitalIn adc_busy; extern MODSERIAL pc; @@ -19,14 +18,17 @@ -Heater::Heater(int i_port, int v_port, FastPWM * drive, float corr_grad, float corr_int, float R_ref) +Heater::Heater(const int i_port, const int v_port, FastPWM * drive, const float corr_grad, const float corr_int, float R_ref) :R_ref(R_ref),i_port(i_port),v_port(v_port),drive(drive),corr_grad(corr_grad),corr_int(corr_int) {} -float Heater::R_to_T(float R) {return R*corr_grad + corr_int;} -float Heater::T_to_R(float T) {return (T - corr_int)/corr_grad;} -void Heater::output() +// Convert from R to T using the linear relationship - T = R * corr_grad + corr_int +float Heater::R_to_T(const float R) const {return R*corr_grad + corr_int;} +float Heater::T_to_R(const float T) const {return (T - corr_int)/corr_grad;} + +void Heater::output()const { + //Prints the current state to the terminal pc.printf("%d,%f,%f,%f,%f,%f\n",timer.read_ms(),R_ref,R,error,error_integrated,drive->read()); } @@ -35,45 +37,44 @@ //Reads R and then resets the drive back to its previous value int i = 0; - float error_prev = error; + //float error_prev = error; double drive_prev = drive->read(); //Store previous value of drive - drive->period_us(1); //Time_on seems to have a precision of us. Larger period => more precise control - *drive = 1.0f; + drive->period_us(1); //Set period to 1us for the measurement + *drive = 1.0f; //Turn the driver on for the measurement wait_us(MEAS_DELAY); //Wait for ADC to settle adc.start_conversion(ALL_CH); + //Incremental back off until ADC is free while(adc_busy == 1) { wait_us(1); i++; - } - drive->write(drive_prev); - drive->period_us(PWM_PERIOD); //Time_on seems to have a precision of us. Larger period => more precise control + } + drive->write(drive_prev); //Reset the duty cycle back to what it was + drive->period_us(PWM_PERIOD); //Reset the period to what it was + + //Get voltage, current and R values from the ADC conversion adc.read_channels(); - - - //pc.printf("conversion took %d us\n", i ); - //i=0; - curr = adc.read_channel_result(i_port); v = adc.read_channel_result(v_port); - if (v<0) {pc.printf("v is %d",v);} + if (curr > 0) {R = (float)v/curr;} //Avoid dividing by 0 - //R_avg = (((N_ROLL_AVG - 1) * R_avg) + R)/N_ROLL_AVG; + //Get error values + error = R_ref - R; - error_diff = (error - error_prev)/WAIT_DELAY; + //error_diff = (error - error_prev)/WAIT_DELAY; - //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 + //Avoid integral windup by limiting integral error past actuation saturation if (error*Kp > WIND_UP_LIMIT) {error_integrated += WIND_UP_LIMIT/Kp;} else if (error*Kp < -WIND_UP_LIMIT) {error_integrated -= WIND_UP_LIMIT/Kp;} else {error_integrated += error;} - + //Output the error every LOG_LIM reads log_count++; - if (log_count > 100) + if (log_count >= LOG_LIM) { log_count = 0; output(); @@ -83,7 +84,7 @@ -void Heater::hold(int hold_time) +void Heater::hold(const int hold_time) { //Holds the heater at R_ref for the given hold time // in: int hold_time - is the time in ms to hold the reference @@ -92,18 +93,19 @@ while (timer.read_ms() < end_time) { read(); - drive->write((double) (Kp * (error + error_integrated/Ti))); - wait_ms(WAIT_DELAY); //Minimum duty cycle of 1% - //pc.printf("%f,%f,%f\n",error,error_integrated,drive.read()); - - + wait_ms(WAIT_DELAY); //Wait before reading again } } -void Heater::ramp_R(int ramp_time, float R_final, float R_start) +void Heater::ramp_R(const int ramp_time, const float R_final, const float R_start) { + //Ramps the heater from R_start to R_final for the given hold time + // in: int hold_time - is the time in ms to hold the reference + // float R_final - is the final R_ref value + // float R_start - is the initial R_ref value + int time = timer.read_ms(); int start_time = time; int end_time = start_time + ramp_time; @@ -118,20 +120,26 @@ } -void Heater::ramp_T(int ramp_time, float T_final, float T_start) +void Heater::ramp_T(const int ramp_time, const float T_final, const float T_start) { + //Ramps the heater from T_start to T_final for the given hold time + // in: int hold_time - is the time in ms to hold the reference + // float T_final - is the final T_ref value + // float T_start - is the initial T_ref value ramp_R(ramp_time, T_to_R(T_final), T_to_R(T_start)); } + + + void Heater::Set_R_ref(float R) {R_ref = R;} void Heater::Set_T_ref(float T_ref) {R_ref = T_to_R(T_ref);} - void Heater::Set_D(float D) {drive->write(D);} -int Heater::Get_i() {return curr;} -int Heater::Get_v() {return v;} +int Heater::Get_i() const {return curr;} +int Heater::Get_v() const {return v;} -float Heater::Get_R() {return R;} -float Heater::Get_T() {return R_to_T(R);} +float Heater::Get_R() const {return R;} +float Heater::Get_T() const {return R_to_T(R);} void Heater::turn_on () {*drive = 1;}