Sat, 07 Nov 2015 13:23:07 +0100
Initial code from reprappro Marlin repository
0 | 1 | /* |
2 | temperature.c - temperature control | |
3 | Part of Marlin | |
4 | ||
5 | Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm | |
6 | ||
7 | This program 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 | This program 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 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
20 | ||
21 | /* | |
22 | This firmware is a mashup between Sprinter and grbl. | |
23 | (https://github.com/kliment/Sprinter) | |
24 | (https://github.com/simen/grbl/tree) | |
25 | ||
26 | It has preliminary support for Matthew Roberts advance algorithm | |
27 | http://reprap.org/pipermail/reprap-dev/2011-May/003323.html | |
28 | ||
29 | */ | |
30 | ||
31 | ||
32 | #include "Marlin.h" | |
33 | #include "ultralcd.h" | |
34 | #include "temperature.h" | |
35 | ||
36 | //=========================================================================== | |
37 | //=============================public variables============================ | |
38 | //=========================================================================== | |
39 | int target_raw[EXTRUDERS_T] = { 0 }; | |
40 | int target_raw_bed = 0; | |
41 | ||
42 | int current_raw[EXTRUDERS_T] = { 0 }; | |
43 | int current_raw_bed = 0; | |
44 | ||
45 | int b_beta = BED_BETA; | |
46 | int b_resistor = BED_RS; | |
47 | long b_thermistor = BED_NTC; | |
48 | float b_inf = BED_R_INF; | |
49 | ||
50 | int n_beta = E_BETA; | |
51 | int n_resistor = E_RS; | |
52 | long n_thermistor = E_NTC; | |
53 | float n_inf = E_R_INF; | |
54 | ||
55 | #ifdef PIDTEMP | |
56 | // used external | |
57 | float pid_setpoint[EXTRUDERS_T] = { 0.0 }; | |
58 | ||
59 | float Kp=DEFAULT_Kp; | |
60 | float Ki=DEFAULT_Ki; | |
61 | int Ki_Max=PID_INTEGRAL_DRIVE_MAX; | |
62 | float Kd=DEFAULT_Kd; | |
63 | ||
64 | #endif //PIDTEMP | |
65 | ||
66 | ||
67 | //=========================================================================== | |
68 | //=============================private variables============================ | |
69 | //=========================================================================== | |
70 | static volatile bool temp_meas_ready = false; | |
71 | ||
72 | static unsigned long previous_millis_bed_heater; | |
73 | //static unsigned long previous_millis_heater; | |
74 | ||
75 | #ifdef PIDTEMP | |
76 | //static cannot be external: | |
77 | static float temp_iState[EXTRUDERS_T] = { 0 }; | |
78 | static float temp_dState[EXTRUDERS_T] = { 0 }; | |
79 | static float pTerm[EXTRUDERS_T]; | |
80 | static float iTerm[EXTRUDERS_T]; | |
81 | static float dTerm[EXTRUDERS_T]; | |
82 | //int output; | |
83 | static float pid_error[EXTRUDERS_T]; | |
84 | static float temp_iState_min[EXTRUDERS_T]; | |
85 | static float temp_iState_max[EXTRUDERS_T]; | |
86 | // static float pid_input[EXTRUDERS_T]; | |
87 | // static float pid_output[EXTRUDERS_T]; | |
88 | static bool pid_reset[EXTRUDERS_T]; | |
89 | #endif //PIDTEMP | |
90 | static unsigned char soft_pwm[EXTRUDERS_T]; | |
91 | ||
92 | ||
93 | // Init min and max temp with extreme values to prevent false errors during startup | |
94 | // static int minttemp[EXTRUDERS_T] = { 0 }; | |
95 | // static int maxttemp[EXTRUDERS_T] = { 16383 }; // the first value used for all | |
96 | static int bed_minttemp = 0; | |
97 | static int bed_maxttemp = 16383; | |
98 | ||
99 | ||
100 | //=========================================================================== | |
101 | //============================= functions ============================ | |
102 | //=========================================================================== | |
103 | ||
104 | void PID_autotune(float temp) | |
105 | { | |
106 | float input; | |
107 | int cycles=0; | |
108 | bool heating = true; | |
109 | ||
110 | unsigned long temp_millis = millis(); | |
111 | unsigned long t1=temp_millis; | |
112 | unsigned long t2=temp_millis; | |
113 | long t_high; | |
114 | long t_low; | |
115 | ||
116 | long bias=PID_MAX/2; | |
117 | long d = PID_MAX/2; | |
118 | float Ku, Tu; | |
119 | float Kp, Ki, Kd; | |
120 | float max, min; | |
121 | ||
122 | SERIAL_ECHOLN("PID Autotune start"); | |
123 | ||
124 | disable_heater(); // switch off all heaters. | |
125 | ||
126 | soft_pwm[0] = PID_MAX/2; | |
127 | ||
128 | for(;;) { | |
129 | ||
130 | if(temp_meas_ready == true) { // temp sample ready | |
131 | CRITICAL_SECTION_START; | |
132 | temp_meas_ready = false; | |
133 | CRITICAL_SECTION_END; | |
134 | input = analog2temp(current_raw[0], 0); | |
135 | ||
136 | max=max(max,input); | |
137 | min=min(min,input); | |
138 | if(heating == true && input > temp) { | |
139 | if(millis() - t2 > 5000) { | |
140 | heating=false; | |
141 | soft_pwm[0] = (bias - d) >> 1; | |
142 | t1=millis(); | |
143 | t_high=t1 - t2; | |
144 | max=temp; | |
145 | } | |
146 | } | |
147 | if(heating == false && input < temp) { | |
148 | if(millis() - t1 > 5000) { | |
149 | heating=true; | |
150 | t2=millis(); | |
151 | t_low=t2 - t1; | |
152 | if(cycles > 0) { | |
153 | bias += (d*(t_high - t_low))/(t_low + t_high); | |
154 | bias = constrain(bias, 20 ,PID_MAX-FULL_PID_BAND); | |
155 | if(bias > PID_MAX/2) d = PID_MAX - 1 - bias; | |
156 | else d = bias; | |
157 | ||
158 | SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias); | |
159 | SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d); | |
160 | SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min); | |
161 | SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max); | |
162 | if(cycles > 2) { | |
163 | Ku = (4.0*d)/(3.14159*(max-min)/2.0); | |
164 | Tu = ((float)(t_low + t_high)/1000.0); | |
165 | SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku); | |
166 | SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu); | |
167 | Kp = 0.6*Ku; | |
168 | Ki = 2*Kp/Tu; | |
169 | Kd = Kp*Tu/8; | |
170 | SERIAL_PROTOCOLLNPGM(" Clasic PID ") | |
171 | SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp); | |
172 | SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki); | |
173 | SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd); | |
174 | } | |
175 | } | |
176 | soft_pwm[0] = (bias + d) >> 1; | |
177 | cycles++; | |
178 | min=temp; | |
179 | } | |
180 | } | |
181 | } | |
182 | if(input > (temp + 20)) { | |
183 | SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature to high"); | |
184 | return; | |
185 | } | |
186 | if(millis() - temp_millis > 2000) { | |
187 | temp_millis = millis(); | |
188 | SERIAL_PROTOCOLPGM("ok T:"); | |
189 | SERIAL_PROTOCOL(degHotend(0)); | |
190 | SERIAL_PROTOCOLPGM(" @:"); | |
191 | SERIAL_PROTOCOLLN(getHeaterPower(0)); | |
192 | } | |
193 | if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) { | |
194 | SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout"); | |
195 | return; | |
196 | } | |
197 | if(cycles > 5) { | |
198 | SERIAL_PROTOCOLLNPGM("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h"); | |
199 | return; | |
200 | } | |
201 | LCD_STATUS; | |
202 | } | |
203 | } | |
204 | ||
205 | void updatePID() | |
206 | { | |
207 | #ifdef PIDTEMP | |
208 | for(int e = 0; e < EXTRUDERS_T; e++) { | |
209 | temp_iState_max[e] = Ki_Max / Ki; | |
210 | } | |
211 | #endif | |
212 | } | |
213 | ||
214 | int getHeaterPower(int heater) { | |
215 | return soft_pwm[heater]; | |
216 | } | |
217 | ||
218 | void manage_heater() | |
219 | { | |
220 | float pid_input; | |
221 | float pid_output; | |
222 | ||
223 | if(temp_meas_ready != true) //better readability | |
224 | return; | |
225 | ||
226 | CRITICAL_SECTION_START; | |
227 | temp_meas_ready = false; | |
228 | CRITICAL_SECTION_END; | |
229 | ||
230 | for(int e = 0; e < EXTRUDERS_T; e++) | |
231 | { | |
232 | ||
233 | #ifdef PIDTEMP | |
234 | pid_input = analog2temp(current_raw[e], e); | |
235 | ||
236 | ||
237 | pid_error[e] = pid_setpoint[e] - pid_input; | |
238 | if(pid_error[e] > FULL_PID_BAND) { | |
239 | pid_output = PID_MAX; | |
240 | pid_reset[e] = true; | |
241 | } | |
242 | else if(pid_error[e] < -FULL_PID_BAND) { | |
243 | pid_output = 0; | |
244 | pid_reset[e] = true; | |
245 | } | |
246 | else { | |
247 | if(pid_reset[e] == true) { | |
248 | temp_iState[e] = 0.0; | |
249 | pid_reset[e] = false; | |
250 | } | |
251 | pTerm[e] = Kp * pid_error[e]; | |
252 | temp_iState[e] += pid_error[e]; | |
253 | temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]); | |
254 | iTerm[e] = Ki * temp_iState[e]; | |
255 | //K1 defined in Configuration.h in the PID settings | |
256 | #define K2 (1.0-K1) | |
257 | dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]); | |
258 | temp_dState[e] = pid_input; | |
259 | pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX); | |
260 | } | |
261 | ||
262 | #ifdef PID_DEBUG | |
263 | SERIAL_ECHOLN(" PIDDEBUG "<<e<<": Input "<<pid_input<<" Output "<<pid_output" pTerm "<<pTerm[e]<<" iTerm "<<iTerm[e]<<" dTerm "<<dTerm[e]); | |
264 | #endif //PID_DEBUG | |
265 | #else /* PID off */ | |
266 | pid_output = 0; | |
267 | if(current_raw[e] < target_raw[e]) { | |
268 | pid_output = PID_MAX; | |
269 | } | |
270 | #endif | |
271 | ||
272 | // Check if temperature is within the correct range | |
273 | if((current_raw[e] > minttemp[e]) && (current_raw[e] < maxttemp[e])) | |
274 | { | |
275 | soft_pwm[e] = (int)pid_output >> 1; | |
276 | } | |
277 | else { | |
278 | soft_pwm[e] = 0; | |
279 | } | |
280 | } // End extruder for loop | |
281 | ||
282 | ||
283 | if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL) | |
284 | return; | |
285 | previous_millis_bed_heater = millis(); | |
286 | ||
287 | #if TEMP_BED_PIN > -1 | |
288 | ||
289 | // Check if temperature is within the correct range | |
290 | if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) { | |
291 | if(current_raw_bed >= target_raw_bed) | |
292 | { | |
293 | WRITE(HEATER_BED_PIN,LOW); | |
294 | } | |
295 | else | |
296 | { | |
297 | WRITE(HEATER_BED_PIN,HIGH); | |
298 | } | |
299 | } | |
300 | else { | |
301 | WRITE(HEATER_BED_PIN,LOW); | |
302 | } | |
303 | #endif | |
304 | } | |
305 | ||
306 | // Use algebra to work out temperatures, not tables | |
307 | // NB - this assumes all extruders use the same thermistor type. | |
308 | int temp2analogi(int celsius, const float& beta, const float& rs, const float& r_inf) | |
309 | { | |
310 | float r = r_inf*exp(beta/(celsius - ABS_ZERO)); | |
311 | return AD_RANGE - (int)(0.5 + AD_RANGE*r/(r + rs)); | |
312 | } | |
313 | ||
314 | float analog2tempi(int raw, const float& beta, const float& rs, const float& r_inf) | |
315 | { | |
316 | float rawf = (float)(AD_RANGE - raw); | |
317 | return ABS_ZERO + beta/log( (rawf*rs/(AD_RANGE - rawf))/r_inf ); | |
318 | } | |
319 | ||
320 | ||
321 | #ifdef REPRAPPRO_MULTIMATERIALS | |
322 | ||
323 | ||
324 | float analog2temp_remote(uint8_t e) | |
325 | { | |
326 | return slaveDegHotend(e); | |
327 | } | |
328 | ||
329 | int temp2analog_remote(int celsius, uint8_t e) | |
330 | { | |
331 | // What do we do about this, then? | |
332 | return temp2analogi(celsius, n_beta, n_resistor, n_inf); | |
333 | } | |
334 | #endif | |
335 | ||
336 | ||
337 | int temp2analog(int celsius, uint8_t e) | |
338 | { | |
339 | #ifdef REPRAPPRO_MULTIMATERIALS | |
340 | if(e > 0) return temp2analog_remote(celsius, e); | |
341 | #endif | |
342 | return temp2analogi(celsius, n_beta, n_resistor, n_inf); | |
343 | } | |
344 | float analog2temp(int raw, uint8_t e) | |
345 | { | |
346 | #ifdef REPRAPPRO_MULTIMATERIALS | |
347 | if(e > 0) return analog2temp_remote(e); | |
348 | #endif | |
349 | return analog2tempi(raw, n_beta, n_resistor, n_inf); | |
350 | } | |
351 | ||
352 | int temp2analogBed(int celsius) | |
353 | { | |
354 | return temp2analogi(celsius, b_beta, b_resistor, b_inf); | |
355 | } | |
356 | float analog2tempBed(int raw) | |
357 | { | |
358 | return analog2tempi(raw, b_beta, b_resistor, b_inf); | |
359 | } | |
360 | ||
361 | ||
362 | ||
363 | void tp_init() | |
364 | { | |
365 | // Finish init of mult extruder arrays | |
366 | for(int e = 0; e < EXTRUDERS_T; e++) { | |
367 | // populate with the first value | |
368 | maxttemp[e] = maxttemp[0]; | |
369 | #ifdef PIDTEMP | |
370 | temp_iState_min[e] = 0.0; | |
371 | temp_iState_max[e] = Ki_Max / Ki; | |
372 | #endif //PIDTEMP | |
373 | } | |
374 | ||
375 | #if (HEATER_0_PIN > -1) | |
376 | SET_OUTPUT(HEATER_0_PIN); | |
377 | #endif | |
378 | #if (HEATER_1_PIN > -1) | |
379 | SET_OUTPUT(HEATER_1_PIN); | |
380 | #endif | |
381 | #if (HEATER_2_PIN > -1) | |
382 | SET_OUTPUT(HEATER_2_PIN); | |
383 | #endif | |
384 | #if (HEATER_BED_PIN > -1) | |
385 | SET_OUTPUT(HEATER_BED_PIN); | |
386 | #endif | |
387 | #if (FAN_PIN > -1) | |
388 | SET_OUTPUT(FAN_PIN); | |
389 | #endif | |
390 | ||
391 | ||
392 | // Set analog inputs | |
393 | ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07; | |
394 | DIDR0 = 0; | |
395 | #ifdef DIDR2 | |
396 | DIDR2 = 0; | |
397 | #endif | |
398 | #if (TEMP_0_PIN > -1) | |
399 | #if TEMP_0_PIN < 8 | |
400 | DIDR0 |= 1 << TEMP_0_PIN; | |
401 | #else | |
402 | DIDR2 |= 1<<(TEMP_0_PIN - 8); | |
403 | #endif | |
404 | #endif | |
405 | #if (TEMP_1_PIN > -1) | |
406 | #if TEMP_1_PIN < 8 | |
407 | DIDR0 |= 1<<TEMP_1_PIN; | |
408 | #else | |
409 | DIDR2 |= 1<<(TEMP_1_PIN - 8); | |
410 | #endif | |
411 | #endif | |
412 | #if (TEMP_2_PIN > -1) | |
413 | #if TEMP_2_PIN < 8 | |
414 | DIDR0 |= 1 << TEMP_2_PIN; | |
415 | #else | |
416 | DIDR2 = 1<<(TEMP_2_PIN - 8); | |
417 | #endif | |
418 | #endif | |
419 | #if (TEMP_BED_PIN > -1) | |
420 | #if TEMP_BED_PIN < 8 | |
421 | DIDR0 |= 1<<TEMP_BED_PIN; | |
422 | #else | |
423 | DIDR2 |= 1<<(TEMP_BED_PIN - 8); | |
424 | #endif | |
425 | #endif | |
426 | ||
427 | // Use timer0 for temperature measurement | |
428 | // Interleave temperature interrupt with millies interrupt | |
429 | OCR0B = 128; | |
430 | TIMSK0 |= (1<<OCIE0B); | |
431 | ||
432 | // Wait for temperature measurement to settle | |
433 | delay(250); | |
434 | ||
435 | #ifdef HEATER_0_MINTEMP | |
436 | minttemp[0] = temp2analog(HEATER_0_MINTEMP, 0); | |
437 | #endif //MINTEMP | |
438 | #ifdef HEATER_0_MAXTEMP | |
439 | maxttemp[0] = temp2analog(HEATER_0_MAXTEMP, 0); | |
440 | #endif //MAXTEMP | |
441 | ||
442 | #if (EXTRUDERS_T > 1) && defined(HEATER_1_MINTEMP) | |
443 | minttemp[1] = temp2analog(HEATER_1_MINTEMP, 1); | |
444 | #endif // MINTEMP 1 | |
445 | #if (EXTRUDERS_T > 1) && defined(HEATER_1_MAXTEMP) | |
446 | maxttemp[1] = temp2analog(HEATER_1_MAXTEMP, 1); | |
447 | #endif //MAXTEMP 1 | |
448 | ||
449 | #if (EXTRUDERS_T > 2) && defined(HEATER_2_MINTEMP) | |
450 | minttemp[2] = temp2analog(HEATER_2_MINTEMP, 2); | |
451 | #endif //MINTEMP 2 | |
452 | #if (EXTRUDERS_T > 2) && defined(HEATER_2_MAXTEMP) | |
453 | maxttemp[2] = temp2analog(HEATER_2_MAXTEMP, 2); | |
454 | #endif //MAXTEMP 2 | |
455 | ||
456 | #ifdef BED_MINTEMP | |
457 | bed_minttemp = temp2analogBed(BED_MINTEMP); | |
458 | #endif //BED_MINTEMP | |
459 | #ifdef BED_MAXTEMP | |
460 | bed_maxttemp = temp2analogBed(BED_MAXTEMP); | |
461 | #endif //BED_MAXTEMP | |
462 | } | |
463 | ||
464 | ||
465 | ||
466 | void disable_heater() | |
467 | { | |
468 | for(int i=0;i<EXTRUDERS_T;i++) | |
469 | setTargetHotend(0,i); | |
470 | setTargetBed(0); | |
471 | #if TEMP_0_PIN > -1 | |
472 | target_raw[0]=0; | |
473 | soft_pwm[0]=0; | |
474 | #if HEATER_0_PIN > -1 | |
475 | WRITE(HEATER_0_PIN,LOW); | |
476 | #endif | |
477 | #endif | |
478 | ||
479 | #if TEMP_1_PIN > -1 | |
480 | target_raw[1]=0; | |
481 | soft_pwm[1]=0; | |
482 | #if HEATER_1_PIN > -1 | |
483 | WRITE(HEATER_1_PIN,LOW); | |
484 | #endif | |
485 | #endif | |
486 | ||
487 | #if TEMP_2_PIN > -1 | |
488 | target_raw[2]=0; | |
489 | soft_pwm[2]=0; | |
490 | #if HEATER_2_PIN > -1 | |
491 | WRITE(HEATER_2_PIN,LOW); | |
492 | #endif | |
493 | #endif | |
494 | ||
495 | #if TEMP_BED_PIN > -1 | |
496 | target_raw_bed=0; | |
497 | #if HEATER_BED_PIN > -1 | |
498 | WRITE(HEATER_BED_PIN,LOW); | |
499 | #endif | |
500 | #endif | |
501 | } | |
502 | ||
503 | void max_temp_error(uint8_t e) { | |
504 | disable_heater(); | |
505 | if(IsStopped() == false) { | |
506 | SERIAL_ERROR_START; | |
507 | SERIAL_ERRORLN((int)e); | |
508 | SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !"); | |
509 | } | |
510 | } | |
511 | ||
512 | void min_temp_error(uint8_t e) { | |
513 | disable_heater(); | |
514 | if(IsStopped() == false) { | |
515 | SERIAL_ERROR_START; | |
516 | SERIAL_ERRORLN((int)e); | |
517 | SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !"); | |
518 | } | |
519 | } | |
520 | ||
521 | void bed_max_temp_error(void) { | |
522 | #if HEATER_BED_PIN > -1 | |
523 | WRITE(HEATER_BED_PIN, 0); | |
524 | #endif | |
525 | if(IsStopped() == false) { | |
526 | SERIAL_ERROR_START; | |
527 | SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!"); | |
528 | } | |
529 | } | |
530 | ||
531 | ||
532 | // Timer 0 is shared with millies | |
533 | ISR(TIMER0_COMPB_vect) | |
534 | { | |
535 | //these variables are only accesible from the ISR, but static, so they don't loose their value | |
536 | static unsigned char temp_count = 0; | |
537 | static unsigned long raw_temp_0_value = 0; | |
538 | static unsigned long raw_temp_1_value = 0; | |
539 | static unsigned long raw_temp_2_value = 0; | |
540 | static unsigned long raw_temp_bed_value = 0; | |
541 | static unsigned char temp_state = 0; | |
542 | static unsigned char pwm_count = 1; | |
543 | static unsigned char soft_pwm_0; | |
544 | static unsigned char soft_pwm_1; | |
545 | static unsigned char soft_pwm_2; | |
546 | ||
547 | if(pwm_count == 0){ | |
548 | soft_pwm_0 = soft_pwm[0]; | |
549 | if(soft_pwm_0 > 0) WRITE(HEATER_0_PIN,1); | |
550 | #ifdef REPRAPPRO_MULTIMATERIALS | |
551 | // Nothing to do here - remote handles it | |
552 | #else | |
553 | #if EXTRUDERS_T > 1 | |
554 | soft_pwm_1 = soft_pwm[1]; | |
555 | if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); | |
556 | #endif | |
557 | #if EXTRUDERS_T > 2 | |
558 | soft_pwm_2 = soft_pwm[2]; | |
559 | if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); | |
560 | #endif | |
561 | #endif | |
562 | } | |
563 | if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0); | |
564 | #ifdef REPRAPPRO_MULTIMATERIALS | |
565 | // Nothing to do here - remote handles it | |
566 | #else | |
567 | #if EXTRUDERS_T > 1 | |
568 | if(soft_pwm_1 <= pwm_count) WRITE(HEATER_1_PIN,0); | |
569 | #endif | |
570 | #if EXTRUDERS_T > 2 | |
571 | if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0); | |
572 | #endif | |
573 | #endif | |
574 | pwm_count++; | |
575 | pwm_count &= 0x7f; | |
576 | ||
577 | switch(temp_state) { | |
578 | case 0: // Prepare TEMP_0 | |
579 | #if (TEMP_0_PIN > -1) | |
580 | #if TEMP_0_PIN > 7 | |
581 | ADCSRB = 1<<MUX5; | |
582 | #else | |
583 | ADCSRB = 0; | |
584 | #endif | |
585 | ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07)); | |
586 | ADCSRA |= 1<<ADSC; // Start conversion | |
587 | #endif | |
588 | #ifdef ULTIPANEL | |
589 | buttons_check(); | |
590 | #endif | |
591 | temp_state = 1; | |
592 | break; | |
593 | case 1: // Measure TEMP_0 | |
594 | #if (TEMP_0_PIN > -1) | |
595 | raw_temp_0_value += ADC; | |
596 | #endif | |
597 | ||
598 | temp_state = 2; | |
599 | break; | |
600 | case 2: // Prepare TEMP_BED | |
601 | #if (TEMP_BED_PIN > -1) | |
602 | #if TEMP_BED_PIN > 7 | |
603 | ADCSRB = 1<<MUX5; | |
604 | #endif | |
605 | ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07)); | |
606 | ADCSRA |= 1<<ADSC; // Start conversion | |
607 | #endif | |
608 | #ifdef ULTIPANEL | |
609 | buttons_check(); | |
610 | #endif | |
611 | temp_state = 3; | |
612 | break; | |
613 | case 3: // Measure TEMP_BED | |
614 | #if (TEMP_BED_PIN > -1) | |
615 | raw_temp_bed_value += ADC; | |
616 | #endif | |
617 | temp_state = 4; | |
618 | break; | |
619 | case 4: // Prepare TEMP_1 | |
620 | #if (TEMP_1_PIN > -1) | |
621 | #if TEMP_1_PIN > 7 | |
622 | ADCSRB = 1<<MUX5; | |
623 | #else | |
624 | ADCSRB = 0; | |
625 | #endif | |
626 | ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07)); | |
627 | ADCSRA |= 1<<ADSC; // Start conversion | |
628 | #endif | |
629 | #ifdef ULTIPANEL | |
630 | buttons_check(); | |
631 | #endif | |
632 | temp_state = 5; | |
633 | break; | |
634 | case 5: // Measure TEMP_1 | |
635 | #if (TEMP_1_PIN > -1) | |
636 | raw_temp_1_value += ADC; | |
637 | #endif | |
638 | temp_state = 6; | |
639 | break; | |
640 | case 6: // Prepare TEMP_2 | |
641 | #if (TEMP_2_PIN > -1) | |
642 | #if TEMP_2_PIN > 7 | |
643 | ADCSRB = 1<<MUX5; | |
644 | #else | |
645 | ADCSRB = 0; | |
646 | #endif | |
647 | ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07)); | |
648 | ADCSRA |= 1<<ADSC; // Start conversion | |
649 | #endif | |
650 | #ifdef ULTIPANEL | |
651 | buttons_check(); | |
652 | #endif | |
653 | temp_state = 7; | |
654 | break; | |
655 | case 7: // Measure TEMP_2 | |
656 | #if (TEMP_2_PIN > -1) | |
657 | raw_temp_2_value += ADC; | |
658 | #endif | |
659 | temp_state = 0; | |
660 | temp_count++; | |
661 | break; | |
662 | // default: | |
663 | // SERIAL_ERROR_START; | |
664 | // SERIAL_ERRORLNPGM("Temp measurement error!"); | |
665 | // break; | |
666 | } | |
667 | ||
668 | if(temp_count >= 16) // 8 ms * 16 = 128ms. | |
669 | { | |
670 | #if defined(HEATER_0_USES_AD595) || defined(HEATER_0_USES_MAX6675) | |
671 | current_raw[0] = raw_temp_0_value; | |
672 | #else | |
673 | current_raw[0] = 16383 - raw_temp_0_value; | |
674 | #endif | |
675 | ||
676 | #if EXTRUDERS_T > 1 | |
677 | #ifdef HEATER_1_USES_AD595 | |
678 | current_raw[1] = raw_temp_1_value; | |
679 | #else | |
680 | current_raw[1] = 16383 - raw_temp_1_value; | |
681 | #endif | |
682 | #endif | |
683 | ||
684 | #if EXTRUDERS_T > 2 | |
685 | #ifdef HEATER_2_USES_AD595 | |
686 | current_raw[2] = raw_temp_2_value; | |
687 | #else | |
688 | current_raw[2] = 16383 - raw_temp_2_value; | |
689 | #endif | |
690 | #endif | |
691 | ||
692 | ||
693 | current_raw_bed = 16383 - raw_temp_bed_value; | |
694 | ||
695 | ||
696 | temp_meas_ready = true; | |
697 | temp_count = 0; | |
698 | raw_temp_0_value = 0; | |
699 | raw_temp_1_value = 0; | |
700 | raw_temp_2_value = 0; | |
701 | raw_temp_bed_value = 0; | |
702 | ||
703 | for(unsigned char e = 0; e < EXTRUDERS_T; e++) { | |
704 | if(current_raw[e] >= maxttemp[e]) { | |
705 | target_raw[e] = 0; | |
706 | max_temp_error(e); | |
707 | #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE | |
708 | { | |
709 | Stop(); | |
710 | } | |
711 | #endif | |
712 | } | |
713 | if(current_raw[e] <= minttemp[e]) { | |
714 | target_raw[e] = 0; | |
715 | min_temp_error(e); | |
716 | #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE | |
717 | { | |
718 | Stop(); | |
719 | } | |
720 | #endif | |
721 | } | |
722 | } | |
723 | ||
724 | #if defined(BED_MAXTEMP) && (HEATER_BED_PIN > -1) | |
725 | if(current_raw_bed >= bed_maxttemp) { | |
726 | target_raw_bed = 0; | |
727 | bed_max_temp_error(); | |
728 | Stop(); | |
729 | } | |
730 | #endif | |
731 | } | |
732 | } | |
733 |