Browse Source

Make multiple PID parameters a config option

* Adds config parameter `PID_PARAMS_PER_EXTRUDER` - allows single PID
parameters to be used where this would be preferable (e.g. dual
identical extruders)
* When disabled, will use `float Kp, Ki, Kd, Kc;` as before.
Preprocessor macros used to switch between.
* ultralcd.cpp defines extra menus for extra parameters only where
required
* M301 reports `e:xx` only if independent pid parameters enabled
* EEPROM structure still leaves space for 3 extruders worth, when undef
will save single parameter to all extruder positions, but only read the
first
* Switching off saves approx 330 B with no LCD enabled, 2634B with LCD
(RRD) enabled: this is significant.
* LCD modifications should be tested.
grob6000 9 years ago
parent
commit
bf2c923db5
6 changed files with 96 additions and 70 deletions
  1. 2
    0
      Marlin/Configuration.h
  2. 21
    17
      Marlin/ConfigurationStore.cpp
  3. 12
    10
      Marlin/Marlin_main.cpp
  4. 17
    8
      Marlin/temperature.cpp
  5. 8
    1
      Marlin/temperature.h
  6. 36
    34
      Marlin/ultralcd.cpp

+ 2
- 0
Marlin/Configuration.h View File

@@ -152,6 +152,8 @@
152 152
   //#define PID_DEBUG // Sends debug data to the serial port.
153 153
   //#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
154 154
   //#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
155
+  //#define PID_PARAMS_PER_EXTRUDER // Uses separate PID parameters for each extruder (useful for mismatched extruders)
156
+                                    // Set/get with gcode: M301 E[extruder number, 0-2]
155 157
   #define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
156 158
                                   // is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
157 159
   #define PID_INTEGRAL_DRIVE_MAX PID_MAX  //limit for the integral term

+ 21
- 17
Marlin/ConfigurationStore.cpp View File

@@ -81,11 +81,11 @@ void Config_StoreSettings()
81 81
 	{
82 82
 	  if (e < EXTRUDERS)
83 83
 	  {
84
-        EEPROM_WRITE_VAR(i,Kp[e]);
85
-        EEPROM_WRITE_VAR(i,Ki[e]);
86
-        EEPROM_WRITE_VAR(i,Kd[e]);
84
+        EEPROM_WRITE_VAR(i,PID_PARAM(Kp,e));
85
+        EEPROM_WRITE_VAR(i,PID_PARAM(Ki,e));
86
+        EEPROM_WRITE_VAR(i,PID_PARAM(Kd,e));
87 87
         #ifdef PID_ADD_EXTRUSION_RATE
88
-        EEPROM_WRITE_VAR(i,Kc[e]);
88
+        EEPROM_WRITE_VAR(i,PID_PARAM(Kc,e));
89 89
         #else//PID_ADD_EXTRUSION_RATE
90 90
 		dummy = 1.0f; // 1.0 = default kc
91 91
 	    EEPROM_WRITE_VAR(dummmy);
@@ -232,9 +232,9 @@ SERIAL_ECHOLNPGM("Scaling factors:");
232 232
     SERIAL_ECHO_START;
233 233
     SERIAL_ECHOLNPGM("PID settings:");
234 234
 	SERIAL_ECHO_START;
235
-    SERIAL_ECHOPAIR("   M301 P", Kp[0]); // for compatibility with hosts, only echos values for E0
236
-    SERIAL_ECHOPAIR(" I" ,unscalePID_i(Ki[0])); 
237
-    SERIAL_ECHOPAIR(" D" ,unscalePID_d(Kd[0]));  
235
+    SERIAL_ECHOPAIR("   M301 P", PID_PARAM(Kp,0)); // for compatibility with hosts, only echos values for E0
236
+	SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0)));
237
+	SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0)));
238 238
     SERIAL_ECHOLN(""); 
239 239
 #endif//PIDTEMP
240 240
 #ifdef FWRETRACT
@@ -341,11 +341,11 @@ void Config_RetrieveSettings()
341 341
 		  if (e < EXTRUDERS)
