Selaa lähdekoodia

Added PID autotune. (experimental)

M303 Starts autotune. Wait till the Kp Ki and Kd constants are printed.
Put these values in Configuration.h
Erik van der Zalm 13 vuotta sitten
vanhempi
commit
c077316b2b
5 muutettua tiedostoa jossa 274 lisäystä ja 169 poistoa
  1. 8
    0
      Marlin/Marlin.pde
  2. 1
    1
      Marlin/pins.h
  3. 88
    1
      Marlin/temperature.cpp
  4. 164
    161
      Marlin/temperature.h
  5. 13
    6
      Marlin/ultralcd.pde

+ 8
- 0
Marlin/Marlin.pde Näytä tiedosto

@@ -109,6 +109,7 @@
109 109
 // M501 - reads parameters from EEPROM (if you need reset them after you changed them temporarily).  
110 110
 // M502 - reverts to the default "factory settings".  You still need to store them in EEPROM afterwards if you want to.
111 111
 // M503 - print the current settings (from memory not from eeprom)
112
+// M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
112 113
 
113 114
 //Stepper Movement Variables
114 115
 
@@ -1197,6 +1198,13 @@ void process_commands()
1197 1198
       allow_cold_extrudes(true);
1198 1199
     }
1199 1200
     break;
1201
+    case 303: // M303 PID autotune
1202
+    {
1203
+      float temp = 150.0;
1204
+      if (code_seen('S')) temp=code_value();
1205
+      PID_autotune(temp);
1206
+    }
1207
+    break;
1200 1208
     case 400: // finish all moves
1201 1209
     {
1202 1210
       st_synchronize();

+ 1
- 1
Marlin/pins.h Näytä tiedosto

@@ -734,7 +734,7 @@
734 734
     #define encrot2 3
735 735
     #define encrot3 1
736 736
 
737
-    
737
+    #define SDCARDDETECT -1
738 738
     //bits in the shift register that carry the buttons for:
739 739
     // left up center down right red
740 740
     #define BL_LE 7

+ 88
- 1
Marlin/temperature.cpp Näytä tiedosto

@@ -62,7 +62,7 @@ int current_raw_bed = 0;
62 62
 //===========================================================================
63 63
 //=============================private variables============================
64 64
 //===========================================================================
65
-static bool temp_meas_ready = false;
65
+static volatile bool temp_meas_ready = false;
66 66
 
67 67
 static unsigned long  previous_millis_bed_heater;
68 68
 //static unsigned long previous_millis_heater;
@@ -132,7 +132,94 @@ static unsigned long  previous_millis_bed_heater;
132 132
 //===========================================================================
133 133
 //=============================   functions      ============================
134 134
 //===========================================================================
135
+
136
+void PID_autotune(float temp)
137
+{
138
+  float input;
139
+  int cycles=0;
140
+  bool heating = true;
141
+  soft_pwm[0] = 255>>1;
142
+
143
+  unsigned long temp_millis = millis();
144
+  unsigned long t1=temp_millis;
145
+  unsigned long t2=temp_millis;
146
+  long t_high;
147
+  long t_low;
148
+
149
+  long bias=127;
150
+  long d = 127;
151
+  float Ku, Tu;
152
+  float Kp, Ki, Kd;
153
+  float max, min;
135 154
   
155
+  SERIAL_ECHOLN("PID Autotune start");
156
+
157
+  for(;;) {
158
+
159
+    if(temp_meas_ready == true) { // temp sample ready
160
+      CRITICAL_SECTION_START;
161
+      temp_meas_ready = false;
162
+      CRITICAL_SECTION_END;
163
+      input = analog2temp(current_raw[0], 0);
164
+      
165
+      max=max(max,input);
166
+      min=min(min,input);
167
+      if(heating == true && input > temp) {
168
+        if(millis() - t2 > 5000) { 
169
+          heating=false;
170
+          soft_pwm[0] = (bias - d) >> 1;
171
+          t1=millis();
172
+          t_high=t1 - t2;
173
+          max=temp;
174
+        }
175
+      }
176
+      if(heating == false && input < temp) {
177
+        if(millis() - t1 > 5000) {
178
+          heating=true;
179
+          t2=millis();
180
+          t_low=t2 - t1;
181
+          if(cycles > 0) {
182
+            bias += (d*(t_high - t_low))/(t_low + t_high);
183
+            bias = constrain(bias, 20 ,235);
184
+            if(bias > 127) d = 254 - bias;
185
+            else d = bias;
186
+
187
+            SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias);
188
+            SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d);
189
+            SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min);
190
+            SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max);
191
+            if(cycles > 2) {
192
+              Ku = (4.0*d)/(3.14159*(max-min)/2.0);
193
+              Tu = ((float)(t_low + t_high)/1000.0);
194
+              Kp = 0.6*Ku;
195
+              Ki = 2*Kp/Tu;
196
+              Kd = Kp*Tu/8;
197
+              SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
198
+              SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
199
+              SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
200
+            }
201
+          }
202
+          soft_pwm[0] = (bias + d) >> 1;
203
+          cycles++;
204
+          min=temp;
205
+        }
206
+      } 
207
+    }
208
+    if(input > (temp + 20)) {
209
+      SERIAL_PROTOCOLLNPGM("PID Autotune failed !!!, Temperature to high");
210
+      return;
211
+    }
212
+    if(millis() - temp_millis > 2000) {
213
+      temp_millis = millis();
214
+      SERIAL_PROTOCOLPGM("ok T:");
215
+      SERIAL_PROTOCOL(degHotend(0));   
216
+      SERIAL_PROTOCOLPGM(" @:");
217
+      SERIAL_PROTOCOLLN(getHeaterPower(0));       
218
+    }
219
+    LCD_STATUS;
220
+  }
221
+}
222
+
136 223
 void updatePID()
