You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1797 lines
51 KiB

/*
temperature.c - temperature control
Part of Marlin
Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This firmware is a mashup between Sprinter and grbl.
(https://github.com/kliment/Sprinter)
(https://github.com/simen/grbl/tree)
It has preliminary support for Matthew Roberts advance algorithm
http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
*/
#include "Marlin.h"
#include "ultralcd.h"
#include "temperature.h"
#include "watchdog.h"
#include "thermistortables.h"
#ifdef HEATER_0_USES_MAX6675
//#include <Sd2PinMap.h>
#endif
//===========================================================================
//=============================public variables============================
//===========================================================================
int target_temperature[EXTRUDERS] = { 0 };
int target_temperature_bed = 0;
int current_temperature_raw[EXTRUDERS] = { 0 };
float current_temperature[EXTRUDERS] = { 0.0 };
int current_temperature_bed_raw = 0;
float current_temperature_bed = 0.0;
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
int redundant_temperature_raw = 0;
float redundant_temperature = 0.0;
#endif
#ifdef PIDTEMPBED
float bedKp=DEFAULT_bedKp;
float bedKi=(DEFAULT_bedKi*PID_dT);
float bedKd=(DEFAULT_bedKd/PID_dT);
#endif //PIDTEMPBED
#ifdef FAN_SOFT_PWM
unsigned char fanSpeedSoftPwm;
#endif
unsigned char soft_pwm_bed;
#ifdef BABYSTEPPING
volatile int babystepsTodo[3]={0,0,0};
#endif
#ifdef FILAMENT_SENSOR
int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
#endif
//===========================================================================
//=============================private variables============================
//===========================================================================
static volatile bool temp_meas_ready = false;
#ifdef PIDTEMP
//static cannot be external:
static float temp_iState[EXTRUDERS] = { 0 };
static float temp_dState[EXTRUDERS] = { 0 };
static float pTerm[EXTRUDERS];
static float iTerm[EXTRUDERS];
static float dTerm[EXTRUDERS];
//int output;
static float pid_error[EXTRUDERS];
static float temp_iState_min[EXTRUDERS];
static float temp_iState_max[EXTRUDERS];
// static float pid_input[EXTRUDERS];
// static float pid_output[EXTRUDERS];
static bool pid_reset[EXTRUDERS];
#endif //PIDTEMP
#ifdef PIDTEMPBED
//static cannot be external:
static float temp_iState_bed = { 0 };
static float temp_dState_bed = { 0 };
static float pTerm_bed;
static float iTerm_bed;
static float dTerm_bed;
//int output;
static float pid_error_bed;
static float temp_iState_min_bed;
static float temp_iState_max_bed;
#else //PIDTEMPBED
static unsigned long previous_millis_bed_heater;
#endif //PIDTEMPBED
static unsigned char soft_pwm[EXTRUDERS];
#ifdef FAN_SOFT_PWM
static unsigned char soft_pwm_fan;
#endif
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
static unsigned long extruder_autofan_last_check;
#endif
#if EXTRUDERS > 3
# error Unsupported number of extruders
#elif EXTRUDERS > 2
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2, v3 }
#elif EXTRUDERS > 1
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2 }
#else
# define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
#endif
#ifdef PIDTEMP
#ifdef PID_PARAMS_PER_EXTRUDER
float Kp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kp, DEFAULT_Kp, DEFAULT_Kp);
float Ki[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT, DEFAULT_Ki*PID_dT);
float Kd[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT, DEFAULT_Kd / PID_dT);
#ifdef PID_ADD_EXTRUSION_RATE
float Kc[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_Kc, DEFAULT_Kc, DEFAULT_Kc);
#endif // PID_ADD_EXTRUSION_RATE
#else //PID_PARAMS_PER_EXTRUDER
float Kp = DEFAULT_Kp;
float Ki = DEFAULT_Ki * PID_dT;
float Kd = DEFAULT_Kd / PID_dT;
#ifdef PID_ADD_EXTRUSION_RATE
float Kc = DEFAULT_Kc;
#endif // PID_ADD_EXTRUSION_RATE
#endif // PID_PARAMS_PER_EXTRUDER
#endif //PIDTEMP
// Init min and max temp with extreme values to prevent false errors during startup
static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0 );
static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383 );
//static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */
#ifdef BED_MAXTEMP
static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
static void *heater_ttbl_map[2] = {(void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE };
static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN };
#else
static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE );
static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN );
#endif
static float analog2temp(int raw, uint8_t e);
static float analog2tempBed(int raw);
static void updateTemperaturesFromRawValues();
#ifdef WATCH_TEMP_PERIOD
int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
#endif //WATCH_TEMP_PERIOD
#ifndef SOFT_PWM_SCALE
#define SOFT_PWM_SCALE 0
#endif
#ifdef FILAMENT_SENSOR
static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor
#endif
//===========================================================================
//============================= functions ============================
//===========================================================================
void PID_autotune(float temp, int extruder, int ncycles)
{
float input = 0.0;
int cycles=0;
bool heating = true;
unsigned long temp_millis = millis();
unsigned long t1=temp_millis;
unsigned long t2=temp_millis;
long t_high = 0;
long t_low = 0;
12 years ago
long bias, d;
float Ku, Tu;
float Kp, Ki, Kd;
float max = 0, min = 10000;
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
unsigned long extruder_autofan_last_check = millis();
#endif
Fixed error found by the free coverity tool (https://scan.coverity.com/) =================================================== Hi, Please find the latest report on new defect(s) introduced to ErikZalm/Marlin found with Coverity Scan. Defect(s) Reported-by: Coverity Scan Showing 15 of 15 defect(s) ** CID 59629: Unchecked return value (CHECKED_RETURN) /Marlin_main.cpp: 2154 in process_commands()() ** CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp: 319 in tone(unsigned char, unsigned int, unsigned long)() ** CID 59631: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1187 in process_commands()() ** CID 59632: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1193 in process_commands()() ** CID 59633: Out-of-bounds write (OVERRUN) /temperature.cpp: 914 in disable_heater()() ** CID 59634: Out-of-bounds write (OVERRUN) /temperature.cpp: 913 in disable_heater()() ** CID 59635: Out-of-bounds read (OVERRUN) /temperature.cpp: 626 in analog2temp(int, unsigned char)() ** CID 59636: Out-of-bounds read (OVERRUN) /temperature.cpp: 620 in analog2temp(int, unsigned char)() ** CID 59637: Out-of-bounds write (OVERRUN) /temperature.cpp: 202 in PID_autotune(float, int, int)() ** CID 59638: Out-of-bounds read (OVERRUN) /temperature.cpp: 214 in PID_autotune(float, int, int)() ** CID 59639: Out-of-bounds write (OVERRUN) /Marlin_main.cpp: 2278 in process_commands()() ** CID 59640: Out-of-bounds read (OVERRUN) /Marlin_main.cpp: 1802 in process_commands()() ** CID 59641: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 51 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ** CID 59642: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 45 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ** CID 59643: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 32 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ________________________________________________________________________________________________________ *** CID 59629: Unchecked return value (CHECKED_RETURN) /Marlin_main.cpp: 2154 in process_commands()() 2148 } 2149 #endif 2150 } 2151 } 2152 break; 2153 case 85: // M85 CID 59629: Unchecked return value (CHECKED_RETURN) Calling "code_seen" without checking return value (as is done elsewhere 66 out of 67 times). 2154 code_seen('S'); 2155 max_inactive_time = code_value() * 1000; 2156 break; 2157 case 92: // M92 2158 for(int8_t i=0; i < NUM_AXIS; i++) 2159 { ________________________________________________________________________________________________________ *** CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp: 319 in tone(unsigned char, unsigned int, unsigned long)() 313 else 314 { 315 // two choices for the 16 bit timers: ck/1 or ck/64 316 ocr = F_CPU / frequency / 2 - 1; 317 318 prescalarbits = 0b001; CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) "ocr > 65535U" is always false regardless of the values of its operands. This occurs as the logical operand of if. 319 if (ocr > 0xffff) 320 { 321 ocr = F_CPU / frequency / 2 / 64 - 1; 322 prescalarbits = 0b011; 323 } 324 ________________________________________________________________________________________________________ *** CID 59631: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1187 in process_commands()() 1181 case 2: // G2 - CW ARC 1182 if(Stopped == false) { 1183 get_arc_coordinates(); 1184 prepare_arc_move(true); 1185 return; 1186 } CID 59631: Missing break in switch (MISSING_BREAK) The above case falls through to this one. 1187 case 3: // G3 - CCW ARC 1188 if(Stopped == false) { 1189 get_arc_coordinates(); 1190 prepare_arc_move(false); 1191 return; 1192 } ________________________________________________________________________________________________________ *** CID 59632: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1193 in process_commands()() 1187 case 3: // G3 - CCW ARC 1188 if(Stopped == false) { 1189 get_arc_coordinates(); 1190 prepare_arc_move(false); 1191 return; 1192 } CID 59632: Missing break in switch (MISSING_BREAK) The above case falls through to this one. 1193 case 4: // G4 dwell 1194 LCD_MESSAGEPGM(MSG_DWELL); 1195 codenum = 0; 1196 if(code_seen('P')) codenum = code_value(); // milliseconds to wait 1197 if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait 1198 ________________________________________________________________________________________________________ *** CID 59633: Out-of-bounds write (OVERRUN) /temperature.cpp: 914 in disable_heater()() 908 WRITE(HEATER_0_PIN,LOW); 909 #endif 910 #endif 911 912 #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 913 target_temperature[1]=0; CID 59633: Out-of-bounds write (OVERRUN) Overrunning array "soft_pwm" of 1 bytes at byte offset 1 using index "1". 914 soft_pwm[1]=0; 915 #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 916 WRITE(HEATER_1_PIN,LOW); 917 #endif 918 #endif 919 ________________________________________________________________________________________________________ *** CID 59634: Out-of-bounds write (OVERRUN) /temperature.cpp: 913 in disable_heater()() 907 #if defined(HEATER_0_PIN) && HEATER_0_PIN > -1 908 WRITE(HEATER_0_PIN,LOW); 909 #endif 910 #endif 911 912 #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 CID 59634: Out-of-bounds write (OVERRUN) Overrunning array "target_temperature" of 1 2-byte elements at element index 1 (byte offset 2) using index "1". 913 target_temperature[1]=0; 914 soft_pwm[1]=0; 915 #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 916 WRITE(HEATER_1_PIN,LOW); 917 #endif 918 #endif ________________________________________________________________________________________________________ *** CID 59635: Out-of-bounds read (OVERRUN) /temperature.cpp: 626 in analog2temp(int, unsigned char)() 620 if(heater_ttbl_map[e] != NULL) 621 { 622 float celsius = 0; 623 uint8_t i; 624 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); 625 CID 59635: Out-of-bounds read (OVERRUN) Overrunning array "heater_ttbllen_map" of 1 bytes at byte offset 1 using index "e" (which evaluates to 1). 626 for (i=1; i<heater_ttbllen_map[e]; i++) 627 { 628 if (PGM_RD_W((*tt)[i][0]) > raw) 629 { 630 celsius = PGM_RD_W((*tt)[i-1][1]) + 631 (raw - PGM_RD_W((*tt)[i-1][0])) * ________________________________________________________________________________________________________ *** CID 59636: Out-of-bounds read (OVERRUN) /temperature.cpp: 620 in analog2temp(int, unsigned char)() 614 if (e == 0) 615 { 616 return 0.25 * raw; 617 } 618 #endif 619 CID 59636: Out-of-bounds read (OVERRUN) Overrunning array "heater_ttbl_map" of 1 2-byte elements at element index 1 (byte offset 2) using index "e" (which evaluates to 1). 620 if(heater_ttbl_map[e] != NULL) 621 { 622 float celsius = 0; 623 uint8_t i; 624 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); 625 ________________________________________________________________________________________________________ *** CID 59637: Out-of-bounds write (OVERRUN) /temperature.cpp: 202 in PID_autotune(float, int, int)() 196 { 197 soft_pwm_bed = (MAX_BED_POWER)/2; 198 bias = d = (MAX_BED_POWER)/2; 199 } 200 else 201 { CID 59637: Out-of-bounds write (OVERRUN) Overrunning array "soft_pwm" of 1 bytes at byte offset 1 using index "extruder" (which evaluates to 1). 202 soft_pwm[extruder] = (PID_MAX)/2; 203 bias = d = (PID_MAX)/2; 204 } 205 206 207 ________________________________________________________________________________________________________ *** CID 59638: Out-of-bounds read (OVERRUN) /temperature.cpp: 214 in PID_autotune(float, int, int)() 208 209 for(;;) { 210 211 if(temp_meas_ready == true) { // temp sample ready 212 updateTemperaturesFromRawValues(); 213 CID 59638: Out-of-bounds read (OVERRUN) Overrunning array "current_temperature" of 1 4-byte elements at element index 1 (byte offset 4) using index "extruder" (which evaluates to 1). 214 input = (extruder<0)?current_temperature_bed:current_temperature[extruder]; 215 216 max=max(max,input); 217 min=min(min,input); 218 if(heating == true && input > temp) { 219 if(millis() - t2 > 5000) { ________________________________________________________________________________________________________ *** CID 59639: Out-of-bounds write (OVERRUN) /Marlin_main.cpp: 2278 in process_commands()() 2272 tmp_extruder = code_value(); 2273 if(tmp_extruder >= EXTRUDERS) { 2274 SERIAL_ECHO_START; 2275 SERIAL_ECHO(MSG_M200_INVALID_EXTRUDER); 2276 } 2277 } CID 59639: Out-of-bounds write (OVERRUN) Overrunning array "volumetric_multiplier" of 1 4-byte elements at element index 1 (byte offset 4) using index "tmp_extruder" (which evaluates to 1). 2278 volumetric_multiplier[tmp_extruder] = 1 / area; 2279 } 2280 break; 2281 case 201: // M201 2282 for(int8_t i=0; i < NUM_AXIS; i++) 2283 { ________________________________________________________________________________________________________ *** CID 59640: Out-of-bounds read (OVERRUN) /Marlin_main.cpp: 1802 in process_commands()() 1796 int pin_status = code_value(); 1797 int pin_number = LED_PIN; 1798 if (code_seen('P') && pin_status >= 0 && pin_status <= 255) 1799 pin_number = code_value(); 1800 for(int8_t i = 0; i < (int8_t)sizeof(sensitive_pins); i++) 1801 { CID 59640: Out-of-bounds read (OVERRUN) Overrunning array "sensitive_pins" of 28 2-byte elements at element index 55 (byte offset 110) using index "i" (which evaluates to 55). 1802 if (sensitive_pins[i] == pin_number) 1803 { 1804 pin_number = -1; 1805 break; 1806 } 1807 } ________________________________________________________________________________________________________ *** CID 59641: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 51 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 45 } 46 47 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 48 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 49 { 50 init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); CID 59641: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 51 } 52 53 void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, 54 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 55 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 56 { ________________________________________________________________________________________________________ *** CID 59642: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 45 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 39 } 40 41 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 42 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 43 { 44 init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); CID 59642: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 45 } 46 47 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 48 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 49 { 50 init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); ________________________________________________________________________________________________________ *** CID 59643: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 32 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 26 27 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 28 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 29 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 30 { 31 init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); CID 59643: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 32 } 33 34 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 35 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 36 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 37 { ________________________________________________________________________________________________________ To view the defects in Coverity Scan visit, http://scan.coverity.com/projects/2224?tab=overview
11 years ago
if ((extruder >= EXTRUDERS)
#if (TEMP_BED_PIN <= -1)
||(extruder < 0)
#endif
){
SERIAL_ECHOLN("PID Autotune failed. Bad extruder number.");
return;
}
SERIAL_ECHOLN("PID Autotune start");
13 years ago
disable_heater(); // switch off all heaters.
if (extruder<0)
{
soft_pwm_bed = (MAX_BED_POWER)/2;
bias = d = (MAX_BED_POWER)/2;
}
else
{
soft_pwm[extruder] = (PID_MAX)/2;
bias = d = (PID_MAX)/2;
12 years ago
}
for(;;) {
if(temp_meas_ready == true) { // temp sample ready
updateTemperaturesFromRawValues();
input = (extruder<0)?current_temperature_bed:current_temperature[extruder];
max=max(max,input);
min=min(min,input);
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
if(millis() - extruder_autofan_last_check > 2500) {
checkExtruderAutoFans();
extruder_autofan_last_check = millis();
}
#endif
if(heating == true && input > temp) {
if(millis() - t2 > 5000) {
heating=false;
if (extruder<0)
soft_pwm_bed = (bias - d) >> 1;
else
soft_pwm[extruder] = (bias - d) >> 1;
t1=millis();
t_high=t1 - t2;
max=temp;
}
}
if(heating == false && input < temp) {
if(millis() - t1 > 5000) {
heating=true;
t2=millis();
t_low=t2 - t1;
if(cycles > 0) {
bias += (d*(t_high - t_low))/(t_low + t_high);
12 years ago
bias = constrain(bias, 20 ,(extruder<0?(MAX_BED_POWER):(PID_MAX))-20);
if(bias > (extruder<0?(MAX_BED_POWER):(PID_MAX))/2) d = (extruder<0?(MAX_BED_POWER):(PID_MAX)) - 1 - bias;
else d = bias;
SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias);
SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d);
SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min);
SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max);
if(cycles > 2) {
Ku = (4.0*d)/(3.14159*(max-min)/2.0);
Tu = ((float)(t_low + t_high)/1000.0);
SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku);
SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu);
Kp = 0.6*Ku;
Ki = 2*Kp/Tu;
Kd = Kp*Tu/8;
11 years ago
SERIAL_PROTOCOLLNPGM(" Classic PID ");
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
/*
Kp = 0.33*Ku;
Ki = Kp/Tu;
Kd = Kp*Tu/3;
SERIAL_PROTOCOLLNPGM(" Some overshoot ");
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
Kp = 0.2*Ku;
Ki = 2*Kp/Tu;
Kd = Kp*Tu/3;
SERIAL_PROTOCOLLNPGM(" No overshoot ");
SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
*/
}
}
if (extruder<0)
soft_pwm_bed = (bias + d) >> 1;
else
soft_pwm[extruder] = (bias + d) >> 1;
cycles++;
min=temp;
}
}
}
if(input > (temp + 20)) {
SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature too high");
return;
}
if(millis() - temp_millis > 2000) {
int p;
if (extruder<0){
p=soft_pwm_bed;
SERIAL_PROTOCOLPGM("ok B:");
}else{
p=soft_pwm[extruder];
SERIAL_PROTOCOLPGM("ok T:");
}
SERIAL_PROTOCOL(input);
SERIAL_PROTOCOLPGM(" @:");
SERIAL_PROTOCOLLN(p);
temp_millis = millis();
}
if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
return;
}
if(cycles > ncycles) {
SERIAL_PROTOCOLLNPGM("PID Autotune finished! Put the last Kp, Ki and Kd constants from above into Configuration.h");
return;
}
lcd_update();
}
}
void updatePID()
{
#ifdef PIDTEMP
for(int e = 0; e < EXTRUDERS; e++) {
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
}
12 years ago
#endif
#ifdef PIDTEMPBED
temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
#endif
}
int getHeaterPower(int heater) {
if (heater<0)
return soft_pwm_bed;
return soft_pwm[heater];
}
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
#if defined(FAN_PIN) && FAN_PIN > -1
#if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
#error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
#endif
#endif
void setExtruderAutoFanState(int pin, bool state)
{
unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0;
// this idiom allows both digital and PWM fan outputs (see M42 handling).
pinMode(pin, OUTPUT);
digitalWrite(pin, newFanSpeed);
analogWrite(pin, newFanSpeed);
}
void checkExtruderAutoFans()
{
uint8_t fanState = 0;
// which fan pins need to be turned on?
#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
fanState |= 1;
#endif
#if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1
if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else
fanState |= 2;
}
#endif
#if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1
if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
{
if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
fanState |= 1;
else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
fanState |= 2;
else
fanState |= 4;
}
#endif
// update extruder auto fan states
#if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
#endif
#if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1
if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
#endif
#if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1
if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
&& EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
#endif
}
#endif // any extruder auto fan pins set
void manage_heater()
{
float pid_input;
float pid_output;
if(temp_meas_ready != true) //better readability
return;
updateTemperaturesFromRawValues();
for(int e = 0; e < EXTRUDERS; e++)
{
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS);
#endif
#ifdef PIDTEMP
pid_input = current_temperature[e];
#ifndef PID_OPENLOOP
pid_error[e] = target_temperature[e] - pid_input;
if(pid_error[e] > PID_FUNCTIONAL_RANGE) {
pid_output = BANG_MAX;
pid_reset[e] = true;
}
else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
pid_output = 0;
pid_reset[e] = true;
}
else {
if(pid_reset[e] == true) {
temp_iState[e] = 0.0;
pid_reset[e] = false;
}
pTerm[e] = PID_PARAM(Kp,e) * pid_error[e];
temp_iState[e] += pid_error[e];
temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
iTerm[e] = PID_PARAM(Ki,e) * temp_iState[e];
//K1 defined in Configuration.h in the PID settings
#define K2 (1.0-K1)
dTerm[e] = (PID_PARAM(Kd,e) * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
pid_output = pTerm[e] + iTerm[e] - dTerm[e];
if (pid_output > PID_MAX) {
if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output=PID_MAX;
} else if (pid_output < 0){
if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
pid_output=0;
}
}
temp_dState[e] = pid_input;
#else
pid_output = constrain(target_temperature[e], 0, PID_MAX);
#endif //PID_OPENLOOP
#ifdef PID_DEBUG
SERIAL_ECHO_START;
SERIAL_ECHO(" PID_DEBUG ");
SERIAL_ECHO(e);
SERIAL_ECHO(": Input ");
SERIAL_ECHO(pid_input);
SERIAL_ECHO(" Output ");
SERIAL_ECHO(pid_output);
SERIAL_ECHO(" pTerm ");
SERIAL_ECHO(pTerm[e]);
SERIAL_ECHO(" iTerm ");
SERIAL_ECHO(iTerm[e]);
SERIAL_ECHO(" dTerm ");
SERIAL_ECHOLN(dTerm[e]);
#endif //PID_DEBUG
#else /* PID off */
pid_output = 0;
if(current_temperature[e] < target_temperature[e]) {
pid_output = PID_MAX;
}
#endif
// Check if temperature is within the correct range
if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
{
soft_pwm[e] = (int)pid_output >> 1;
}
else {
soft_pwm[e] = 0;
}
#ifdef WATCH_TEMP_PERIOD
if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD)
{
if(degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE)
{
setTargetHotend(0, e);
LCD_MESSAGEPGM("Heating failed");
SERIAL_ECHO_START;
SERIAL_ECHOLN("Heating failed");
}else{
watchmillis[e] = 0;
}
}
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
if(fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
disable_heater();
if(IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Extruder switched off. Temperature difference between temp sensors is too high !");
LCD_ALERTMESSAGEPGM("Err: REDUNDANT TEMP ERROR");
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
#endif
}
#endif
} // End extruder for loop
#if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
(defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
if(millis() - extruder_autofan_last_check > 2500) // only need to check fan state very infrequently
{
checkExtruderAutoFans();
extruder_autofan_last_check = millis();
}
#endif
#ifndef PIDTEMPBED
if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
return;
previous_millis_bed_heater = millis();
#endif
#if TEMP_SENSOR_BED != 0
#ifdef THERMAL_RUNAWAY_PROTECTION_PERIOD && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, 9, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS);
#endif
#ifdef PIDTEMPBED
pid_input = current_temperature_bed;
#ifndef PID_OPENLOOP
pid_error_bed = target_temperature_bed - pid_input;
pTerm_bed = bedKp * pid_error_bed;
temp_iState_bed += pid_error_bed;
temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
iTerm_bed = bedKi * temp_iState_bed;
//K1 defined in Configuration.h in the PID settings
#define K2 (1.0-K1)
dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
temp_dState_bed = pid_input;
pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
if (pid_output > MAX_BED_POWER) {
if (pid_error_bed > 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output=MAX_BED_POWER;
} else if (pid_output < 0){
if (pid_error_bed < 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
pid_output=0;
}
#else
pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
#endif //PID_OPENLOOP
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
{
soft_pwm_bed = (int)pid_output >> 1;
}
else {
soft_pwm_bed = 0;
}
#elif !defined(BED_LIMIT_SWITCHING)
// Check if temperature is within the correct range
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
{
if(current_temperature_bed >= target_temperature_bed)
{
soft_pwm_bed = 0;
}
else
{
soft_pwm_bed = MAX_BED_POWER>>1;
}
}
else
{
soft_pwm_bed = 0;
WRITE(HEATER_BED_PIN,LOW);
}
#else //#ifdef BED_LIMIT_SWITCHING
// Check if temperature is within the correct band
if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
{
if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
{
soft_pwm_bed = 0;
}
else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
{
soft_pwm_bed = MAX_BED_POWER>>1;
}
}
else
{
soft_pwm_bed = 0;
WRITE(HEATER_BED_PIN,LOW);
}
#endif
#endif
//code for controlling the extruder rate based on the width sensor
#ifdef FILAMENT_SENSOR
if(filament_sensor)
{
meas_shift_index=delay_index1-meas_delay_cm;
if(meas_shift_index<0)
meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed
//get the delayed info and add 100 to reconstitute to a percent of the nominal filament diameter
//then square it to get an area
if(meas_shift_index<0)
meas_shift_index=0;
else if (meas_shift_index>MAX_MEASUREMENT_DELAY)
meas_shift_index=MAX_MEASUREMENT_DELAY;
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/100.0,2);
if (volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] <0.01)
volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01;
}
#endif
}
#define PGM_RD_W(x) (short)pgm_read_word(&x)
// Derived from RepRap FiveD extruder::getTemperature()
// For hot end temperature measurement.
static float analog2temp(int raw, uint8_t e) {
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
if(e > EXTRUDERS)
#else
if(e >= EXTRUDERS)
#endif
{
SERIAL_ERROR_START;
SERIAL_ERROR((int)e);
SERIAL_ERRORLNPGM(" - Invalid extruder number !");
kill();
return 0.0;
}
#ifdef HEATER_0_USES_MAX6675
if (e == 0)
{
return 0.25 * raw;
}
#endif
if(heater_ttbl_map[e] != NULL)
{
float celsius = 0;
uint8_t i;
short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
for (i=1; i<heater_ttbllen_map[e]; i++)
{
if (PGM_RD_W((*tt)[i][0]) > raw)
{
celsius = PGM_RD_W((*tt)[i-1][1]) +
(raw - PGM_RD_W((*tt)[i-1][0])) *
(float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /
(float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0]));
break;
}
}
// Overflow: Set to last value in the table
if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i-1][1]);
return celsius;
}
return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
}
// Derived from RepRap FiveD extruder::getTemperature()
// For bed temperature measurement.
static float analog2tempBed(int raw) {
#ifdef BED_USES_THERMISTOR
float celsius = 0;
byte i;
for (i=1; i<BEDTEMPTABLE_LEN; i++)
{
if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw)
{
celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) +
(raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) *
(float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) /
(float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i-1][0]));
break;
}
}
// Overflow: Set to last value in the table
if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]);
return celsius;
#elif defined BED_USES_AD595
return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
#else
return 0;
#endif
}
/* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
static void updateTemperaturesFromRawValues()
{
for(uint8_t e=0;e<EXTRUDERS;e++)
{
current_temperature[e] = analog2temp(current_temperature_raw[e], e);
}
current_temperature_bed = analog2tempBed(current_temperature_bed_raw);
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature = analog2temp(redundant_temperature_raw, 1);
#endif
#if defined (FILAMENT_SENSOR) && (FILWIDTH_PIN > -1) //check if a sensor is supported
filament_width_meas = analog2widthFil();
#endif
//Reset the watchdog after we know we have a temperature measurement.
watchdog_reset();
CRITICAL_SECTION_START;
temp_meas_ready = false;
CRITICAL_SECTION_END;
}
// For converting raw Filament Width to milimeters
#ifdef FILAMENT_SENSOR
float analog2widthFil() {
return current_raw_filwidth/16383.0*5.0;
//return current_raw_filwidth;
}
// For converting raw Filament Width to a ratio
int widthFil_to_size_ratio() {
float temp;
temp=filament_width_meas;
if(filament_width_meas<MEASURED_LOWER_LIMIT)
temp=filament_width_nominal; //assume sensor cut out
else if (filament_width_meas>MEASURED_UPPER_LIMIT)
temp= MEASURED_UPPER_LIMIT;
return(filament_width_nominal/temp*100);
}
#endif
void tp_init()
{
#if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
//disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
MCUCR=(1<<JTD);
MCUCR=(1<<JTD);
#endif
// Finish init of mult extruder arrays
for(int e = 0; e < EXTRUDERS; e++) {
// populate with the first value
maxttemp[e] = maxttemp[0];
#ifdef PIDTEMP
temp_iState_min[e] = 0.0;
temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / PID_PARAM(Ki,e);
#endif //PIDTEMP
#ifdef PIDTEMPBED
temp_iState_min_bed = 0.0;
temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
#endif //PIDTEMPBED
}
#if defined(HEATER_0_PIN) && (HEATER_0_PIN > -1)
SET_OUTPUT(HEATER_0_PIN);
#endif
#if defined(HEATER_1_PIN) && (HEATER_1_PIN > -1)
SET_OUTPUT(HEATER_1_PIN);
#endif
#if defined(HEATER_2_PIN) && (HEATER_2_PIN > -1)
SET_OUTPUT(HEATER_2_PIN);
#endif
#if defined(HEATER_BED_PIN) && (HEATER_BED_PIN > -1)
SET_OUTPUT(HEATER_BED_PIN);
#endif
#if defined(FAN_PIN) && (FAN_PIN > -1)
SET_OUTPUT(FAN_PIN);
#ifdef FAST_PWM_FAN
setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
#endif
#ifdef FAN_SOFT_PWM
soft_pwm_fan = fanSpeedSoftPwm / 2;
#endif
#endif
#ifdef HEATER_0_USES_MAX6675
#ifndef SDSUPPORT
SET_OUTPUT(SCK_PIN);
WRITE(SCK_PIN,0);
SET_OUTPUT(MOSI_PIN);
WRITE(MOSI_PIN,1);
SET_INPUT(MISO_PIN);
WRITE(MISO_PIN,1);
#endif
/* Using pinMode and digitalWrite, as that was the only way I could get it to compile */
//Have to toggle SD card CS pin to low first, to enable firmware to talk with SD card
pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN,0);
pinMode(MAX6675_SS, OUTPUT);
digitalWrite(MAX6675_SS,1);
#endif
// Set analog inputs
ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
#if TEMP_0_PIN < 8
DIDR0 |= 1 << TEMP_0_PIN;
#else
DIDR2 |= 1<<(TEMP_0_PIN - 8);
#endif
#endif
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
#if TEMP_1_PIN < 8
DIDR0 |= 1<<TEMP_1_PIN;
#else
DIDR2 |= 1<<(TEMP_1_PIN - 8);
#endif
#endif
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
#if TEMP_2_PIN < 8
DIDR0 |= 1 << TEMP_2_PIN;
#else
DIDR2 |= 1<<(TEMP_2_PIN - 8);
#endif
#endif
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
#if TEMP_BED_PIN < 8
DIDR0 |= 1<<TEMP_BED_PIN;
#else
DIDR2 |= 1<<(TEMP_BED_PIN - 8);
#endif
#endif
//Added for Filament Sensor
#ifdef FILAMENT_SENSOR
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1)
#if FILWIDTH_PIN < 8
DIDR0 |= 1<<FILWIDTH_PIN;
#else
DIDR2 |= 1<<(FILWIDTH_PIN - 8);
#endif
#endif
#endif
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
TIMSK0 |= (1<<OCIE0B);
// Wait for temperature measurement to settle
delay(250);
#ifdef HEATER_0_MINTEMP
minttemp[0] = HEATER_0_MINTEMP;
while(analog2temp(minttemp_raw[0], 0) < HEATER_0_MINTEMP) {
#if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
minttemp_raw[0] += OVERSAMPLENR;
#else
minttemp_raw[0] -= OVERSAMPLENR;
#endif
}
#endif //MINTEMP
#ifdef HEATER_0_MAXTEMP
maxttemp[0] = HEATER_0_MAXTEMP;
while(analog2temp(maxttemp_raw[0], 0) > HEATER_0_MAXTEMP) {
#if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
maxttemp_raw[0] -= OVERSAMPLENR;
#else
maxttemp_raw[0] += OVERSAMPLENR;
#endif
}
#endif //MAXTEMP
#if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
minttemp[1] = HEATER_1_MINTEMP;
while(analog2temp(minttemp_raw[1], 1) < HEATER_1_MINTEMP) {
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
minttemp_raw[1] += OVERSAMPLENR;
#else
minttemp_raw[1] -= OVERSAMPLENR;
#endif
}
#endif // MINTEMP 1
#if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
maxttemp[1] = HEATER_1_MAXTEMP;
while(analog2temp(maxttemp_raw[1], 1) > HEATER_1_MAXTEMP) {
#if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
maxttemp_raw[1] -= OVERSAMPLENR;
#else
maxttemp_raw[1] += OVERSAMPLENR;
#endif
}
#endif //MAXTEMP 1
#if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
minttemp[2] = HEATER_2_MINTEMP;
while(analog2temp(minttemp_raw[2], 2) < HEATER_2_MINTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
minttemp_raw[2] += OVERSAMPLENR;
#else
minttemp_raw[2] -= OVERSAMPLENR;
#endif
}
#endif //MINTEMP 2
#if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
maxttemp[2] = HEATER_2_MAXTEMP;
while(analog2temp(maxttemp_raw[2], 2) > HEATER_2_MAXTEMP) {
#if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
maxttemp_raw[2] -= OVERSAMPLENR;
#else
maxttemp_raw[2] += OVERSAMPLENR;
#endif
}
#endif //MAXTEMP 2
#ifdef BED_MINTEMP
/* No bed MINTEMP error implemented?!? */ /*
while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
#if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
bed_minttemp_raw += OVERSAMPLENR;
#else
bed_minttemp_raw -= OVERSAMPLENR;
#endif
}
*/
#endif //BED_MINTEMP
#ifdef BED_MAXTEMP
while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) {
#if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
bed_maxttemp_raw -= OVERSAMPLENR;
#else
bed_maxttemp_raw += OVERSAMPLENR;
#endif
}
#endif //BED_MAXTEMP
}
void setWatch()
{
#ifdef WATCH_TEMP_PERIOD
for (int e = 0; e < EXTRUDERS; e++)
{
if(degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2))
{
watch_start_temp[e] = degHotend(e);
watchmillis[e] = millis();
}
}
#endif
}
#if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc)
{
/*
SERIAL_ECHO_START;
SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:");
SERIAL_ECHO(heater_id);
SERIAL_ECHO(" ; State:");
SERIAL_ECHO(*state);
SERIAL_ECHO(" ; Timer:");
SERIAL_ECHO(*timer);
SERIAL_ECHO(" ; Temperature:");
SERIAL_ECHO(temperature);
SERIAL_ECHO(" ; Target Temp:");
SERIAL_ECHO(target_temperature);
SERIAL_ECHOLN("");
*/
if ((target_temperature == 0) || thermal_runaway)
{
*state = 0;
*timer = 0;
return;
}
switch (*state)
{
case 0: // "Heater Inactive" state
if (target_temperature > 0) *state = 1;
break;
case 1: // "First Heating" state
if (temperature >= target_temperature) *state = 2;
break;
case 2: // "Temperature Stable" state
if (temperature >= (target_temperature - hysteresis_degc))
{
*timer = millis();
}
else if ( (millis() - *timer) > ((unsigned long) period_seconds) * 1000)
{
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Thermal Runaway, system stopped! Heater_ID: ");
SERIAL_ERRORLN((int)heater_id);
LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
thermal_runaway = true;
while(1)
{
disable_heater();
disable_x();
disable_y();
disable_z();
disable_e0();
disable_e1();
disable_e2();
manage_heater();
lcd_update();
}
}
break;
}
}
#endif
void disable_heater()
{
for(int i=0;i<EXTRUDERS;i++)
setTargetHotend(0,i);
setTargetBed(0);
#if defined(TEMP_0_PIN) && TEMP_0_PIN > -1
target_temperature[0]=0;
soft_pwm[0]=0;
#if defined(HEATER_0_PIN) && HEATER_0_PIN > -1
WRITE(HEATER_0_PIN,LOW);
#endif
#endif
Fixed error found by the free coverity tool (https://scan.coverity.com/) =================================================== Hi, Please find the latest report on new defect(s) introduced to ErikZalm/Marlin found with Coverity Scan. Defect(s) Reported-by: Coverity Scan Showing 15 of 15 defect(s) ** CID 59629: Unchecked return value (CHECKED_RETURN) /Marlin_main.cpp: 2154 in process_commands()() ** CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp: 319 in tone(unsigned char, unsigned int, unsigned long)() ** CID 59631: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1187 in process_commands()() ** CID 59632: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1193 in process_commands()() ** CID 59633: Out-of-bounds write (OVERRUN) /temperature.cpp: 914 in disable_heater()() ** CID 59634: Out-of-bounds write (OVERRUN) /temperature.cpp: 913 in disable_heater()() ** CID 59635: Out-of-bounds read (OVERRUN) /temperature.cpp: 626 in analog2temp(int, unsigned char)() ** CID 59636: Out-of-bounds read (OVERRUN) /temperature.cpp: 620 in analog2temp(int, unsigned char)() ** CID 59637: Out-of-bounds write (OVERRUN) /temperature.cpp: 202 in PID_autotune(float, int, int)() ** CID 59638: Out-of-bounds read (OVERRUN) /temperature.cpp: 214 in PID_autotune(float, int, int)() ** CID 59639: Out-of-bounds write (OVERRUN) /Marlin_main.cpp: 2278 in process_commands()() ** CID 59640: Out-of-bounds read (OVERRUN) /Marlin_main.cpp: 1802 in process_commands()() ** CID 59641: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 51 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ** CID 59642: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 45 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ** CID 59643: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 32 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ________________________________________________________________________________________________________ *** CID 59629: Unchecked return value (CHECKED_RETURN) /Marlin_main.cpp: 2154 in process_commands()() 2148 } 2149 #endif 2150 } 2151 } 2152 break; 2153 case 85: // M85 CID 59629: Unchecked return value (CHECKED_RETURN) Calling "code_seen" without checking return value (as is done elsewhere 66 out of 67 times). 2154 code_seen('S'); 2155 max_inactive_time = code_value() * 1000; 2156 break; 2157 case 92: // M92 2158 for(int8_t i=0; i < NUM_AXIS; i++) 2159 { ________________________________________________________________________________________________________ *** CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp: 319 in tone(unsigned char, unsigned int, unsigned long)() 313 else 314 { 315 // two choices for the 16 bit timers: ck/1 or ck/64 316 ocr = F_CPU / frequency / 2 - 1; 317 318 prescalarbits = 0b001; CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) "ocr > 65535U" is always false regardless of the values of its operands. This occurs as the logical operand of if. 319 if (ocr > 0xffff) 320 { 321 ocr = F_CPU / frequency / 2 / 64 - 1; 322 prescalarbits = 0b011; 323 } 324 ________________________________________________________________________________________________________ *** CID 59631: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1187 in process_commands()() 1181 case 2: // G2 - CW ARC 1182 if(Stopped == false) { 1183 get_arc_coordinates(); 1184 prepare_arc_move(true); 1185 return; 1186 } CID 59631: Missing break in switch (MISSING_BREAK) The above case falls through to this one. 1187 case 3: // G3 - CCW ARC 1188 if(Stopped == false) { 1189 get_arc_coordinates(); 1190 prepare_arc_move(false); 1191 return; 1192 } ________________________________________________________________________________________________________ *** CID 59632: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1193 in process_commands()() 1187 case 3: // G3 - CCW ARC 1188 if(Stopped == false) { 1189 get_arc_coordinates(); 1190 prepare_arc_move(false); 1191 return; 1192 } CID 59632: Missing break in switch (MISSING_BREAK) The above case falls through to this one. 1193 case 4: // G4 dwell 1194 LCD_MESSAGEPGM(MSG_DWELL); 1195 codenum = 0; 1196 if(code_seen('P')) codenum = code_value(); // milliseconds to wait 1197 if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait 1198 ________________________________________________________________________________________________________ *** CID 59633: Out-of-bounds write (OVERRUN) /temperature.cpp: 914 in disable_heater()() 908 WRITE(HEATER_0_PIN,LOW); 909 #endif 910 #endif 911 912 #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 913 target_temperature[1]=0; CID 59633: Out-of-bounds write (OVERRUN) Overrunning array "soft_pwm" of 1 bytes at byte offset 1 using index "1". 914 soft_pwm[1]=0; 915 #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 916 WRITE(HEATER_1_PIN,LOW); 917 #endif 918 #endif 919 ________________________________________________________________________________________________________ *** CID 59634: Out-of-bounds write (OVERRUN) /temperature.cpp: 913 in disable_heater()() 907 #if defined(HEATER_0_PIN) && HEATER_0_PIN > -1 908 WRITE(HEATER_0_PIN,LOW); 909 #endif 910 #endif 911 912 #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 CID 59634: Out-of-bounds write (OVERRUN) Overrunning array "target_temperature" of 1 2-byte elements at element index 1 (byte offset 2) using index "1". 913 target_temperature[1]=0; 914 soft_pwm[1]=0; 915 #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 916 WRITE(HEATER_1_PIN,LOW); 917 #endif 918 #endif ________________________________________________________________________________________________________ *** CID 59635: Out-of-bounds read (OVERRUN) /temperature.cpp: 626 in analog2temp(int, unsigned char)() 620 if(heater_ttbl_map[e] != NULL) 621 { 622 float celsius = 0; 623 uint8_t i; 624 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); 625 CID 59635: Out-of-bounds read (OVERRUN) Overrunning array "heater_ttbllen_map" of 1 bytes at byte offset 1 using index "e" (which evaluates to 1). 626 for (i=1; i<heater_ttbllen_map[e]; i++) 627 { 628 if (PGM_RD_W((*tt)[i][0]) > raw) 629 { 630 celsius = PGM_RD_W((*tt)[i-1][1]) + 631 (raw - PGM_RD_W((*tt)[i-1][0])) * ________________________________________________________________________________________________________ *** CID 59636: Out-of-bounds read (OVERRUN) /temperature.cpp: 620 in analog2temp(int, unsigned char)() 614 if (e == 0) 615 { 616 return 0.25 * raw; 617 } 618 #endif 619 CID 59636: Out-of-bounds read (OVERRUN) Overrunning array "heater_ttbl_map" of 1 2-byte elements at element index 1 (byte offset 2) using index "e" (which evaluates to 1). 620 if(heater_ttbl_map[e] != NULL) 621 { 622 float celsius = 0; 623 uint8_t i; 624 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); 625 ________________________________________________________________________________________________________ *** CID 59637: Out-of-bounds write (OVERRUN) /temperature.cpp: 202 in PID_autotune(float, int, int)() 196 { 197 soft_pwm_bed = (MAX_BED_POWER)/2; 198 bias = d = (MAX_BED_POWER)/2; 199 } 200 else 201 { CID 59637: Out-of-bounds write (OVERRUN) Overrunning array "soft_pwm" of 1 bytes at byte offset 1 using index "extruder" (which evaluates to 1). 202 soft_pwm[extruder] = (PID_MAX)/2; 203 bias = d = (PID_MAX)/2; 204 } 205 206 207 ________________________________________________________________________________________________________ *** CID 59638: Out-of-bounds read (OVERRUN) /temperature.cpp: 214 in PID_autotune(float, int, int)() 208 209 for(;;) { 210 211 if(temp_meas_ready == true) { // temp sample ready 212 updateTemperaturesFromRawValues(); 213 CID 59638: Out-of-bounds read (OVERRUN) Overrunning array "current_temperature" of 1 4-byte elements at element index 1 (byte offset 4) using index "extruder" (which evaluates to 1). 214 input = (extruder<0)?current_temperature_bed:current_temperature[extruder]; 215 216 max=max(max,input); 217 min=min(min,input); 218 if(heating == true && input > temp) { 219 if(millis() - t2 > 5000) { ________________________________________________________________________________________________________ *** CID 59639: Out-of-bounds write (OVERRUN) /Marlin_main.cpp: 2278 in process_commands()() 2272 tmp_extruder = code_value(); 2273 if(tmp_extruder >= EXTRUDERS) { 2274 SERIAL_ECHO_START; 2275 SERIAL_ECHO(MSG_M200_INVALID_EXTRUDER); 2276 } 2277 } CID 59639: Out-of-bounds write (OVERRUN) Overrunning array "volumetric_multiplier" of 1 4-byte elements at element index 1 (byte offset 4) using index "tmp_extruder" (which evaluates to 1). 2278 volumetric_multiplier[tmp_extruder] = 1 / area; 2279 } 2280 break; 2281 case 201: // M201 2282 for(int8_t i=0; i < NUM_AXIS; i++) 2283 { ________________________________________________________________________________________________________ *** CID 59640: Out-of-bounds read (OVERRUN) /Marlin_main.cpp: 1802 in process_commands()() 1796 int pin_status = code_value(); 1797 int pin_number = LED_PIN; 1798 if (code_seen('P') && pin_status >= 0 && pin_status <= 255) 1799 pin_number = code_value(); 1800 for(int8_t i = 0; i < (int8_t)sizeof(sensitive_pins); i++) 1801 { CID 59640: Out-of-bounds read (OVERRUN) Overrunning array "sensitive_pins" of 28 2-byte elements at element index 55 (byte offset 110) using index "i" (which evaluates to 55). 1802 if (sensitive_pins[i] == pin_number) 1803 { 1804 pin_number = -1; 1805 break; 1806 } 1807 } ________________________________________________________________________________________________________ *** CID 59641: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 51 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 45 } 46 47 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 48 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 49 { 50 init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); CID 59641: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 51 } 52 53 void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, 54 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 55 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 56 { ________________________________________________________________________________________________________ *** CID 59642: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 45 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 39 } 40 41 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 42 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 43 { 44 init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); CID 59642: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 45 } 46 47 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 48 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 49 { 50 init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); ________________________________________________________________________________________________________ *** CID 59643: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 32 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 26 27 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 28 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 29 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 30 { 31 init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); CID 59643: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 32 } 33 34 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 35 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 36 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 37 { ________________________________________________________________________________________________________ To view the defects in Coverity Scan visit, http://scan.coverity.com/projects/2224?tab=overview
11 years ago
#if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 && EXTRUDERS > 1
target_temperature[1]=0;
soft_pwm[1]=0;
#if defined(HEATER_1_PIN) && HEATER_1_PIN > -1
WRITE(HEATER_1_PIN,LOW);
#endif
#endif
Fixed error found by the free coverity tool (https://scan.coverity.com/) =================================================== Hi, Please find the latest report on new defect(s) introduced to ErikZalm/Marlin found with Coverity Scan. Defect(s) Reported-by: Coverity Scan Showing 15 of 15 defect(s) ** CID 59629: Unchecked return value (CHECKED_RETURN) /Marlin_main.cpp: 2154 in process_commands()() ** CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp: 319 in tone(unsigned char, unsigned int, unsigned long)() ** CID 59631: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1187 in process_commands()() ** CID 59632: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1193 in process_commands()() ** CID 59633: Out-of-bounds write (OVERRUN) /temperature.cpp: 914 in disable_heater()() ** CID 59634: Out-of-bounds write (OVERRUN) /temperature.cpp: 913 in disable_heater()() ** CID 59635: Out-of-bounds read (OVERRUN) /temperature.cpp: 626 in analog2temp(int, unsigned char)() ** CID 59636: Out-of-bounds read (OVERRUN) /temperature.cpp: 620 in analog2temp(int, unsigned char)() ** CID 59637: Out-of-bounds write (OVERRUN) /temperature.cpp: 202 in PID_autotune(float, int, int)() ** CID 59638: Out-of-bounds read (OVERRUN) /temperature.cpp: 214 in PID_autotune(float, int, int)() ** CID 59639: Out-of-bounds write (OVERRUN) /Marlin_main.cpp: 2278 in process_commands()() ** CID 59640: Out-of-bounds read (OVERRUN) /Marlin_main.cpp: 1802 in process_commands()() ** CID 59641: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 51 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ** CID 59642: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 45 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ** CID 59643: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 32 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() ________________________________________________________________________________________________________ *** CID 59629: Unchecked return value (CHECKED_RETURN) /Marlin_main.cpp: 2154 in process_commands()() 2148 } 2149 #endif 2150 } 2151 } 2152 break; 2153 case 85: // M85 CID 59629: Unchecked return value (CHECKED_RETURN) Calling "code_seen" without checking return value (as is done elsewhere 66 out of 67 times). 2154 code_seen('S'); 2155 max_inactive_time = code_value() * 1000; 2156 break; 2157 case 92: // M92 2158 for(int8_t i=0; i < NUM_AXIS; i++) 2159 { ________________________________________________________________________________________________________ *** CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/Tone.cpp: 319 in tone(unsigned char, unsigned int, unsigned long)() 313 else 314 { 315 // two choices for the 16 bit timers: ck/1 or ck/64 316 ocr = F_CPU / frequency / 2 - 1; 317 318 prescalarbits = 0b001; CID 59630: Operands don't affect result (CONSTANT_EXPRESSION_RESULT) "ocr > 65535U" is always false regardless of the values of its operands. This occurs as the logical operand of if. 319 if (ocr > 0xffff) 320 { 321 ocr = F_CPU / frequency / 2 / 64 - 1; 322 prescalarbits = 0b011; 323 } 324 ________________________________________________________________________________________________________ *** CID 59631: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1187 in process_commands()() 1181 case 2: // G2 - CW ARC 1182 if(Stopped == false) { 1183 get_arc_coordinates(); 1184 prepare_arc_move(true); 1185 return; 1186 } CID 59631: Missing break in switch (MISSING_BREAK) The above case falls through to this one. 1187 case 3: // G3 - CCW ARC 1188 if(Stopped == false) { 1189 get_arc_coordinates(); 1190 prepare_arc_move(false); 1191 return; 1192 } ________________________________________________________________________________________________________ *** CID 59632: Missing break in switch (MISSING_BREAK) /Marlin_main.cpp: 1193 in process_commands()() 1187 case 3: // G3 - CCW ARC 1188 if(Stopped == false) { 1189 get_arc_coordinates(); 1190 prepare_arc_move(false); 1191 return; 1192 } CID 59632: Missing break in switch (MISSING_BREAK) The above case falls through to this one. 1193 case 4: // G4 dwell 1194 LCD_MESSAGEPGM(MSG_DWELL); 1195 codenum = 0; 1196 if(code_seen('P')) codenum = code_value(); // milliseconds to wait 1197 if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait 1198 ________________________________________________________________________________________________________ *** CID 59633: Out-of-bounds write (OVERRUN) /temperature.cpp: 914 in disable_heater()() 908 WRITE(HEATER_0_PIN,LOW); 909 #endif 910 #endif 911 912 #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 913 target_temperature[1]=0; CID 59633: Out-of-bounds write (OVERRUN) Overrunning array "soft_pwm" of 1 bytes at byte offset 1 using index "1". 914 soft_pwm[1]=0; 915 #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 916 WRITE(HEATER_1_PIN,LOW); 917 #endif 918 #endif 919 ________________________________________________________________________________________________________ *** CID 59634: Out-of-bounds write (OVERRUN) /temperature.cpp: 913 in disable_heater()() 907 #if defined(HEATER_0_PIN) && HEATER_0_PIN > -1 908 WRITE(HEATER_0_PIN,LOW); 909 #endif 910 #endif 911 912 #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 CID 59634: Out-of-bounds write (OVERRUN) Overrunning array "target_temperature" of 1 2-byte elements at element index 1 (byte offset 2) using index "1". 913 target_temperature[1]=0; 914 soft_pwm[1]=0; 915 #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 916 WRITE(HEATER_1_PIN,LOW); 917 #endif 918 #endif ________________________________________________________________________________________________________ *** CID 59635: Out-of-bounds read (OVERRUN) /temperature.cpp: 626 in analog2temp(int, unsigned char)() 620 if(heater_ttbl_map[e] != NULL) 621 { 622 float celsius = 0; 623 uint8_t i; 624 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); 625 CID 59635: Out-of-bounds read (OVERRUN) Overrunning array "heater_ttbllen_map" of 1 bytes at byte offset 1 using index "e" (which evaluates to 1). 626 for (i=1; i<heater_ttbllen_map[e]; i++) 627 { 628 if (PGM_RD_W((*tt)[i][0]) > raw) 629 { 630 celsius = PGM_RD_W((*tt)[i-1][1]) + 631 (raw - PGM_RD_W((*tt)[i-1][0])) * ________________________________________________________________________________________________________ *** CID 59636: Out-of-bounds read (OVERRUN) /temperature.cpp: 620 in analog2temp(int, unsigned char)() 614 if (e == 0) 615 { 616 return 0.25 * raw; 617 } 618 #endif 619 CID 59636: Out-of-bounds read (OVERRUN) Overrunning array "heater_ttbl_map" of 1 2-byte elements at element index 1 (byte offset 2) using index "e" (which evaluates to 1). 620 if(heater_ttbl_map[e] != NULL) 621 { 622 float celsius = 0; 623 uint8_t i; 624 short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]); 625 ________________________________________________________________________________________________________ *** CID 59637: Out-of-bounds write (OVERRUN) /temperature.cpp: 202 in PID_autotune(float, int, int)() 196 { 197 soft_pwm_bed = (MAX_BED_POWER)/2; 198 bias = d = (MAX_BED_POWER)/2; 199 } 200 else 201 { CID 59637: Out-of-bounds write (OVERRUN) Overrunning array "soft_pwm" of 1 bytes at byte offset 1 using index "extruder" (which evaluates to 1). 202 soft_pwm[extruder] = (PID_MAX)/2; 203 bias = d = (PID_MAX)/2; 204 } 205 206 207 ________________________________________________________________________________________________________ *** CID 59638: Out-of-bounds read (OVERRUN) /temperature.cpp: 214 in PID_autotune(float, int, int)() 208 209 for(;;) { 210 211 if(temp_meas_ready == true) { // temp sample ready 212 updateTemperaturesFromRawValues(); 213 CID 59638: Out-of-bounds read (OVERRUN) Overrunning array "current_temperature" of 1 4-byte elements at element index 1 (byte offset 4) using index "extruder" (which evaluates to 1). 214 input = (extruder<0)?current_temperature_bed:current_temperature[extruder]; 215 216 max=max(max,input); 217 min=min(min,input); 218 if(heating == true && input > temp) { 219 if(millis() - t2 > 5000) { ________________________________________________________________________________________________________ *** CID 59639: Out-of-bounds write (OVERRUN) /Marlin_main.cpp: 2278 in process_commands()() 2272 tmp_extruder = code_value(); 2273 if(tmp_extruder >= EXTRUDERS) { 2274 SERIAL_ECHO_START; 2275 SERIAL_ECHO(MSG_M200_INVALID_EXTRUDER); 2276 } 2277 } CID 59639: Out-of-bounds write (OVERRUN) Overrunning array "volumetric_multiplier" of 1 4-byte elements at element index 1 (byte offset 4) using index "tmp_extruder" (which evaluates to 1). 2278 volumetric_multiplier[tmp_extruder] = 1 / area; 2279 } 2280 break; 2281 case 201: // M201 2282 for(int8_t i=0; i < NUM_AXIS; i++) 2283 { ________________________________________________________________________________________________________ *** CID 59640: Out-of-bounds read (OVERRUN) /Marlin_main.cpp: 1802 in process_commands()() 1796 int pin_status = code_value(); 1797 int pin_number = LED_PIN; 1798 if (code_seen('P') && pin_status >= 0 && pin_status <= 255) 1799 pin_number = code_value(); 1800 for(int8_t i = 0; i < (int8_t)sizeof(sensitive_pins); i++) 1801 { CID 59640: Out-of-bounds read (OVERRUN) Overrunning array "sensitive_pins" of 28 2-byte elements at element index 55 (byte offset 110) using index "i" (which evaluates to 55). 1802 if (sensitive_pins[i] == pin_number) 1803 { 1804 pin_number = -1; 1805 break; 1806 } 1807 } ________________________________________________________________________________________________________ *** CID 59641: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 51 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 45 } 46 47 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 48 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 49 { 50 init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); CID 59641: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 51 } 52 53 void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, 54 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 55 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 56 { ________________________________________________________________________________________________________ *** CID 59642: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 45 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 39 } 40 41 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 42 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 43 { 44 init(1, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0); CID 59642: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 45 } 46 47 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 48 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3) 49 { 50 init(1, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0); ________________________________________________________________________________________________________ *** CID 59643: Uninitialized scalar field (UNINIT_CTOR) /Applications/Arduino.app/Contents/Resources/Java/libraries/LiquidCrystal/LiquidCrystal.cpp: 32 in LiquidCrystal::LiquidCrystal(unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char, unsigned char)() 26 27 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 28 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 29 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 30 { 31 init(0, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); CID 59643: Uninitialized scalar field (UNINIT_CTOR) Non-static class member "_initialized" is not initialized in this constructor nor in any functions that it calls. 32 } 33 34 LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable, 35 uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 36 uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) 37 { ________________________________________________________________________________________________________ To view the defects in Coverity Scan visit, http://scan.coverity.com/projects/2224?tab=overview
11 years ago
#if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 && EXTRUDERS > 2
target_temperature[2]=0;
soft_pwm[2]=0;
#if defined(HEATER_2_PIN) && HEATER_2_PIN > -1
WRITE(HEATER_2_PIN,LOW);
#endif
#endif
#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
target_temperature_bed=0;
soft_pwm_bed=0;
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN,LOW);
#endif
#endif
}
void max_temp_error(uint8_t e) {
disable_heater();
if(IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLN((int)e);
SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !");
LCD_ALERTMESSAGEPGM("Err: MAXTEMP");
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
#endif
}
void min_temp_error(uint8_t e) {
disable_heater();
if(IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLN((int)e);
SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !");
LCD_ALERTMESSAGEPGM("Err: MINTEMP");
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
#endif
}
void bed_max_temp_error(void) {
#if HEATER_BED_PIN > -1
WRITE(HEATER_BED_PIN, 0);
#endif
if(IsStopped() == false) {
SERIAL_ERROR_START;
SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!");
LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED");
}
#ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
Stop();
#endif
}
#ifdef HEATER_0_USES_MAX6675
#define MAX6675_HEAT_INTERVAL 250
long max6675_previous_millis = MAX6675_HEAT_INTERVAL;
int max6675_temp = 2000;
int read_max6675()
{
if (millis() - max6675_previous_millis < MAX6675_HEAT_INTERVAL)
return max6675_temp;
max6675_previous_millis = millis();
max6675_temp = 0;
#ifdef PRR
PRR &= ~(1<<PRSPI);
#elif defined PRR0
PRR0 &= ~(1<<PRSPI);
#endif
SPCR = (1<<MSTR) | (1<<SPE) | (1<<SPR0);
// enable TT_MAX6675
WRITE(MAX6675_SS, 0);
// ensure 100ns delay - a bit extra is fine
asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
// read MSB
SPDR = 0;
for (;(SPSR & (1<<SPIF)) == 0;);
max6675_temp = SPDR;
max6675_temp <<= 8;
// read LSB
SPDR = 0;
for (;(SPSR & (1<<SPIF)) == 0;);
max6675_temp |= SPDR;
// disable TT_MAX6675
WRITE(MAX6675_SS, 1);
if (max6675_temp & 4)
{
// thermocouple open
max6675_temp = 2000;
}
else
{
max6675_temp = max6675_temp >> 3;
}
return max6675_temp;
}
#endif
// Timer 0 is shared with millies
ISR(TIMER0_COMPB_vect)
{
//these variables are only accesible from the ISR, but static, so they don't lose their value
static unsigned char temp_count = 0;
static unsigned long raw_temp_0_value = 0;
static unsigned long raw_temp_1_value = 0;
static unsigned long raw_temp_2_value = 0;
static unsigned long raw_temp_bed_value = 0;
static unsigned char temp_state = 10;
static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
static unsigned char soft_pwm_0;
#ifdef SLOW_PWM_HEATERS
static unsigned char slow_pwm_count = 0;
static unsigned char state_heater_0 = 0;
static unsigned char state_timer_heater_0 = 0;
#endif
#if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
static unsigned char soft_pwm_1;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_1 = 0;
static unsigned char state_timer_heater_1 = 0;
#endif
#endif
#if EXTRUDERS > 2
static unsigned char soft_pwm_2;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_2 = 0;
static unsigned char state_timer_heater_2 = 0;
#endif
#endif
#if HEATER_BED_PIN > -1
static unsigned char soft_pwm_b;
#ifdef SLOW_PWM_HEATERS
static unsigned char state_heater_b = 0;
static unsigned char state_timer_heater_b = 0;
#endif
#endif
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
static unsigned long raw_filwidth_value = 0; //added for filament width sensor
#endif
#ifndef SLOW_PWM_HEATERS
/*
* standard PWM modulation
*/
if(pwm_count == 0){
soft_pwm_0 = soft_pwm[0];
if(soft_pwm_0 > 0) {
WRITE(HEATER_0_PIN,1);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN,1);
#endif
} else WRITE(HEATER_0_PIN,0);
#if EXTRUDERS > 1
soft_pwm_1 = soft_pwm[1];
if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0);
#endif
#if EXTRUDERS > 2
soft_pwm_2 = soft_pwm[2];
if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0);
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
soft_pwm_b = soft_pwm_bed;
if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
#endif
#ifdef FAN_SOFT_PWM
soft_pwm_fan = fanSpeedSoftPwm / 2;
if(soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
#endif
}
if(soft_pwm_0 < pwm_count) {
WRITE(HEATER_0_PIN,0);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN,0);
#endif
}
#if EXTRUDERS > 1
if(soft_pwm_1 < pwm_count) WRITE(HEATER_1_PIN,0);
#endif
#if EXTRUDERS > 2
if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0);
#endif
#ifdef FAN_SOFT_PWM
if(soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
#endif
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
#else //ifndef SLOW_PWM_HEATERS
/*
* SLOW PWM HEATERS
*
* for heaters drived by relay
*/
#ifndef MIN_STATE_TIME
#define MIN_STATE_TIME 16 // MIN_STATE_TIME * 65.5 = time in milliseconds
#endif
if (slow_pwm_count == 0) {
// EXTRUDER 0
soft_pwm_0 = soft_pwm[0];
if (soft_pwm_0 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_0 == 0) {
// if change state set timer
if (state_heater_0 == 0) {
state_timer_heater_0 = MIN_STATE_TIME;
}
state_heater_0 = 1;
WRITE(HEATER_0_PIN, 1);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN, 1);
#endif
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_0 == 0) {
// if change state set timer
if (state_heater_0 == 1) {
state_timer_heater_0 = MIN_STATE_TIME;
}
state_heater_0 = 0;
WRITE(HEATER_0_PIN, 0);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN, 0);
#endif
}
}
#if EXTRUDERS > 1
// EXTRUDER 1
soft_pwm_1 = soft_pwm[1];
if (soft_pwm_1 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 0) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 1;
WRITE(HEATER_1_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 1) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 0;
WRITE(HEATER_1_PIN, 0);
}
}
#endif
#if EXTRUDERS > 2
// EXTRUDER 2
soft_pwm_2 = soft_pwm[2];
if (soft_pwm_2 > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 0) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 1;
WRITE(HEATER_2_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 1) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 0;
WRITE(HEATER_2_PIN, 0);
}
}
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// BED
soft_pwm_b = soft_pwm_bed;
if (soft_pwm_b > 0) {
// turn ON heather only if the minimum time is up
if (state_timer_heater_b == 0) {
// if change state set timer
if (state_heater_b == 0) {
state_timer_heater_b = MIN_STATE_TIME;
}
state_heater_b = 1;
WRITE(HEATER_BED_PIN, 1);
}
} else {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_b == 0) {
// if change state set timer
if (state_heater_b == 1) {
state_timer_heater_b = MIN_STATE_TIME;
}
state_heater_b = 0;
WRITE(HEATER_BED_PIN, 0);
}
}
#endif
} // if (slow_pwm_count == 0)
// EXTRUDER 0
if (soft_pwm_0 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_0 == 0) {
// if change state set timer
if (state_heater_0 == 1) {
state_timer_heater_0 = MIN_STATE_TIME;
}
state_heater_0 = 0;
WRITE(HEATER_0_PIN, 0);
#ifdef HEATERS_PARALLEL
WRITE(HEATER_1_PIN, 0);
#endif
}
}
#if EXTRUDERS > 1
// EXTRUDER 1
if (soft_pwm_1 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_1 == 0) {
// if change state set timer
if (state_heater_1 == 1) {
state_timer_heater_1 = MIN_STATE_TIME;
}
state_heater_1 = 0;
WRITE(HEATER_1_PIN, 0);
}
}
#endif
#if EXTRUDERS > 2
// EXTRUDER 2
if (soft_pwm_2 < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_2 == 0) {
// if change state set timer
if (state_heater_2 == 1) {
state_timer_heater_2 = MIN_STATE_TIME;
}
state_heater_2 = 0;
WRITE(HEATER_2_PIN, 0);
}
}
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// BED
if (soft_pwm_b < slow_pwm_count) {
// turn OFF heather only if the minimum time is up
if (state_timer_heater_b == 0) {
// if change state set timer
if (state_heater_b == 1) {
state_timer_heater_b = MIN_STATE_TIME;
}
state_heater_b = 0;
WRITE(HEATER_BED_PIN, 0);
}
}
#endif
#ifdef FAN_SOFT_PWM
if (pwm_count == 0){
soft_pwm_fan = fanSpeedSoftPwm / 2;
if (soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
}
if (soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
#endif
pwm_count += (1 << SOFT_PWM_SCALE);
pwm_count &= 0x7f;
// increment slow_pwm_count only every 64 pwm_count circa 65.5ms
if ((pwm_count % 64) == 0) {
slow_pwm_count++;
slow_pwm_count &= 0x7f;
// Extruder 0
if (state_timer_heater_0 > 0) {
state_timer_heater_0--;
}
#if EXTRUDERS > 1
// Extruder 1
if (state_timer_heater_1 > 0)
state_timer_heater_1--;
#endif
#if EXTRUDERS > 2
// Extruder 2
if (state_timer_heater_2 > 0)
state_timer_heater_2--;
#endif
#if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
// Bed
if (state_timer_heater_b > 0)
state_timer_heater_b--;
#endif
} //if ((pwm_count % 64) == 0) {
#endif //ifndef SLOW_PWM_HEATERS
switch(temp_state) {
case 0: // Prepare TEMP_0
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
#if TEMP_0_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 1;
break;
case 1: // Measure TEMP_0
#if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
raw_temp_0_value += ADC;
#endif
#ifdef HEATER_0_USES_MAX6675 // TODO remove the blocking
raw_temp_0_value = read_max6675();
#endif
temp_state = 2;
break;
case 2: // Prepare TEMP_BED
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
#if TEMP_BED_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 3;
break;
case 3: // Measure TEMP_BED
#if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
raw_temp_bed_value += ADC;
#endif
temp_state = 4;
break;
case 4: // Prepare TEMP_1
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
#if TEMP_1_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 5;
break;
case 5: // Measure TEMP_1
#if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
raw_temp_1_value += ADC;
#endif
temp_state = 6;
break;
case 6: // Prepare TEMP_2
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
#if TEMP_2_PIN > 7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 7;
break;
case 7: // Measure TEMP_2
#if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
raw_temp_2_value += ADC;
#endif
temp_state = 8;//change so that Filament Width is also measured
break;
case 8: //Prepare FILWIDTH
#if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1)
#if FILWIDTH_PIN>7
ADCSRB = 1<<MUX5;
#else
ADCSRB = 0;
#endif
ADMUX = ((1 << REFS0) | (FILWIDTH_PIN & 0x07));
ADCSRA |= 1<<ADSC; // Start conversion
#endif
lcd_buttons_update();
temp_state = 9;
break;
case 9: //Measure FILWIDTH
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
//raw_filwidth_value += ADC; //remove to use an IIR filter approach
if(ADC>102) //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
{
raw_filwidth_value= raw_filwidth_value-(raw_filwidth_value>>7); //multipliy raw_filwidth_value by 127/128
raw_filwidth_value= raw_filwidth_value + ((unsigned long)ADC<<7); //add new ADC reading
}
#endif
temp_state = 0;
temp_count++;
break;
case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
temp_state = 0;
break;
// default:
// SERIAL_ERROR_START;
// SERIAL_ERRORLNPGM("Temp measurement error!");
// break;
}
if(temp_count >= OVERSAMPLENR) // 10 * 16 * 1/(16000000/64/256) = 164ms.
{
if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
{
current_temperature_raw[0] = raw_temp_0_value;
#if EXTRUDERS > 1
current_temperature_raw[1] = raw_temp_1_value;
#endif
#ifdef TEMP_SENSOR_1_AS_REDUNDANT
redundant_temperature_raw = raw_temp_1_value;
#endif
#if EXTRUDERS > 2
current_temperature_raw[2] = raw_temp_2_value;
#endif
current_temperature_bed_raw = raw_temp_bed_value;
}
//Add similar code for Filament Sensor - can be read any time since IIR filtering is used
#if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
current_raw_filwidth = raw_filwidth_value>>10; //need to divide to get to 0-16384 range since we used 1/128 IIR filter approach
#endif
temp_meas_ready = true;
temp_count = 0;
raw_temp_0_value = 0;
raw_temp_1_value = 0;
raw_temp_2_value = 0;
raw_temp_bed_value = 0;
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
if(current_temperature_raw[0] <= maxttemp_raw[0]) {
#else
if(current_temperature_raw[0] >= maxttemp_raw[0]) {
#endif
max_temp_error(0);
}
#if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
if(current_temperature_raw[0] >= minttemp_raw[0]) {
#else
if(current_temperature_raw[0] <= minttemp_raw[0]) {
#endif
min_temp_error(0);
}
#if EXTRUDERS > 1
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
if(current_temperature_raw[1] <= maxttemp_raw[1]) {
#else
if(current_temperature_raw[1] >= maxttemp_raw[1]) {
#endif
max_temp_error(1);
}
#if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
if(current_temperature_raw[1] >= minttemp_raw[1]) {
#else
if(current_temperature_raw[1] <= minttemp_raw[1]) {
#endif
min_temp_error(1);
}
#endif
#if EXTRUDERS > 2
#if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
if(current_temperature_raw[2] <= maxttemp_raw[2]) {
#else
if(current_temperature_raw[2] >= maxttemp_raw[2]) {
#endif
max_temp_error(2);
}
#if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
if(current_temperature_raw[2] >= minttemp_raw[2]) {
#else
if(current_temperature_raw[2] <= minttemp_raw[2]) {
#endif
min_temp_error(2);
}
#endif
/* No bed MINTEMP error? */
#if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
# if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
if(current_temperature_bed_raw <= bed_maxttemp_raw) {
#else
if(current_temperature_bed_raw >= bed_maxttemp_raw) {
#endif
target_temperature_bed = 0;
bed_max_temp_error();
}
#endif
}
#ifdef BABYSTEPPING
for(uint8_t axis=0;axis<3;axis++)
{
int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
if(curTodo>0)
{
babystep(axis,/*fwd*/true);
babystepsTodo[axis]--; //less to do next time
}
else
if(curTodo<0)
{
babystep(axis,/*fwd*/false);
babystepsTodo[axis]++; //less to do next time
}
}
#endif //BABYSTEPPING
}
#ifdef PIDTEMP
// Apply the scale factors to the PID values
float scalePID_i(float i)
{
return i*PID_dT;
}
float unscalePID_i(float i)
{
return i/PID_dT;
}
float scalePID_d(float d)
{
return d/PID_dT;
}
float unscalePID_d(float d)
{
return d*PID_dT;
}
#endif //PIDTEMP