Heater for threaded program
Dependents: LEX_Threaded_Programming_V3
Heater.cpp
- Committer:
- omatthews
- Date:
- 2019-07-24
- Revision:
- 16:cd837b230b09
- Parent:
- 15:e7838491c104
- Child:
- 17:0bfed0e96927
File content as of revision 16:cd837b230b09:
/*------------------------------------------------------------------------------ Library code file for interface to Heater Date: 16/07/2018 ------------------------------------------------------------------------------*/ #include "mbed.h" #include "MODSERIAL.h" #include "Heater.h" #include "ADS8568_ADC.h" extern ADS8568_ADC adc; extern float scale_factors[8]; extern Timer timer; extern DigitalIn adc_busy; extern MODSERIAL pc; extern int log_count; extern float R_avg; Heater::Heater(int i_port, int v_port, PwmOut * drive, float corr_grad, 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() { pc.printf("%d,%f,%f,%f,%f\n",timer.read_ms(),R_ref,R,R_avg,drive->read()); } void Heater::read() { //Reads R and then resets the drive back to its previous value int i = 0; float drive_prev = drive->read(); //Store previous value of drive *drive = 1; wait_us(MEAS_DELAY); //Wait for ADC to settle adc.start_conversion(ALL_CH); while(adc_busy == 1) { wait_us(1); i++; } drive->write(drive_prev); 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 = (float)v/curr; R_avg = (((N_ROLL_AVG - 1) * R_avg) + R)/N_ROLL_AVG; error = R_ref - R_avg; //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 if (error*Kd > 1) {error = 1/Kd;} else if (error*Kd < -1) {error = -1/Kd;} error_integrated += error; log_count++; if (log_count > 50) { log_count = 0; output(); } } void Heater::hold(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 int end_time = timer.read_ms() + hold_time; while (timer.read_ms() < end_time) { read(); drive->write(Kd * error + Ki * error_integrated); wait_ms(WAIT_DELAY); //Minimum duty cycle of 1% //pc.printf("%f,%f,%f\n",error,error_integrated,drive.read()); } } void Heater::ramp_R(int ramp_time, float R_final, float R_start) { int time = timer.read_ms(); int start_time = time; int end_time = start_time + ramp_time; float ramp_rate = (R_final - R_start)/ramp_time; while (time < end_time) { Set_R_ref(R_start + ramp_rate * (time - start_time)); hold(1); time = timer.read_ms(); } } void Heater::ramp_T(int ramp_time, float T_final, float T_start) { 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;} float Heater::Get_R() {return R;} float Heater::Get_T() {return R_to_T(R);} void Heater::turn_on () {*drive = 1;} void Heater::turn_off () {*drive = 0;}