|
@@ -57,6 +57,15 @@ int current_raw_bed = 0;
|
57
|
57
|
float Kc=DEFAULT_Kc;
|
58
|
58
|
#endif
|
59
|
59
|
#endif //PIDTEMP
|
|
60
|
+
|
|
61
|
+#ifdef PIDTEMPBED
|
|
62
|
+ // used external
|
|
63
|
+ float pid_setpoint_bed = { 0.0 };
|
|
64
|
+
|
|
65
|
+ float bedKp=DEFAULT_bedKp;
|
|
66
|
+ float bedKi=(DEFAULT_bedKi*PID_dT);
|
|
67
|
+ float bedKd=(DEFAULT_bedKd/PID_dT);
|
|
68
|
+#endif //PIDTEMPBED
|
60
|
69
|
|
61
|
70
|
|
62
|
71
|
//===========================================================================
|
|
@@ -64,9 +73,6 @@ int current_raw_bed = 0;
|
64
|
73
|
//===========================================================================
|
65
|
74
|
static volatile bool temp_meas_ready = false;
|
66
|
75
|
|
67
|
|
-static unsigned long previous_millis_bed_heater;
|
68
|
|
-//static unsigned long previous_millis_heater;
|
69
|
|
-
|
70
|
76
|
#ifdef PIDTEMP
|
71
|
77
|
//static cannot be external:
|
72
|
78
|
static float temp_iState[EXTRUDERS] = { 0 };
|
|
@@ -82,7 +88,20 @@ static unsigned long previous_millis_bed_heater;
|
82
|
88
|
// static float pid_output[EXTRUDERS];
|
83
|
89
|
static bool pid_reset[EXTRUDERS];
|
84
|
90
|
#endif //PIDTEMP
|
|
91
|
+#ifdef PIDTEMPBED
|
|
92
|
+ //static cannot be external:
|
|
93
|
+ static float temp_iState_bed = { 0 };
|
|
94
|
+ static float temp_dState_bed = { 0 };
|
|
95
|
+ static float pTerm_bed;
|
|
96
|
+ static float iTerm_bed;
|
|
97
|
+ static float dTerm_bed;
|
|
98
|
+ //int output;
|
|
99
|
+ static float pid_error_bed;
|
|
100
|
+ static float temp_iState_min_bed;
|
|
101
|
+ static float temp_iState_max_bed;
|
|
102
|
+#endif //PIDTEMPBED
|
85
|
103
|
static unsigned char soft_pwm[EXTRUDERS];
|
|
104
|
+ static unsigned char soft_pwm_bed;
|
86
|
105
|
|
87
|
106
|
#ifdef WATCHPERIOD
|
88
|
107
|
int watch_raw[EXTRUDERS] = { -1000 }; // the first value used for all
|
|
@@ -122,7 +141,7 @@ static unsigned long previous_millis_bed_heater;
|
122
|
141
|
//============================= functions ============================
|
123
|
142
|
//===========================================================================
|
124
|
143
|
|
125
|
|
-void PID_autotune(float temp)
|
|
144
|
+void PID_autotune(float temp, int extruder, int ncycles)
|
126
|
145
|
{
|
127
|
146
|
float input;
|
128
|
147
|
int cycles=0;
|
|
@@ -139,27 +158,45 @@ void PID_autotune(float temp)
|
139
|
158
|
float Ku, Tu;
|
140
|
159
|
float Kp, Ki, Kd;
|
141
|
160
|
float max, min;
|
142
|
|
-
|
|
161
|
+
|
|
162
|
+ if ((extruder > EXTRUDERS)
|
|
163
|
+ #if (TEMP_BED_PIN <= -1)
|
|
164
|
+ ||(extruder < 0)
|
|
165
|
+ #endif
|
|
166
|
+ ){
|
|
167
|
+ SERIAL_ECHOLN("PID Autotune failed. Bad extruder number.");
|
|
168
|
+ return;
|
|
169
|
+ }
|
|
170
|
+
|
143
|
171
|
SERIAL_ECHOLN("PID Autotune start");
|
144
|
172
|
|
145
|
173
|
disable_heater(); // switch off all heaters.
|
146
|
|
-
|
147
|
|
- soft_pwm[0] = PID_MAX/2;
|
148
|
|
-
|
149
|
|
- for(;;) {
|
|
174
|
+
|
|
175
|
+ if (extruder<0)
|
|
176
|
+ soft_pwm_bed = PID_MAX/2;
|
|
177
|
+ else
|
|
178
|
+ soft_pwm[extruder] = PID_MAX/2;
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+ for(;;) {
|
150
|
184
|
|
151
|
185
|
if(temp_meas_ready == true) { // temp sample ready
|
152
|
186
|
CRITICAL_SECTION_START;
|
153
|
187
|
temp_meas_ready = false;
|
154
|
188
|
CRITICAL_SECTION_END;
|
155
|
|
- input = analog2temp(current_raw[0], 0);
|
156
|
|
-
|
|
189
|
+ input = (extruder<0)?analog2tempBed(current_raw_bed):analog2temp(current_raw[extruder], extruder);
|
|
190
|
+
|
157
|
191
|
max=max(max,input);
|
158
|
192
|
min=min(min,input);
|
159
|
193
|
if(heating == true && input > temp) {
|
160
|
194
|
if(millis() - t2 > 5000) {
|
161
|
195
|
heating=false;
|
162
|
|
- soft_pwm[0] = (bias - d) >> 1;
|
|
196
|
+ if (extruder<0)
|
|
197
|
+ soft_pwm_bed = (bias - d) >> 1;
|
|
198
|
+ else
|
|
199
|
+ soft_pwm[extruder] = (bias - d) >> 1;
|
163
|
200
|
t1=millis();
|
164
|
201
|
t_high=t1 - t2;
|
165
|
202
|
max=temp;
|
|
@@ -210,7 +247,10 @@ void PID_autotune(float temp)
|
210
|
247
|
*/
|
211
|
248
|
}
|
212
|
249
|
}
|
213
|
|
- soft_pwm[0] = (bias + d) >> 1;
|
|
250
|
+ if (extruder<0)
|
|
251
|
+ soft_pwm_bed = (bias + d) >> 1;
|
|
252
|
+ else
|
|
253
|
+ soft_pwm[extruder] = (bias + d) >> 1;
|
214
|
254
|
cycles++;
|
215
|
255
|
min=temp;
|
216
|
256
|
}
|
|
@@ -221,17 +261,26 @@ void PID_autotune(float temp)
|
221
|
261
|
return;
|
222
|
262
|
}
|
223
|
263
|
if(millis() - temp_millis > 2000) {
|
224
|
|
- temp_millis = millis();
|
225
|
|
- SERIAL_PROTOCOLPGM("ok T:");
|
226
|
|
- SERIAL_PROTOCOL(degHotend(0));
|
|
264
|
+ int p;
|
|
265
|
+ if (extruder<0){
|
|
266
|
+ p=soft_pwm_bed;
|
|
267
|
+ SERIAL_PROTOCOLPGM("ok B:");
|
|
268
|
+ }else{
|
|
269
|
+ p=soft_pwm[extruder];
|
|
270
|
+ SERIAL_PROTOCOLPGM("ok T:");
|
|
271
|
+ }
|
|
272
|
+
|
|
273
|
+ SERIAL_PROTOCOL(input);
|
227
|
274
|
SERIAL_PROTOCOLPGM(" @:");
|
228
|
|
- SERIAL_PROTOCOLLN(getHeaterPower(0));
|
|
275
|
+ SERIAL_PROTOCOLLN(p);
|
|
276
|
+
|
|
277
|
+ temp_millis = millis();
|
229
|
278
|
}
|
230
|
279
|
if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
|
231
|
280
|
SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
|
232
|
281
|
return;
|
233
|
282
|
}
|
234
|
|
- if(cycles > 5) {
|
|
283
|
+ if(cycles > ncycles) {
|
235
|
284
|
SERIAL_PROTOCOLLNPGM("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h");
|
236
|
285
|
return;
|
237
|
286
|
}
|
|
@@ -245,19 +294,18 @@ void updatePID()
|
245
|
294
|
for(int e = 0; e < EXTRUDERS; e++) {
|
246
|
295
|
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
|
247
|
296
|
}
|
|
297
|
+ temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
|
248
|
298
|
#endif
|
249
|
299
|
}
|
250
|
300
|
|
251
|
301
|
int getHeaterPower(int heater) {
|
|
302
|
+ if (heater<0)
|
|
303
|
+ return soft_pwm_bed;
|
252
|
304
|
return soft_pwm[heater];
|
253
|
305
|
}
|
254
|
306
|
|
255
|
307
|
void manage_heater()
|
256
|
308
|
{
|
257
|
|
-#ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
|
258
|
|
- static int bed_needs_heating=0;
|
259
|
|
- static int bed_is_on=0;
|
260
|
|
-#endif
|
261
|
309
|
|
262
|
310
|
#ifdef USE_WATCHDOG
|
263
|
311
|
wd_reset();
|
|
@@ -298,12 +346,16 @@ void manage_heater()
|
298
|
346
|
temp_iState[e] += pid_error[e];
|
299
|
347
|
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
|
300
|
348
|
iTerm[e] = Ki * temp_iState[e];
|
|
349
|
+
|
301
|
350
|
//K1 defined in Configuration.h in the PID settings
|
302
|
351
|
#define K2 (1.0-K1)
|
303
|
352
|
dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
|
304
|
353
|
temp_dState[e] = pid_input;
|
|
354
|
+
|
305
|
355
|
pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX);
|
306
|
356
|
}
|
|
357
|
+ #else
|
|
358
|
+ pid_output = constrain(pid_setpoint[e], 0, PID_MAX);
|
307
|
359
|
#endif //PID_OPENLOOP
|
308
|
360
|
#ifdef PID_DEBUG
|
309
|
361
|
SERIAL_ECHOLN(" PIDDEBUG "<<e<<": Input "<<pid_input<<" Output "<<pid_output" pTerm "<<pTerm[e]<<" iTerm "<<iTerm[e]<<" dTerm "<<dTerm[e]);
|
|
@@ -338,42 +390,58 @@ void manage_heater()
|
338
|
390
|
}
|
339
|
391
|
#endif
|
340
|
392
|
|
341
|
|
-#ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
|
342
|
|
- if (bed_needs_heating){
|
343
|
|
- if (bed_is_on==0)
|
344
|
|
- WRITE(HEATER_BED_PIN,HIGH);
|
345
|
|
- if (bed_is_on==1)
|
346
|
|
- WRITE(HEATER_BED_PIN,LOW);
|
347
|
|
- bed_is_on=(bed_is_on+1) % HEATER_BED_DUTY_CYCLE_DIVIDER;
|
348
|
|
- }
|
349
|
|
-#endif
|
350
|
393
|
|
|
394
|
+ #ifndef PIDTEMPBED
|
351
|
395
|
if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
|
352
|
396
|
return;
|
353
|
397
|
previous_millis_bed_heater = millis();
|
354
|
|
-
|
|
398
|
+ #endif
|
|
399
|
+
|
355
|
400
|
#if TEMP_BED_PIN > -1
|
356
|
401
|
|
357
|
|
- #ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
|
358
|
|
- bed_needs_heating=0;
|
359
|
|
- #endif
|
|
402
|
+ #ifdef PIDTEMPBED
|
|
403
|
+ pid_input = analog2tempBed(current_raw_bed);
|
|
404
|
+
|
|
405
|
+ #ifndef PID_OPENLOOP
|
|
406
|
+ pid_error_bed = pid_setpoint_bed - pid_input;
|
|
407
|
+ pTerm_bed = bedKp * pid_error_bed;
|
|
408
|
+ temp_iState_bed += pid_error_bed;
|
|
409
|
+ temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
|
|
410
|
+ iTerm_bed = bedKi * temp_iState_bed;
|
|
411
|
+
|
|
412
|
+ //K1 defined in Configuration.h in the PID settings
|
|
413
|
+ #define K2 (1.0-K1)
|
|
414
|
+ dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
|
|
415
|
+ temp_dState_bed = pid_input;
|
|
416
|
+
|
|
417
|
+ pid_output = constrain(pTerm_bed + iTerm_bed - dTerm_bed, 0, PID_MAX);
|
|
418
|
+
|
|
419
|
+ #else
|
|
420
|
+ pid_output = constrain(pid_setpoint_bed, 0, PID_MAX);
|
|
421
|
+ #endif //PID_OPENLOOP
|
360
|
422
|
|
361
|
|
- #ifndef BED_LIMIT_SWITCHING
|
|
423
|
+ if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp))
|
|
424
|
+ {
|
|
425
|
+ soft_pwm_bed = (int)pid_output >> 1;
|
|
426
|
+ }
|
|
427
|
+ else {
|
|
428
|
+ soft_pwm_bed = 0;
|
|
429
|
+ }
|
|
430
|
+
|
|
431
|
+ #elif not defined BED_LIMIT_SWITCHING
|
362
|
432
|
// Check if temperature is within the correct range
|
363
|
433
|
if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
|
364
|
434
|
if(current_raw_bed >= target_raw_bed)
|
365
|
435
|
{
|
366
|
|
- WRITE(HEATER_BED_PIN,LOW);
|
|
436
|
+ soft_pwm_bed = 0;
|
367
|
437
|
}
|
368
|
438
|
else
|
369
|
439
|
{
|
370
|
|
- #ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
|
371
|
|
- bed_needs_heating=1;
|
372
|
|
- #endif
|
373
|
|
- WRITE(HEATER_BED_PIN,HIGH);
|
|
440
|
+ soft_pwm_bed = 100;
|
374
|
441
|
}
|
375
|
442
|
}
|
376
|
443
|
else {
|
|
444
|
+ soft_pwm_bed = 0;
|
377
|
445
|
WRITE(HEATER_BED_PIN,LOW);
|
378
|
446
|
}
|
379
|
447
|
#else //#ifdef BED_LIMIT_SWITCHING
|
|
@@ -381,18 +449,16 @@ void manage_heater()
|
381
|
449
|
if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
|
382
|
450
|
if(current_raw_bed > target_bed_high_temp)
|
383
|
451
|
{
|
384
|
|
- WRITE(HEATER_BED_PIN,LOW);
|
|
452
|
+ soft_pwm_bed = 0;
|
385
|
453
|
}
|
386
|
454
|
else
|
387
|
455
|
if(current_raw_bed <= target_bed_low_temp)
|
388
|
456
|
{
|
389
|
|
- #ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
|
390
|
|
- bed_needs_heating=1;
|
391
|
|
- #endif
|
392
|
|
- WRITE(HEATER_BED_PIN,HIGH);
|
|
457
|
+ soft_pwm_bed = 100;
|
393
|
458
|
}
|
394
|
459
|
}
|
395
|
460
|
else {
|
|
461
|
+ soft_pwm_bed = 0;
|
396
|
462
|
WRITE(HEATER_BED_PIN,LOW);
|
397
|
463
|
}
|
398
|
464
|
#endif
|
|
@@ -567,6 +633,8 @@ void tp_init()
|
567
|
633
|
#ifdef PIDTEMP
|
568
|
634
|
temp_iState_min[e] = 0.0;
|
569
|
635
|
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
|
|
636
|
+ temp_iState_min_bed = 0.0;
|
|
637
|
+ temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
|
570
|
638
|
#endif //PIDTEMP
|
571
|
639
|
}
|
572
|
640
|
|
|
@@ -728,6 +796,7 @@ void disable_heater()
|
728
|
796
|
|
729
|
797
|
#if TEMP_BED_PIN > -1
|
730
|
798
|
target_raw_bed=0;
|
|
799
|
+ soft_pwm_bed=0;
|
731
|
800
|
#if HEATER_BED_PIN > -1
|
732
|
801
|
WRITE(HEATER_BED_PIN,LOW);
|
733
|
802
|
#endif
|
|
@@ -832,6 +901,7 @@ ISR(TIMER0_COMPB_vect)
|
832
|
901
|
static unsigned char soft_pwm_0;
|
833
|
902
|
static unsigned char soft_pwm_1;
|
834
|
903
|
static unsigned char soft_pwm_2;
|
|
904
|
+ static unsigned char soft_pwm_b;
|
835
|
905
|
|
836
|
906
|
if(pwm_count == 0){
|
837
|
907
|
soft_pwm_0 = soft_pwm[0];
|
|
@@ -844,6 +914,10 @@ ISR(TIMER0_COMPB_vect)
|
844
|
914
|
soft_pwm_2 = soft_pwm[2];
|
845
|
915
|
if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1);
|
846
|
916
|
#endif
|
|
917
|
+ #if HEATER_BED_PIN > -1
|
|
918
|
+ soft_pwm_b = soft_pwm_bed;
|
|
919
|
+ if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1);
|
|
920
|
+ #endif
|
847
|
921
|
}
|
848
|
922
|
if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0);
|
849
|
923
|
#if EXTRUDERS > 1
|
|
@@ -852,6 +926,9 @@ ISR(TIMER0_COMPB_vect)
|
852
|
926
|
#if EXTRUDERS > 2
|
853
|
927
|
if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0);
|
854
|
928
|
#endif
|
|
929
|
+ #if HEATER_BED_PIN > -1
|
|
930
|
+ if(soft_pwm_b <= pwm_count) WRITE(HEATER_BED_PIN,0);
|
|
931
|
+ #endif
|
855
|
932
|
|
856
|
933
|
pwm_count++;
|
857
|
934
|
pwm_count &= 0x7f;
|