Heater files
Dependents: LEX-Demo-Firmware-Logging LEX-Demo-Firmware-Logging
Diff: Heater.cpp
- Revision:
- 17:0bfed0e96927
- Parent:
- 16:cd837b230b09
- Child:
- 18:f5d26d3d532f
--- a/Heater.cpp Wed Jul 24 14:29:44 2019 +0000 +++ b/Heater.cpp Thu Jul 25 16:20:01 2019 +0000 @@ -19,7 +19,7 @@ -Heater::Heater(int i_port, int v_port, PwmOut * drive, float corr_grad, float corr_int, float R_ref) +Heater::Heater(int i_port, int v_port, FastPWM * 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;} @@ -27,16 +27,19 @@ void Heater::output() { - pc.printf("%d,%f,%f,%f,%f\n",timer.read_ms(),R_ref,R,R_avg,drive->read()); + pc.printf("%d,%f,%f,%f,%f,%f\n",timer.read_ms(),R_ref,R,error,error_integrated,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; + 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; wait_us(MEAS_DELAY); //Wait for ADC to settle adc.start_conversion(ALL_CH); while(adc_busy == 1) @@ -45,6 +48,8 @@ i++; } drive->write(drive_prev); + drive->period_us(PWM_PERIOD); //Time_on seems to have a precision of us. Larger period => more precise control + adc.read_channels(); @@ -54,21 +59,21 @@ 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; + if (curr > 0) {R = (float)v/curr;} //Avoid dividing by 0 + //R_avg = (((N_ROLL_AVG - 1) * R_avg) + R)/N_ROLL_AVG; - error = R_ref - R_avg; + error = R_ref - R; + 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 - if (error*Kd > 1) {error = 1/Kd;} - else if (error*Kd < -1) {error = -1/Kd;} + 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;} - error_integrated += error; log_count++; - if (log_count > 50) + if (log_count > 100) { log_count = 0; output(); @@ -88,7 +93,7 @@ { read(); - drive->write(Kd * error + Ki * error_integrated); + 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());