342 342
 		  {
343 343
 		    // do not need to scale PID values as the values in EEPROM are already scaled			  
344
-            EEPROM_READ_VAR(i,Kp[e]);
345
-            EEPROM_READ_VAR(i,Ki[e]);
346
-		    EEPROM_READ_VAR(i,Kd[e]);
344
+            EEPROM_READ_VAR(i,PID_PARAM(Kp,e));
345
+            EEPROM_READ_VAR(i,PID_PARAM(Ki,e));
346
+		    EEPROM_READ_VAR(i,PID_PARAM(Kd,e));
347 347
 #ifdef PID_ADD_EXTRUSION_RATE
348
-            EEPROM_READ_VAR(i,Kc[e]);
348
+            EEPROM_READ_VAR(i,PID_PARAM(Kc,e));
349 349
 #else//PID_ADD_EXTRUSION_RATE
350 350
 	        EEPROM_READ_VAR(i,dummy);
351 351
 #endif//PID_ADD_EXTRUSION_RATE
@@ -470,14 +470,18 @@ void Config_ResetDefault()
470 470
     lcd_contrast = DEFAULT_LCD_CONTRAST;
471 471
 #endif//DOGLCD
472 472
 #ifdef PIDTEMP
473
+#ifdef PID_PARAMS_PER_EXTRUDER
473 474
 	for (int e = 0; e < EXTRUDERS; e++)
475
+#else // PID_PARAMS_PER_EXTRUDER
476
+	int e = 0; // only need to write once
477
+#endif // PID_PARAMS_PER_EXTRUDER
474 478
 	{
475
-      Kp[e] = DEFAULT_Kp;
476
-      Ki[e] = scalePID_i(DEFAULT_Ki);
477
-      Kd[e] = scalePID_d(DEFAULT_Kd);
478
-#ifdef PID_ADD_EXTRUSION_RATE
479
-      Kc[e] = DEFAULT_Kc;
480
-#endif//PID_ADD_EXTRUSION_RATE
479
+      PID_PARAM(Kp,e) = DEFAULT_Kp;
480
+      PID_PARAM(Ki,e) = scalePID_i(DEFAULT_Ki);
481
+      PID_PARAM(Kd,e) = scalePID_d(DEFAULT_Kd);
482
+      #ifdef PID_ADD_EXTRUSION_RATE
483
+        PID_PARAM(Kc,e) = DEFAULT_Kc;
484
+      #endif//PID_ADD_EXTRUSION_RATE
481 485
     }
482 486
     // call updatePID (similar to when we have processed M301)
483 487
     updatePID();

+ 12
- 10
Marlin/Marlin_main.cpp View File

@@ -3209,27 +3209,29 @@ Sigma_Exit:
3209 3209
 		if (e < EXTRUDERS) // catch bad input value
3210 3210
 		{
3211 3211
 
3212
-			if (code_seen('P')) Kp[e] = code_value();
3213
-			if (code_seen('I')) Ki[e] = scalePID_i(code_value());
3214
-			if (code_seen('D')) Kd[e] = scalePID_d(code_value());
3212
+			if (code_seen('P')) PID_PARAM(Kp,e) = code_value();
3213
+			if (code_seen('I')) PID_PARAM(Ki,e) = scalePID_i(code_value());
3214
+			if (code_seen('D')) PID_PARAM(Kd,e) = scalePID_d(code_value());
3215 3215
 			#ifdef PID_ADD_EXTRUSION_RATE
3216
-			if (code_seen('C')) Kc[e] = code_value();
3216
+			if (code_seen('C')) PID_PARAM(Kc,e) = code_value();
3217 3217
 			#endif			
3218 3218
 
3219 3219
 			updatePID();
3220 3220
 			SERIAL_PROTOCOL(MSG_OK);
3221
-			SERIAL_PROTOCOL(" e:"); // specify extruder in serial output
3222
-			SERIAL_PROTOCOL(e);
3221
+            #ifdef PID_PARAMS_PER_EXTRUDER
3222
+			  SERIAL_PROTOCOL(" e:"); // specify extruder in serial output
3223
+			  SERIAL_PROTOCOL(e);
3224
+            #endif // PID_PARAMS_PER_EXTRUDER
3223 3225
 			SERIAL_PROTOCOL(" p:");
3224
-			SERIAL_PROTOCOL(Kp[e]);
3226
+			SERIAL_PROTOCOL(PID_PARAM(Kp,e));
3225 3227
 			SERIAL_PROTOCOL(" i:");
3226
-			SERIAL_PROTOCOL(unscalePID_i(Ki[e]));
3228
+			SERIAL_PROTOCOL(unscalePID_i(PID_PARAM(Ki,e)));
3227 3229
 			SERIAL_PROTOCOL(" d:");
3228
-			SERIAL_PROTOCOL(unscalePID_d(Kd[e]));
3230
+			SERIAL_PROTOCOL(unscalePID_d(PID_PARAM(Kd,e)));
3229 3231
 			#ifdef PID_ADD_EXTRUSION_RATE
3230 3232
 			SERIAL_PROTOCOL(" c:");
3231 3233
 			//Kc does not have scaling applied above, or in resetting defaults
3232
-			SERIAL_PROTOCOL(Kc[e]);
3234
+			SERIAL_PROTOCOL(PID_PARAM(Kc,e));
3233 3235
 			#endif
3234 3236
 			SERIAL_PROTOCOLLN("");
3235 3237
 		

+ 17
- 8
Marlin/temperature.cpp View File

@@ -126,12 +126,21 @@ static volatile bool temp_meas_ready = false;
126 126
 #endif
127 127
 
128 128
 #ifdef PIDTEMP
129
+#ifdef PID_PARAMS_PER_EXTRUDER
129 130
   float Kp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp);
130 131
   float Ki[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT);
131 132
   float Kd[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT);
132
-#ifdef PID_ADD_EXTRUSION_RATE
133
-  float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc);
134
-#endif
133
+  #ifdef PID_ADD_EXTRUSION_RATE
134
+    float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc);
135
+  #endif // PID_ADD_EXTRUSION_RATE
136
+#else //PID_PARAMS_PER_EXTRUDER
137
+  float Kp = DEFAULT_Kp;
138
+  float Ki = DEFAULT_Ki * PID_dT;
139
+  float Kd = DEFAULT_Kd / PID_dT;
140
+  #ifdef PID_ADD_EXTRUSION_RATE
141
+    float Kc = DEFAULT_Kc;
142
+  #endif // PID_ADD_EXTRUSION_RATE
143
+#endif // PID_PARAMS_PER_EXTRUDER
135 144
 #endif //PIDTEMP
