2 temperature.c - temperature control
5 Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
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.
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.
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/>.
22 This firmware is a mashup between Sprinter and grbl.
23 (https://github.com/kliment/Sprinter)
24 (https://github.com/simen/grbl/tree)
26 It has preliminary support for Matthew Roberts advance algorithm
27 http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
34 #include "temperature.h"
37 //===========================================================================
38 //=============================public variables============================
39 //===========================================================================
40 int target_raw[EXTRUDERS] = { 0 };
41 int target_raw_bed = 0;
42 #ifdef BED_LIMIT_SWITCHING
43 int target_bed_low_temp =0;
44 int target_bed_high_temp =0;
46 int current_raw[EXTRUDERS] = { 0 };
47 int current_raw_bed = 0;
51 float pid_setpoint[EXTRUDERS] = { 0.0 };
54 float Ki=(DEFAULT_Ki*PID_dT);
55 float Kd=(DEFAULT_Kd/PID_dT);
56 #ifdef PID_ADD_EXTRUSION_RATE
62 //===========================================================================
63 //=============================private variables============================
64 //===========================================================================
65 static volatile bool temp_meas_ready = false;
67 static unsigned long previous_millis_bed_heater;
68 //static unsigned long previous_millis_heater;
71 //static cannot be external:
72 static float temp_iState[EXTRUDERS] = { 0 };
73 static float temp_dState[EXTRUDERS] = { 0 };
74 static float pTerm[EXTRUDERS];
75 static float iTerm[EXTRUDERS];
76 static float dTerm[EXTRUDERS];
78 static float pid_error[EXTRUDERS];
79 static float temp_iState_min[EXTRUDERS];
80 static float temp_iState_max[EXTRUDERS];
81 // static float pid_input[EXTRUDERS];
82 // static float pid_output[EXTRUDERS];
83 static bool pid_reset[EXTRUDERS];
85 static unsigned char soft_pwm[EXTRUDERS];
88 int watch_raw[EXTRUDERS] = { -1000 }; // the first value used for all
89 int watch_oldtemp[3] = {0,0,0};
90 unsigned long watchmillis = 0;
93 // Init min and max temp with extreme values to prevent false errors during startup
94 static int minttemp[EXTRUDERS] = { 0 };
95 static int maxttemp[EXTRUDERS] = { 16383 }; // the first value used for all
96 static int bed_minttemp = 0;
97 static int bed_maxttemp = 16383;
98 static void *heater_ttbl_map[EXTRUDERS] = { (void *)heater_0_temptable
100 , (void *)heater_1_temptable
103 , (void *)heater_2_temptable
106 #error Unsupported number of extruders
109 static int heater_ttbllen_map[EXTRUDERS] = { heater_0_temptable_len
111 , heater_1_temptable_len
114 , heater_2_temptable_len
117 #error Unsupported number of extruders
121 //===========================================================================
122 //============================= functions ============================
123 //===========================================================================
125 void PID_autotune(float temp)
131 unsigned long temp_millis = millis();
132 unsigned long t1=temp_millis;
133 unsigned long t2=temp_millis;
143 SERIAL_ECHOLN("PID Autotune start");
145 disable_heater(); // switch off all heaters.
147 soft_pwm[0] = 255>>1;
151 if(temp_meas_ready == true) { // temp sample ready
152 CRITICAL_SECTION_START;
153 temp_meas_ready = false;
154 CRITICAL_SECTION_END;
155 input = analog2temp(current_raw[0], 0);
159 if(heating == true && input > temp) {
160 if(millis() - t2 > 5000) {
162 soft_pwm[0] = (bias - d) >> 1;
168 if(heating == false && input < temp) {
169 if(millis() - t1 > 5000) {
174 bias += (d*(t_high - t_low))/(t_low + t_high);
175 bias = constrain(bias, 20 ,235);
176 if(bias > 127) d = 254 - bias;
179 SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias);
180 SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d);
181 SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min);
182 SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max);
184 Ku = (4.0*d)/(3.14159*(max-min)/2.0);
185 Tu = ((float)(t_low + t_high)/1000.0);
186 SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku);
187 SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu);
191 SERIAL_PROTOCOLLNPGM(" Clasic PID ")
192 SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
193 SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
194 SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
199 SERIAL_PROTOCOLLNPGM(" Some overshoot ")
200 SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
201 SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
202 SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
206 SERIAL_PROTOCOLLNPGM(" No overshoot ")
207 SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
208 SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
209 SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
213 soft_pwm[0] = (bias + d) >> 1;
219 if(input > (temp + 20)) {
220 SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature to high");
223 if(millis() - temp_millis > 2000) {
224 temp_millis = millis();
225 SERIAL_PROTOCOLPGM("ok T:");
226 SERIAL_PROTOCOL(degHotend(0));
227 SERIAL_PROTOCOLPGM(" @:");
228 SERIAL_PROTOCOLLN(getHeaterPower(0));
230 if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
231 SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
235 SERIAL_PROTOCOLLNPGM("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h");
245 for(int e = 0; e < EXTRUDERS; e++) {
246 temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
251 int getHeaterPower(int heater) {
252 return soft_pwm[heater];
264 if(temp_meas_ready != true) //better readability
267 CRITICAL_SECTION_START;
268 temp_meas_ready = false;
269 CRITICAL_SECTION_END;
271 for(int e = 0; e < EXTRUDERS; e++)
275 pid_input = analog2temp(current_raw[e], e);
278 pid_error[e] = pid_setpoint[e] - pid_input;
279 if(pid_error[e] > 10) {
280 pid_output = PID_MAX;
283 else if(pid_error[e] < -10) {
288 if(pid_reset[e] == true) {
289 temp_iState[e] = 0.0;
290 pid_reset[e] = false;
292 pTerm[e] = Kp * pid_error[e];
293 temp_iState[e] += pid_error[e];
294 temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
295 iTerm[e] = Ki * temp_iState[e];
296 //K1 defined in Configuration.h in the PID settings
298 dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
299 temp_dState[e] = pid_input;
300 pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX);
302 #endif //PID_OPENLOOP
304 SERIAL_ECHOLN(" PIDDEBUG "<<e<<": Input "<<pid_input<<" Output "<<pid_output" pTerm "<<pTerm[e]<<" iTerm "<<iTerm[e]<<" dTerm "<<dTerm[e]);
308 if(current_raw[e] < target_raw[e]) {
309 pid_output = PID_MAX;
313 // Check if temperature is within the correct range
314 if((current_raw[e] > minttemp[e]) && (current_raw[e] < maxttemp[e]))
316 soft_pwm[e] = (int)pid_output >> 1;
321 } // End extruder for loop
324 if(watchmillis && millis() - watchmillis > WATCHPERIOD){
325 if(watch_oldtemp[0] >= degHotend(active_extruder)){
326 setTargetHotend(0,active_extruder);
327 LCD_MESSAGEPGM("Heating failed");
329 SERIAL_ECHOLN("Heating failed");
336 if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
338 previous_millis_bed_heater = millis();
340 #if TEMP_BED_PIN > -1
342 #ifndef BED_LIMIT_SWITCHING
343 // Check if temperature is within the correct range
344 if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
345 if(current_raw_bed >= target_raw_bed)
347 WRITE(HEATER_BED_PIN,LOW);
351 WRITE(HEATER_BED_PIN,HIGH);
355 WRITE(HEATER_BED_PIN,LOW);
357 #else //#ifdef BED_LIMIT_SWITCHING
358 // Check if temperature is within the correct band
359 if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
360 if(current_raw_bed > target_bed_high_temp)
362 WRITE(HEATER_BED_PIN,LOW);
365 if(current_raw_bed <= target_bed_low_temp)
367 WRITE(HEATER_BED_PIN,HIGH);
371 WRITE(HEATER_BED_PIN,LOW);
377 #define PGM_RD_W(x) (short)pgm_read_word(&x)
378 // Takes hot end temperature value as input and returns corresponding raw value.
379 // For a thermistor, it uses the RepRap thermistor temp table.
380 // This is needed because PID in hydra firmware hovers around a given analog value, not a temp value.
381 // This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
382 int temp2analog(int celsius, uint8_t e) {
386 SERIAL_ERROR((int)e);
387 SERIAL_ERRORLNPGM(" - Invalid extruder number!");
390 #ifdef HEATER_0_USES_MAX6675
396 if(heater_ttbl_map[e] != 0)
400 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
402 for (i=1; i<heater_ttbllen_map[e]; i++)
404 if (PGM_RD_W((*tt)[i][1]) < celsius)
406 raw = PGM_RD_W((*tt)[i-1][0]) +
407 (celsius - PGM_RD_W((*tt)[i-1][1])) *
408 (PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0])) /
409 (PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1]));
414 // Overflow: Set to last value in the table
415 if (i == heater_ttbllen_map[e]) raw = PGM_RD_W((*tt)[i-1][0]);
417 return (1023 * OVERSAMPLENR) - raw;
419 return ((celsius-TEMP_SENSOR_AD595_OFFSET)/TEMP_SENSOR_AD595_GAIN) * (1024.0 / (5.0 * 100.0) ) * OVERSAMPLENR;
422 // Takes bed temperature value as input and returns corresponding raw value.
423 // For a thermistor, it uses the RepRap thermistor temp table.
424 // This is needed because PID in hydra firmware hovers around a given analog value, not a temp value.
425 // This function is derived from inversing the logic from a portion of getTemperature() in FiveD RepRap firmware.
426 int temp2analogBed(int celsius) {
427 #ifdef BED_USES_THERMISTOR
431 for (i=1; i<bedtemptable_len; i++)
433 if (PGM_RD_W(bedtemptable[i][1]) < celsius)
435 raw = PGM_RD_W(bedtemptable[i-1][0]) +
436 (celsius - PGM_RD_W(bedtemptable[i-1][1])) *
437 (PGM_RD_W(bedtemptable[i][0]) - PGM_RD_W(bedtemptable[i-1][0])) /
438 (PGM_RD_W(bedtemptable[i][1]) - PGM_RD_W(bedtemptable[i-1][1]));
444 // Overflow: Set to last value in the table
445 if (i == bedtemptable_len) raw = PGM_RD_W(bedtemptable[i-1][0]);
447 return (1023 * OVERSAMPLENR) - raw;
448 #elif defined BED_USES_AD595
449 return lround(((celsius-TEMP_SENSOR_AD595_OFFSET)/TEMP_SENSOR_AD595_GAIN) * (1024.0 * OVERSAMPLENR/ (5.0 * 100.0) ) );
451 #warning No heater-type defined for the bed.
456 // Derived from RepRap FiveD extruder::getTemperature()
457 // For hot end temperature measurement.
458 float analog2temp(int raw, uint8_t e) {
462 SERIAL_ERROR((int)e);
463 SERIAL_ERRORLNPGM(" - Invalid extruder number !");
466 #ifdef HEATER_0_USES_MAX6675
473 if(heater_ttbl_map[e] != 0)
477 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
479 raw = (1023 * OVERSAMPLENR) - raw;
480 for (i=1; i<heater_ttbllen_map[e]; i++)
482 if (PGM_RD_W((*tt)[i][0]) > raw)
484 celsius = PGM_RD_W((*tt)[i-1][1]) +
485 (raw - PGM_RD_W((*tt)[i-1][0])) *
486 (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /
487 (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0]));
492 // Overflow: Set to last value in the table
493 if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i-1][1]);
497 return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
500 // Derived from RepRap FiveD extruder::getTemperature()
501 // For bed temperature measurement.
502 float analog2tempBed(int raw) {
503 #ifdef BED_USES_THERMISTOR
507 raw = (1023 * OVERSAMPLENR) - raw;
509 for (i=1; i<bedtemptable_len; i++)
511 if (PGM_RD_W(bedtemptable[i][0]) > raw)
513 celsius = PGM_RD_W(bedtemptable[i-1][1]) +
514 (raw - PGM_RD_W(bedtemptable[i-1][0])) *
515 (float)(PGM_RD_W(bedtemptable[i][1]) - PGM_RD_W(bedtemptable[i-1][1])) /
516 (float)(PGM_RD_W(bedtemptable[i][0]) - PGM_RD_W(bedtemptable[i-1][0]));
521 // Overflow: Set to last value in the table
522 if (i == bedtemptable_len) celsius = PGM_RD_W(bedtemptable[i-1][1]);
525 #elif defined BED_USES_AD595
526 return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
528 #warning No heater-type defined for the bed.
535 // Finish init of mult extruder arrays
536 for(int e = 0; e < EXTRUDERS; e++) {
537 // populate with the first value
539 watch_raw[e] = watch_raw[0];
541 maxttemp[e] = maxttemp[0];
543 temp_iState_min[e] = 0.0;
544 temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
548 #if (HEATER_0_PIN > -1)
549 SET_OUTPUT(HEATER_0_PIN);
551 #if (HEATER_1_PIN > -1)
552 SET_OUTPUT(HEATER_1_PIN);
554 #if (HEATER_2_PIN > -1)
555 SET_OUTPUT(HEATER_2_PIN);
557 #if (HEATER_BED_PIN > -1)
558 SET_OUTPUT(HEATER_BED_PIN);
564 #ifdef HEATER_0_USES_MAX6675
566 SET_OUTPUT(MAX_SCK_PIN);
567 WRITE(MAX_SCK_PIN,0);
569 SET_OUTPUT(MAX_MOSI_PIN);
570 WRITE(MAX_MOSI_PIN,1);
572 SET_INPUT(MAX_MISO_PIN);
573 WRITE(MAX_MISO_PIN,1);
576 SET_OUTPUT(MAX6675_SS);
581 ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
586 #if (TEMP_0_PIN > -1)
588 DIDR0 |= 1 << TEMP_0_PIN;
590 DIDR2 |= 1<<(TEMP_0_PIN - 8);
593 #if (TEMP_1_PIN > -1)
595 DIDR0 |= 1<<TEMP_1_PIN;
597 DIDR2 |= 1<<(TEMP_1_PIN - 8);
600 #if (TEMP_2_PIN > -1)
602 DIDR0 |= 1 << TEMP_2_PIN;
604 DIDR2 = 1<<(TEMP_2_PIN - 8);
607 #if (TEMP_BED_PIN > -1)
609 DIDR0 |= 1<<TEMP_BED_PIN;
611 DIDR2 |= 1<<(TEMP_BED_PIN - 8);
615 // Use timer0 for temperature measurement
616 // Interleave temperature interrupt with millies interrupt
618 TIMSK0 |= (1<<OCIE0B);
620 // Wait for temperature measurement to settle
623 #ifdef HEATER_0_MINTEMP
624 minttemp[0] = temp2analog(HEATER_0_MINTEMP, 0);
626 #ifdef HEATER_0_MAXTEMP
627 maxttemp[0] = temp2analog(HEATER_0_MAXTEMP, 0);
630 #if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
631 minttemp[1] = temp2analog(HEATER_1_MINTEMP, 1);
633 #if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
634 maxttemp[1] = temp2analog(HEATER_1_MAXTEMP, 1);
637 #if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
638 minttemp[2] = temp2analog(HEATER_2_MINTEMP, 2);
640 #if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
641 maxttemp[2] = temp2analog(HEATER_2_MAXTEMP, 2);
645 bed_minttemp = temp2analogBed(BED_MINTEMP);
648 bed_maxttemp = temp2analogBed(BED_MAXTEMP);
658 for (int e = 0; e < EXTRUDERS; e++)
660 if(isHeatingHotend(e))
661 watch_oldtemp[0] = degHotend(0);
664 watch_raw[e] = current_raw[e];
672 void disable_heater()
674 for(int i=0;i<EXTRUDERS;i++)
675 setTargetHotend(0,i);
680 #if HEATER_0_PIN > -1
681 WRITE(HEATER_0_PIN,LOW);
688 #if HEATER_1_PIN > -1
689 WRITE(HEATER_1_PIN,LOW);
696 #if HEATER_2_PIN > -1
697 WRITE(HEATER_2_PIN,LOW);
701 #if TEMP_BED_PIN > -1
703 #if HEATER_BED_PIN > -1
704 WRITE(HEATER_BED_PIN,LOW);
709 void max_temp_error(uint8_t e) {
711 if(IsStopped() == false) {
713 SERIAL_ERRORLN((int)e);
714 SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !");
718 void min_temp_error(uint8_t e) {
720 if(IsStopped() == false) {
722 SERIAL_ERRORLN((int)e);
723 SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !");
727 void bed_max_temp_error(void) {
728 #if HEATER_BED_PIN > -1
729 WRITE(HEATER_BED_PIN, 0);
731 if(IsStopped() == false) {
733 SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!");
737 #define HEAT_INTERVAL 250
738 #ifdef HEATER_0_USES_MAX6675
739 long max6675_previous_millis = -HEAT_INTERVAL;
740 int max6675_temp = 2000;
744 if (millis() - max6675_previous_millis < HEAT_INTERVAL)
747 max6675_previous_millis = millis();
756 SPCR = (1<<MSTR) | (1<<SPE) | (1<<SPR0);
759 WRITE(MAX6675_SS, 0);
761 // ensure 100ns delay - a bit extra is fine
766 for (;(SPSR & (1<<SPIF)) == 0;);
772 for (;(SPSR & (1<<SPIF)) == 0;);
773 max6675_temp |= SPDR;
775 // disable TT_MAX6675
776 WRITE(MAX6675_SS, 1);
778 if (max6675_temp & 4)
785 max6675_temp = max6675_temp >> 3;
793 // Timer 0 is shared with millies
794 ISR(TIMER0_COMPB_vect)
796 //these variables are only accesible from the ISR, but static, so they don't loose their value
797 static unsigned char temp_count = 0;
798 static unsigned long raw_temp_0_value = 0;
799 static unsigned long raw_temp_1_value = 0;
800 static unsigned long raw_temp_2_value = 0;
801 static unsigned long raw_temp_bed_value = 0;
802 static unsigned char temp_state = 0;
803 static unsigned char pwm_count = 1;
804 static unsigned char soft_pwm_0;
805 static unsigned char soft_pwm_1;
806 static unsigned char soft_pwm_2;
809 soft_pwm_0 = soft_pwm[0];
810 if(soft_pwm_0 > 0) WRITE(HEATER_0_PIN,1);
812 soft_pwm_1 = soft_pwm[1];
813 if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1);
816 soft_pwm_2 = soft_pwm[2];
817 if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1);
820 if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0);
822 if(soft_pwm_1 <= pwm_count) WRITE(HEATER_1_PIN,0);
825 if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0);
832 case 0: // Prepare TEMP_0
833 #if (TEMP_0_PIN > -1)
839 ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
840 ADCSRA |= 1<<ADSC; // Start conversion
847 case 1: // Measure TEMP_0
848 #if (TEMP_0_PIN > -1)
849 raw_temp_0_value += ADC;
851 #ifdef HEATER_0_USES_MAX6675 // TODO remove the blocking
852 raw_temp_0_value = read_max6675();
856 case 2: // Prepare TEMP_BED
857 #if (TEMP_BED_PIN > -1)
861 ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
862 ADCSRA |= 1<<ADSC; // Start conversion
869 case 3: // Measure TEMP_BED
870 #if (TEMP_BED_PIN > -1)
871 raw_temp_bed_value += ADC;
875 case 4: // Prepare TEMP_1
876 #if (TEMP_1_PIN > -1)
882 ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
883 ADCSRA |= 1<<ADSC; // Start conversion
890 case 5: // Measure TEMP_1
891 #if (TEMP_1_PIN > -1)
892 raw_temp_1_value += ADC;
896 case 6: // Prepare TEMP_2
897 #if (TEMP_2_PIN > -1)
903 ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
904 ADCSRA |= 1<<ADSC; // Start conversion
911 case 7: // Measure TEMP_2
912 #if (TEMP_2_PIN > -1)
913 raw_temp_2_value += ADC;
919 // SERIAL_ERROR_START;
920 // SERIAL_ERRORLNPGM("Temp measurement error!");
924 if(temp_count >= 16) // 8 ms * 16 = 128ms.
926 #if defined(HEATER_0_USES_AD595) || defined(HEATER_0_USES_MAX6675)
927 current_raw[0] = raw_temp_0_value;
929 current_raw[0] = 16383 - raw_temp_0_value;
933 #ifdef HEATER_1_USES_AD595
934 current_raw[1] = raw_temp_1_value;
936 current_raw[1] = 16383 - raw_temp_1_value;
941 #ifdef HEATER_2_USES_AD595
942 current_raw[2] = raw_temp_2_value;
944 current_raw[2] = 16383 - raw_temp_2_value;
948 #ifdef BED_USES_AD595
949 current_raw_bed = raw_temp_bed_value;
951 current_raw_bed = 16383 - raw_temp_bed_value;
954 temp_meas_ready = true;
956 raw_temp_0_value = 0;
957 raw_temp_1_value = 0;
958 raw_temp_2_value = 0;
959 raw_temp_bed_value = 0;
961 for(unsigned char e = 0; e < EXTRUDERS; e++) {
962 if(current_raw[e] >= maxttemp[e]) {
965 #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
971 if(current_raw[e] <= minttemp[e]) {
974 #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
982 #if defined(BED_MAXTEMP) && (HEATER_BED_PIN > -1)
983 if(current_raw_bed >= bed_maxttemp) {
985 bed_max_temp_error();