137 224
 {
138 225
 #ifdef PIDTEMP

+ 164
- 161
Marlin/temperature.h Näytä tiedosto

@@ -1,162 +1,165 @@
1
-/*
2
-  temperature.h - temperature controller
3
-  Part of Marlin
4
-
5
-  Copyright (c) 2011 Erik van der Zalm
6
-
7
-  Grbl is free software: you can redistribute it and/or modify
8
-  it under the terms of the GNU General Public License as published by
9
-  the Free Software Foundation, either version 3 of the License, or
10
-  (at your option) any later version.
11
-
12
-  Grbl is distributed in the hope that it will be useful,
13
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
-  GNU General Public License for more details.
16
-
17
-  You should have received a copy of the GNU General Public License
18
-  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
19
-*/
20
-
21
-#ifndef temperature_h
22
-#define temperature_h 
23
-
24
-#include "Marlin.h"
25
-#include "planner.h"
26
-#ifdef PID_ADD_EXTRUSION_RATE
27
-  #include "stepper.h"
28
-#endif
29
-
30
-// public functions
31
-void tp_init();  //initialise the heating
32
-void manage_heater(); //it is critical that this is called periodically.
33
-
34
-//low leven conversion routines
35
-// do not use this routines and variables outsie of temperature.cpp
36
-int temp2analog(int celsius, uint8_t e);
37
-int temp2analogBed(int celsius);
38
-float analog2temp(int raw, uint8_t e);
39
-float analog2tempBed(int raw);
40
-extern int target_raw[EXTRUDERS];  
41
-extern int heatingtarget_raw[EXTRUDERS];  
42
-extern int current_raw[EXTRUDERS];
43
-extern int target_raw_bed;
44
-extern int current_raw_bed;
45
-#ifdef BED_LIMIT_SWITCHING
46
-  extern int target_bed_low_temp ;  
47
-  extern int target_bed_high_temp ;
48
-#endif
49
-extern float Kp,Ki,Kd,Kc;
50
-
51
-#ifdef PIDTEMP
52
-  extern float pid_setpoint[EXTRUDERS];
53
-#endif
54
-  
55
-// #ifdef WATCHPERIOD
56
-  extern int watch_raw[EXTRUDERS] ;
57
-//   extern unsigned long watchmillis;
58
-// #endif
59
-
60
-
61
-//high level conversion routines, for use outside of temperature.cpp
62
-//inline so that there is no performance decrease.
63
-//deg=degreeCelsius
64
-
65
-FORCE_INLINE float degHotend(uint8_t extruder) {  
66
-  return analog2temp(current_raw[extruder], extruder);
67
-};
68
-
69
-FORCE_INLINE float degBed() {
70
-  return analog2tempBed(current_raw_bed);
71
-};
72
-
73
-FORCE_INLINE float degTargetHotend(uint8_t extruder) {  
74
-  return analog2temp(target_raw[extruder], extruder);
75
-};
76
-
77
-FORCE_INLINE float degTargetBed() {   
78
-  return analog2tempBed(target_raw_bed);
79
-};
80
-
81
-FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {  
82
-  target_raw[extruder] = temp2analog(celsius, extruder);
83
-#ifdef PIDTEMP
84
-  pid_setpoint[extruder] = celsius;
85
-#endif //PIDTEMP
86
-};
87
-
88
-FORCE_INLINE void setTargetBed(const float &celsius) {  
89
-  
90
-  target_raw_bed = temp2analogBed(celsius);
91
-  #ifdef BED_LIMIT_SWITCHING
92
-    if(celsius>BED_HYSTERESIS)
93
-    {
94
-    target_bed_low_temp= temp2analogBed(celsius-BED_HYSTERESIS);
95
-    target_bed_high_temp= temp2analogBed(celsius+BED_HYSTERESIS);
96
-    }
97
-    else
98
-    { 
99
-      target_bed_low_temp=0;
100
-      target_bed_high_temp=0;
101
-    }
102
-  #endif
103
-};
104
-
105
-FORCE_INLINE bool isHeatingHotend(uint8_t extruder){  
106
-  return target_raw[extruder] > current_raw[extruder];
107
-};
108
-
109
-FORCE_INLINE bool isHeatingBed() {
110
-  return target_raw_bed > current_raw_bed;
111
-};
112
-
113
-FORCE_INLINE bool isCoolingHotend(uint8_t extruder) {  
114
-  return target_raw[extruder] < current_raw[extruder];
115
-};
116
-
117
-FORCE_INLINE bool isCoolingBed() {
118
-  return target_raw_bed < current_raw_bed;
119
-};
120
-
121
-#define degHotend0() degHotend(0)
122
-#define degTargetHotend0() degTargetHotend(0)
123
-#define setTargetHotend0(_celsius) setTargetHotend((_celsius), 0)
124
-#define isHeatingHotend0() isHeatingHotend(0)
125
-#define isCoolingHotend0() isCoolingHotend(0)
126
-#if EXTRUDERS > 1
127
-#define degHotend1() degHotend(1)
128
-#define degTargetHotend1() degTargetHotend(1)
129
-#define setTargetHotend1(_celsius) setTargetHotend((_celsius), 1)
130
-#define isHeatingHotend1() isHeatingHotend(1)
131
-#define isCoolingHotend1() isCoolingHotend(1)
132
-#endif
133
-#if EXTRUDERS > 2
134
-#define degHotend2() degHotend(2)
135
-#define degTargetHotend2() degTargetHotend(2)
136
-#define setTargetHotend2(_celsius) setTargetHotend((_celsius), 2)
137
-#define isHeatingHotend2() isHeatingHotend(2)
138
-#define isCoolingHotend2() isCoolingHotend(2)
139
-#endif
140
-#if EXTRUDERS > 3
141
-#error Invalid number of extruders
142
-#endif
143
-
144
-
145
-
146
-int getHeaterPower(int heater);
147
-void disable_heater();
148
-void setWatch();
149
-void updatePID();
150
-
151
-FORCE_INLINE void autotempShutdown(){
152
- #ifdef AUTOTEMP
153
- if(autotemp_enabled)
154
- {
155
-  autotemp_enabled=false;
156
-  if(degTargetHotend(ACTIVE_EXTRUDER)>autotemp_min)
157
-    setTargetHotend(0,ACTIVE_EXTRUDER);
158
- }
159
- #endif
160
-}
161
-#endif
1
+/*
2
+  temperature.h - temperature controller
3
+  Part of Marlin
4
+
5
+  Copyright (c) 2011 Erik van der Zalm
6
+
7
+  Grbl is free software: you can redistribute it and/or modify
8
+  it under the terms of the GNU General Public License as published by
9
+  the Free Software Foundation, either version 3 of the License, or
10
+  (at your option) any later version.
11
+
12
+  Grbl is distributed in the hope that it will be useful,
13
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+  GNU General Public License for more details.
16
+
17
+  You should have received a copy of the GNU General Public License
18
+  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
19
+*/
20
+
21
+#ifndef temperature_h
22
+#define temperature_h 
23
+
24
+#include "Marlin.h"
25
+#include "planner.h"
26
+#ifdef PID_ADD_EXTRUSION_RATE
27
+  #include "stepper.h"
28
+#endif
29
+
30
+// public functions
31
+void tp_init();  //initialise the heating
32
+void manage_heater(); //it is critical that this is called periodically.
33
+
34
+//low leven conversion routines
35
+// do not use this routines and variables outsie of temperature.cpp
36
+int temp2analog(int celsius, uint8_t e);
37
+int temp2analogBed(int celsius);
38
+float analog2temp(int raw, uint8_t e);
39
+float analog2tempBed(int raw);
40
+extern int target_raw[EXTRUDERS];  
41
+extern int heatingtarget_raw[EXTRUDERS];  
42
+extern int current_raw[EXTRUDERS];
43
+extern int target_raw_bed;
44
+extern int current_raw_bed;
45
+#ifdef BED_LIMIT_SWITCHING
46
+  extern int target_bed_low_temp ;  
47
+  extern int target_bed_high_temp ;
48
+#endif
49
+extern float Kp,Ki,Kd,Kc;
50
+
51
+#ifdef PIDTEMP
52
+  extern float pid_setpoint[EXTRUDERS];
53
+#endif
54
+  
55
+// #ifdef WATCHPERIOD
56
+  extern int watch_raw[EXTRUDERS] ;
57
+//   extern unsigned long watchmillis;
58
+// #endif
59
+
60
+
61
+//high level conversion routines, for use outside of temperature.cpp
62
+//inline so that there is no performance decrease.
63
+//deg=degreeCelsius
64
+
65
+FORCE_INLINE float degHotend(uint8_t extruder) {  
66
+  return analog2temp(current_raw[extruder], extruder);
67
+};
68
+
69
+FORCE_INLINE float degBed() {
70
+  return analog2tempBed(current_raw_bed);
71
+};
72
+
73
+FORCE_INLINE float degTargetHotend(uint8_t extruder) {  
74
+  return analog2temp(target_raw[extruder], extruder);
75
+};
76
+
77
+FORCE_INLINE float degTargetBed() {   
78
+  return analog2tempBed(target_raw_bed);
79
+};
80
+
81
+FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {  
82
+  target_raw[extruder] = temp2analog(celsius, extruder);
83
+#ifdef PIDTEMP
84
+  pid_setpoint[extruder] = celsius;
85
+#endif //PIDTEMP
86
+};
87
+
88
+FORCE_INLINE void setTargetBed(const float &celsius) {  
89
+  
90
+  target_raw_bed = temp2analogBed(celsius);
91
+  #ifdef BED_LIMIT_SWITCHING
92
+    if(celsius>BED_HYSTERESIS)
93
+    {
94
+    target_bed_low_temp= temp2analogBed(celsius-BED_HYSTERESIS);
95
+    target_bed_high_temp= temp2analogBed(celsius+BED_HYSTERESIS);
96
+    }
97
+    else
98
+    { 
99
+      target_bed_low_temp=0;
100
+      target_bed_high_temp=0;
101
+    }
102
+  #endif
103
+};
104
+
105
+FORCE_INLINE bool isHeatingHotend(uint8_t extruder){  
106
+  return target_raw[extruder] > current_raw[extruder];
107
+};
108
+
109
+FORCE_INLINE bool isHeatingBed() {
110
+  return target_raw_bed > current_raw_bed;
111
+};
112
+
113
+FORCE_INLINE bool isCoolingHotend(uint8_t extruder) {  
114
+  return target_raw[extruder] < current_raw[extruder];
115
+};
116
+
117
+FORCE_INLINE bool isCoolingBed() {
118
+  return target_raw_bed < current_raw_bed;
119
+};
120
+
121
+#define degHotend0() degHotend(0)
122
+#define degTargetHotend0() degTargetHotend(0)
123
+#define setTargetHotend0(_celsius) setTargetHotend((_celsius), 0)
124
+#define isHeatingHotend0() isHeatingHotend(0)
125
+#define isCoolingHotend0() isCoolingHotend(0)
126
+#if EXTRUDERS > 1
127
+#define degHotend1() degHotend(1)
128
+#define degTargetHotend1() degTargetHotend(1)
129
+#define setTargetHotend1(_celsius) setTargetHotend((_celsius), 1)
130
+#define isHeatingHotend1() isHeatingHotend(1)
131
+#define isCoolingHotend1() isCoolingHotend(1)
132
+#endif
133
+#if EXTRUDERS > 2
134
+#define degHotend2() degHotend(2)
135
+#define degTargetHotend2() degTargetHotend(2)
136
+#define setTargetHotend2(_celsius) setTargetHotend((_celsius), 2)
137
+#define isHeatingHotend2() isHeatingHotend(2)
138
+#define isCoolingHotend2() isCoolingHotend(2)
139
+#endif
140
+#if EXTRUDERS > 3
141
+#error Invalid number of extruders
142
+#endif
143
+
144
+
145
+
146
+int getHeaterPower(int heater);
147
+void disable_heater();
148
+void setWatch();
149
+void updatePID();
150
+
151
+FORCE_INLINE void autotempShutdown(){
152
+ #ifdef AUTOTEMP
153
+ if(autotemp_enabled)
154
+ {
155
+  autotemp_enabled=false;
156
+  if(degTargetHotend(ACTIVE_EXTRUDER)>autotemp_min)
157
+    setTargetHotend(0,ACTIVE_EXTRUDER);
158
+ }
159
+ #endif
160
+}
161
+
162
+void PID_autotune(float temp);
163
+
164
+#endif
162 165
 

+ 13
- 6
Marlin/ultralcd.pde Näytä tiedosto

@@ -315,19 +315,18 @@ void MainMenu::showStatus()
315 315
   static int olddegHotEnd0=-1;
316 316
   static int oldtargetHotEnd0=-1;
317 317
   //force_lcd_update=true;
318
-  if(force_lcd_update||feedmultiplychanged)  //initial display of content
318
+  if(force_lcd_update)  //initial display of content
319 319
   {
320
-    feedmultiplychanged=false;
321 320
     encoderpos=feedmultiply;
322 321
     clear();
323
-    lcd.setCursor(0,0);lcdprintPGM("\002123/567\001 ");
322
+    lcd.setCursor(0,0);lcdprintPGM("\002---/---\001 ");
324 323
     #if defined BED_USES_THERMISTOR || defined BED_USES_AD595 
325
-      lcd.setCursor(10,0);lcdprintPGM("B123/567\001 ");
324
+      lcd.setCursor(10,0);lcdprintPGM("B---/---\001 ");
326 325
     #endif
327 326
   }
328 327
     
329 328
   int tHotEnd0=intround(degHotend0());
330
-  if((abs(tHotEnd0-olddegHotEnd0)>1)||force_lcd_update) //>1 because otherwise the lcd is refreshed to often.
329
+  if((tHotEnd0!=olddegHotEnd0)||force_lcd_update)
331 330
   {
332 331
     lcd.setCursor(1,0);
333 332
     lcd.print(ftostr3(tHotEnd0));
@@ -379,8 +378,15 @@ void MainMenu::showStatus()
379 378
     lcdprintPGM("Z:");lcd.print(ftostr52(current_position[2]));
380 379
     oldzpos=currentz;
381 380
   }
381
+  
382 382
   static int oldfeedmultiply=0;
383 383
   int curfeedmultiply=feedmultiply;
384
+  
385
+  if(feedmultiplychanged == true) {
386
+    feedmultiplychanged == false;
387
+    encoderpos = curfeedmultiply;
388
+  }
389
+  
384 390
   if(encoderpos!=curfeedmultiply||force_lcd_update)
385 391
   {
386 392
    curfeedmultiply=encoderpos;
@@ -391,12 +397,14 @@ void MainMenu::showStatus()
391 397
    feedmultiply=curfeedmultiply;
392 398
    encoderpos=curfeedmultiply;
393 399
   }
400
+  
394 401
   if((curfeedmultiply!=oldfeedmultiply)||force_lcd_update)
395 402
   {
396 403
    oldfeedmultiply=curfeedmultiply;
397 404
    lcd.setCursor(0,2);
398 405
    lcd.print(itostr3(curfeedmultiply));lcdprintPGM("% ");
399 406
   }
407
+  
400 408
   if(messagetext[0]!='\0')
401 409
   {
402 410
     lcd.setCursor(0,LCD_HEIGHT-1);
@@ -404,7 +412,6 @@ void MainMenu::showStatus()
404 412
     uint8_t n=strlen(messagetext);
405 413
     for(int8_t i=0;i<LCD_WIDTH-n;i++)
406 414
       lcd.print(" ");
407
-    
408 415
     messagetext[0]='\0';
409 416
   }
410 417
   

Loading…
Peruuta
Tallenna