Heater for threaded program

Dependents:   LEX_Threaded_Programming

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());