136 145
 
137 146
 // Init min and max temp with extreme values to prevent false errors during startup
@@ -343,7 +352,7 @@ void updatePID()
343 352
 {
344 353
 #ifdef PIDTEMP
345 354
   for(int e = 0; e < EXTRUDERS; e++) { 
346
-     temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e];  
355
+     temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);  
347 356
   }
348 357
 #endif
349 358
 #ifdef PIDTEMPBED
@@ -464,14 +473,14 @@ void manage_heater()
464 473
             temp_iState[e] = 0.0;
465 474
             pid_reset[e] = false;
466 475
           }
467
-          pTerm[e] = Kp[e] * pid_error[e];
476
+          pTerm[e] = PID_PARAM(Kp,e) * pid_error[e];
468 477
           temp_iState[e] += pid_error[e];
469 478
           temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
470
-          iTerm[e] = Ki[e] * temp_iState[e];
479
+          iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e];
471 480
 
472 481
           //K1 defined in Configuration.h in the PID settings
473 482
           #define K2 (1.0-K1)
474
-          dTerm[e] = (Kd[e] * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
483
+          dTerm[e] = (PID_PARAM(Kd,e) * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
475 484
           pid_output = pTerm[e] + iTerm[e] - dTerm[e];
476 485
           if (pid_output > PID_MAX) {
477 486
             if (pid_error[e] > 0 )  temp_iState[e] -= pid_error[e]; // conditional un-integration
@@ -811,7 +820,7 @@ void tp_init()
811 820
     maxttemp[e] = maxttemp[0];
812 821
 #ifdef PIDTEMP
813 822
     temp_iState_min[e] = 0.0;
814
-    temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki[e];
823
+    temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
815 824
 #endif //PIDTEMP
816 825
 #ifdef PIDTEMPBED
817 826
     temp_iState_min_bed = 0.0;

+ 8
- 1
Marlin/temperature.h View File

@@ -58,7 +58,14 @@ extern float current_temperature_bed;
58 58
 #endif
59 59
 
60 60
 #ifdef PIDTEMP
61
-  extern float Kp[EXTRUDERS], Ki[EXTRUDERS], Kd[EXTRUDERS], Kc[EXTRUDERS];
61
+
62
+  #ifdef PID_PARAMS_PER_EXTRUDER
63
+    extern float Kp[EXTRUDERS], Ki[EXTRUDERS], Kd[EXTRUDERS], Kc[EXTRUDERS]; // one param per extruder
64
+    #define PID_PARAM(param,e) param[e] // use macro to point to array value
65
+  #else
66
+    extern float Kp, Ki, Kd, Kc; // one param per extruder - saves 20 or 36 bytes of ram (inc array pointer)
67
+    #define PID_PARAM(param, e) param // use macro to point directly to value
68
+  #endif // PID_PARAMS_PER_EXTRUDER	
62 69
   float scalePID_i(float i);
63 70
   float scalePID_d(float d);
64 71
   float unscalePID_i(float i);

+ 36
- 34
Marlin/ultralcd.cpp View File

@@ -790,41 +790,43 @@ static void lcd_control_temperature_menu()
790 790
 #ifdef PIDTEMP
791 791
 	// set up temp variables - undo the default scaling
792 792
 	pid_current_extruder = 0;
793
-	raw_Ki = unscalePID_i(Ki[0]);
794
-	raw_Kd = unscalePID_d(Kd[0]);
795
-	MENU_ITEM_EDIT(float52, MSG_PID_P, &Kp[0], 1, 9990);
793
+	raw_Ki = unscalePID_i(PID_PARAM(Ki,0));
794
+	raw_Kd = unscalePID_d(PID_PARAM(Kd,0));
795
+	MENU_ITEM_EDIT(float52, MSG_PID_P, &PID_PARAM(Kp,0), 1, 9990);
796 796
 	// i is typically a small value so allows values below 1
797 797
 	MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
798 798
 	MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D, &raw_Kd, 1, 9990, copy_and_scalePID_d);
799
-# ifdef PID_ADD_EXTRUSION_RATE
800
-	MENU_ITEM_EDIT(float3, MSG_PID_C, &Kc[0], 1, 9990);
801
-# endif//PID_ADD_EXTRUSION_RATE
802
-#if EXTRUDERS > 1
803
-	// set up temp variables - undo the default scaling
804
-	pid_current_extruder = 1;
805
-	raw_Ki = unscalePID_i(Ki[1]);
806
-	raw_Kd = unscalePID_d(Kd[1]);
807
-	MENU_ITEM_EDIT(float52, MSG_PID_P1, &Kp[1], 1, 9990);
808
-	// i is typically a small value so allows values below 1
809
-	MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I1, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
810
-	MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D1, &raw_Kd, 1, 9990, copy_and_scalePID_d);
811
-# ifdef PID_ADD_EXTRUSION_RATE
812
-	MENU_ITEM_EDIT(float3, MSG_PID_C1, &Kc[1], 1, 9990);
813
-# endif//PID_ADD_EXTRUSION_RATE	
814
-#endif//EXTRUDERS > 1
815
-#if EXTRUDERS > 2
816
-	// set up temp variables - undo the default scaling
817
-	pid_current_extruder = 2;
818
-	raw_Ki = unscalePID_i(Ki[2]);
819
-	raw_Kd = unscalePID_d(Kd[2]);
820
-	MENU_ITEM_EDIT(float52, MSG_PID_P2, &Kp[2], 1, 9990);
821
-	// i is typically a small value so allows values below 1
822
-	MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I2, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
823
-	MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D2, &raw_Kd, 1, 9990, copy_and_scalePID_d);
824
-# ifdef PID_ADD_EXTRUSION_RATE
825
-	MENU_ITEM_EDIT(float3, MSG_PID_C2, &Kc[2], 1, 9990);
826
-# endif//PID_ADD_EXTRUSION_RATE	
827
-#endif//EXTRUDERS > 2
799
+    #ifdef PID_ADD_EXTRUSION_RATE
800
+	  MENU_ITEM_EDIT(float3, MSG_PID_C, &PID_PARAM(Kc,0), 1, 9990);
801
+    #endif//PID_ADD_EXTRUSION_RATE
802
+#ifdef PID_PARAMS_PER_EXTRUDER
803
+  #if EXTRUDERS > 1
804
+	  // set up temp variables - undo the default scaling
805
+	  pid_current_extruder = 0;
806
+	  raw_Ki = unscalePID_i(PID_PARAM(Ki,1));
807
+	  raw_Kd = unscalePID_d(PID_PARAM(Kd,1));
808
+	  MENU_ITEM_EDIT(float52, MSG_PID_P1, &PID_PARAM(Kp,1), 1, 9990);
809
+	  // i is typically a small value so allows values below 1
810
+	  MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I1, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
811
+	  MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D1, &raw_Kd, 1, 9990, copy_and_scalePID_d);
812
+      #ifdef PID_ADD_EXTRUSION_RATE
813
+	    MENU_ITEM_EDIT(float3, MSG_PID_C1, &PID_PARAM(Kc,1), 1, 9990);
814
+      #endif//PID_ADD_EXTRUSION_RATE
815
+  #endif//EXTRUDERS > 1
816
+  #if EXTRUDERS > 2
817
+	    // set up temp variables - undo the default scaling
818
+	    pid_current_extruder = 0;
819
+	    raw_Ki = unscalePID_i(PID_PARAM(Ki,2));
820
+	    raw_Kd = unscalePID_d(PID_PARAM(Kd,2));
821
+	    MENU_ITEM_EDIT(float52, MSG_PID_P2, &PID_PARAM(Kp,2), 1, 9990);
822
+	    // i is typically a small value so allows values below 1
823
+	    MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_I2, &raw_Ki, 0.01, 9990, copy_and_scalePID_i);
824
+	    MENU_ITEM_EDIT_CALLBACK(float52, MSG_PID_D2, &raw_Kd, 1, 9990, copy_and_scalePID_d);
825
+        #ifdef PID_ADD_EXTRUSION_RATE
826
+	      MENU_ITEM_EDIT(float3, MSG_PID_C2, &PID_PARAM(Kc,2), 1, 9990);
827
+        #endif//PID_ADD_EXTRUSION_RATE
828
+  #endif//EXTRUDERS > 2
829
+#endif // PID_PARAMS_PER_EXTRUDER
828 830
 #endif//PIDTEMP
829 831
     MENU_ITEM(submenu, MSG_PREHEAT_PLA_SETTINGS, lcd_control_temperature_preheat_pla_settings_menu);
830 832
     MENU_ITEM(submenu, MSG_PREHEAT_ABS_SETTINGS, lcd_control_temperature_preheat_abs_settings_menu);
@@ -1731,7 +1733,7 @@ char *ftostr52(const float &x)
1731 1733
 void copy_and_scalePID_i()
1732 1734
 {
1733 1735
 #ifdef PIDTEMP
1734
-  Ki[pid_current_extruder] = scalePID_i(raw_Ki);
1736
+  PID_PARAM(Ki, pid_current_extruder) = scalePID_i(raw_Ki);
1735 1737
   updatePID();
1736 1738
 #endif
1737 1739
 }
@@ -1741,7 +1743,7 @@ void copy_and_scalePID_i()
1741 1743
 void copy_and_scalePID_d()
1742 1744
 {
1743 1745
 #ifdef PIDTEMP
1744
-  Kd[pid_current_extruder] = scalePID_d(raw_Kd);
1746
+	PID_PARAM(Kd, pid_current_extruder) = scalePID_d(raw_Kd);
1745 1747
   updatePID();
1746 1748
 #endif
1747 1749
 }

Loading…
Cancel
Save