temperature.cpp 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015
  1. /*
  2. temperature.c - temperature control
  3. Part of Marlin
  4. Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /*
  17. This firmware is a mashup between Sprinter and grbl.
  18. (https://github.com/kliment/Sprinter)
  19. (https://github.com/simen/grbl/tree)
  20. It has preliminary support for Matthew Roberts advance algorithm
  21. http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
  22. */
  23. #include "Marlin.h"
  24. #include "ultralcd.h"
  25. #include "temperature.h"
  26. #include "watchdog.h"
  27. #include "cardreader.h"
  28. #include "Sd2PinMap.h"
  29. //===========================================================================
  30. //=============================public variables============================
  31. //===========================================================================
  32. int target_temperature[EXTRUDERS] = { 0 };
  33. int target_temperature_bed = 0;
  34. int current_temperature_raw[EXTRUDERS] = { 0 };
  35. float current_temperature[EXTRUDERS] = { 0.0 };
  36. int current_temperature_bed_raw = 0;
  37. float current_temperature_bed = 0.0;
  38. #ifdef TEMP_SENSOR_1_AS_REDUNDANT
  39. int redundant_temperature_raw = 0;
  40. float redundant_temperature = 0.0;
  41. #endif
  42. #ifdef PIDTEMP
  43. float Kp=DEFAULT_Kp;
  44. float Ki=(DEFAULT_Ki*PID_dT);
  45. float Kd=(DEFAULT_Kd/PID_dT);
  46. #ifdef PID_ADD_EXTRUSION_RATE
  47. float Kc=DEFAULT_Kc;
  48. #endif
  49. #endif //PIDTEMP
  50. #ifdef PIDTEMPBED
  51. float bedKp=DEFAULT_bedKp;
  52. float bedKi=(DEFAULT_bedKi*PID_dT);
  53. float bedKd=(DEFAULT_bedKd/PID_dT);
  54. #endif //PIDTEMPBED
  55. #ifdef FAN_SOFT_PWM
  56. unsigned char fanSpeedSoftPwm;
  57. #endif
  58. unsigned char soft_pwm_bed;
  59. #ifdef BABYSTEPPING
  60. volatile int babystepsTodo[3]={0,0,0};
  61. #endif
  62. #ifdef FILAMENT_SENSOR
  63. int current_raw_filwidth = 0; //Holds measured filament diameter - one extruder only
  64. #endif
  65. //===========================================================================
  66. //=============================private variables============================
  67. //===========================================================================
  68. static volatile bool temp_meas_ready = false;
  69. #ifdef PIDTEMP
  70. //static cannot be external:
  71. static float temp_iState[EXTRUDERS] = { 0 };
  72. static float temp_dState[EXTRUDERS] = { 0 };
  73. static float pTerm[EXTRUDERS];
  74. static float iTerm[EXTRUDERS];
  75. static float dTerm[EXTRUDERS];
  76. //int output;
  77. static float pid_error[EXTRUDERS];
  78. static float temp_iState_min[EXTRUDERS];
  79. static float temp_iState_max[EXTRUDERS];
  80. // static float pid_input[EXTRUDERS];
  81. // static float pid_output[EXTRUDERS];
  82. static bool pid_reset[EXTRUDERS];
  83. #endif //PIDTEMP
  84. #ifdef PIDTEMPBED
  85. //static cannot be external:
  86. static float temp_iState_bed = { 0 };
  87. static float temp_dState_bed = { 0 };
  88. static float pTerm_bed;
  89. static float iTerm_bed;
  90. static float dTerm_bed;
  91. //int output;
  92. static float pid_error_bed;
  93. static float temp_iState_min_bed;
  94. static float temp_iState_max_bed;
  95. #else //PIDTEMPBED
  96. static unsigned long previous_millis_bed_heater;
  97. #endif //PIDTEMPBED
  98. static unsigned char soft_pwm[EXTRUDERS];
  99. #ifdef FAN_SOFT_PWM
  100. static unsigned char soft_pwm_fan;
  101. #endif
  102. #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
  103. (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
  104. (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
  105. static unsigned long extruder_autofan_last_check;
  106. #endif
  107. #if EXTRUDERS > 3
  108. # error Unsupported number of extruders
  109. #elif EXTRUDERS > 2
  110. # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2, v3 }
  111. #elif EXTRUDERS > 1
  112. # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2 }
  113. #else
  114. # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
  115. #endif
  116. // Init min and max temp with extreme values to prevent false errors during startup
  117. static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
  118. static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
  119. static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0 );
  120. static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383 );
  121. #ifdef BED_MINTEMP
  122. static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP;
  123. #endif
  124. #ifdef BED_MAXTEMP
  125. static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
  126. #endif
  127. #ifdef TEMP_SENSOR_1_AS_REDUNDANT
  128. static void *heater_ttbl_map[2] = {(void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE };
  129. static uint8_t heater_ttbllen_map[2] = { HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN };
  130. #else
  131. static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE );
  132. static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN );
  133. #endif
  134. static float analog2temp(int raw, uint8_t e);
  135. static float analog2tempBed(int raw);
  136. static void updateTemperaturesFromRawValues();
  137. enum TempRunawayStates
  138. {
  139. TempRunaway_INACTIVE = 0,
  140. TempRunaway_PREHEAT = 1,
  141. TempRunaway_ACTIVE = 2,
  142. };
  143. #ifdef WATCH_TEMP_PERIOD
  144. int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
  145. unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
  146. #endif //WATCH_TEMP_PERIOD
  147. #ifndef SOFT_PWM_SCALE
  148. #define SOFT_PWM_SCALE 0
  149. #endif
  150. #ifdef FILAMENT_SENSOR
  151. static int meas_shift_index; //used to point to a delayed sample in buffer for filament width sensor
  152. #endif
  153. //===========================================================================
  154. //============================= functions ============================
  155. //===========================================================================
  156. void PID_autotune(float temp, int extruder, int ncycles)
  157. {
  158. float input = 0.0;
  159. int cycles=0;
  160. bool heating = true;
  161. unsigned long temp_millis = millis();
  162. unsigned long t1=temp_millis;
  163. unsigned long t2=temp_millis;
  164. long t_high = 0;
  165. long t_low = 0;
  166. long bias, d;
  167. float Ku, Tu;
  168. float Kp, Ki, Kd;
  169. float max = 0, min = 10000;
  170. #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
  171. (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
  172. (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
  173. unsigned long extruder_autofan_last_check = millis();
  174. #endif
  175. if ((extruder >= EXTRUDERS)
  176. #if (TEMP_BED_PIN <= -1)
  177. ||(extruder < 0)
  178. #endif
  179. ){
  180. SERIAL_ECHOLN("PID Autotune failed. Bad extruder number.");
  181. return;
  182. }
  183. SERIAL_ECHOLN("PID Autotune start");
  184. disable_heater(); // switch off all heaters.
  185. if (extruder<0)
  186. {
  187. soft_pwm_bed = (MAX_BED_POWER)/2;
  188. bias = d = (MAX_BED_POWER)/2;
  189. }
  190. else
  191. {
  192. soft_pwm[extruder] = (PID_MAX)/2;
  193. bias = d = (PID_MAX)/2;
  194. }
  195. for(;;) {
  196. if(temp_meas_ready == true) { // temp sample ready
  197. updateTemperaturesFromRawValues();
  198. input = (extruder<0)?current_temperature_bed:current_temperature[extruder];
  199. max=max(max,input);
  200. min=min(min,input);
  201. #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
  202. (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
  203. (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
  204. if(millis() - extruder_autofan_last_check > 2500) {
  205. checkExtruderAutoFans();
  206. extruder_autofan_last_check = millis();
  207. }
  208. #endif
  209. if(heating == true && input > temp) {
  210. if(millis() - t2 > 5000) {
  211. heating=false;
  212. if (extruder<0)
  213. soft_pwm_bed = (bias - d) >> 1;
  214. else
  215. soft_pwm[extruder] = (bias - d) >> 1;
  216. t1=millis();
  217. t_high=t1 - t2;
  218. max=temp;
  219. }
  220. }
  221. if(heating == false && input < temp) {
  222. if(millis() - t1 > 5000) {
  223. heating=true;
  224. t2=millis();
  225. t_low=t2 - t1;
  226. if(cycles > 0) {
  227. bias += (d*(t_high - t_low))/(t_low + t_high);
  228. bias = constrain(bias, 20 ,(extruder<0?(MAX_BED_POWER):(PID_MAX))-20);
  229. if(bias > (extruder<0?(MAX_BED_POWER):(PID_MAX))/2) d = (extruder<0?(MAX_BED_POWER):(PID_MAX)) - 1 - bias;
  230. else d = bias;
  231. SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias);
  232. SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d);
  233. SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min);
  234. SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max);
  235. if(cycles > 2) {
  236. Ku = (4.0*d)/(3.14159*(max-min)/2.0);
  237. Tu = ((float)(t_low + t_high)/1000.0);
  238. SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku);
  239. SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu);
  240. Kp = 0.6*Ku;
  241. Ki = 2*Kp/Tu;
  242. Kd = Kp*Tu/8;
  243. SERIAL_PROTOCOLLNPGM(" Classic PID ");
  244. SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
  245. SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
  246. SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
  247. /*
  248. Kp = 0.33*Ku;
  249. Ki = Kp/Tu;
  250. Kd = Kp*Tu/3;
  251. SERIAL_PROTOCOLLNPGM(" Some overshoot ");
  252. SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
  253. SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
  254. SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
  255. Kp = 0.2*Ku;
  256. Ki = 2*Kp/Tu;
  257. Kd = Kp*Tu/3;
  258. SERIAL_PROTOCOLLNPGM(" No overshoot ");
  259. SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
  260. SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
  261. SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
  262. */
  263. }
  264. }
  265. if (extruder<0)
  266. soft_pwm_bed = (bias + d) >> 1;
  267. else
  268. soft_pwm[extruder] = (bias + d) >> 1;
  269. cycles++;
  270. min=temp;
  271. }
  272. }
  273. }
  274. if(input > (temp + 20)) {
  275. SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature too high");
  276. return;
  277. }
  278. if(millis() - temp_millis > 2000) {
  279. int p;
  280. if (extruder<0){
  281. p=soft_pwm_bed;
  282. SERIAL_PROTOCOLPGM("ok B:");
  283. }else{
  284. p=soft_pwm[extruder];
  285. SERIAL_PROTOCOLPGM("ok T:");
  286. }
  287. SERIAL_PROTOCOL(input);
  288. SERIAL_PROTOCOLPGM(" @:");
  289. SERIAL_PROTOCOLLN(p);
  290. temp_millis = millis();
  291. }
  292. if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
  293. SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
  294. return;
  295. }
  296. if(cycles > ncycles) {
  297. SERIAL_PROTOCOLLNPGM("PID Autotune finished! Put the last Kp, Ki and Kd constants from above into Configuration.h");
  298. return;
  299. }
  300. lcd_update();
  301. }
  302. }
  303. void updatePID()
  304. {
  305. #ifdef PIDTEMP
  306. for(int e = 0; e < EXTRUDERS; e++) {
  307. temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
  308. }
  309. #endif
  310. #ifdef PIDTEMPBED
  311. temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
  312. #endif
  313. }
  314. int getHeaterPower(int heater) {
  315. if (heater<0)
  316. return soft_pwm_bed;
  317. return soft_pwm[heater];
  318. }
  319. #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
  320. (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
  321. (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
  322. #if defined(FAN_PIN) && FAN_PIN > -1
  323. #if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
  324. #error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
  325. #endif
  326. #if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
  327. #error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN"
  328. #endif
  329. #if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
  330. #error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
  331. #endif
  332. #endif
  333. void setExtruderAutoFanState(int pin, bool state)
  334. {
  335. unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0;
  336. // this idiom allows both digital and PWM fan outputs (see M42 handling).
  337. pinMode(pin, OUTPUT);
  338. digitalWrite(pin, newFanSpeed);
  339. analogWrite(pin, newFanSpeed);
  340. }
  341. void countFanSpeed()
  342. {
  343. fan_speed[0] = (fan_edge_counter[0] * (float(250) / (millis() - extruder_autofan_last_check)));
  344. fan_speed[1] = (fan_edge_counter[1] * (float(250) / (millis() - extruder_autofan_last_check)));
  345. fan_edge_counter[0] = 0;
  346. fan_edge_counter[1] = 0;
  347. }
  348. void checkFanSpeed()
  349. {
  350. static unsigned char fan_speed_errors[2] = { 0,0 };
  351. if (fan_speed[0] == 0 && current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE) fan_speed_errors[0]++;
  352. else fan_speed_errors[0] = 0;
  353. if (fan_speed[1] == 0 && fanSpeed > MIN_PRINT_FAN_SPEED) fan_speed_errors[1]++;
  354. else fan_speed_errors[1] = 0;
  355. if (fan_speed_errors[0] > 5) fanSpeedError(0);
  356. if (fan_speed_errors[1] > 5) fanSpeedError(1);
  357. }
  358. void fanSpeedError(unsigned char _fan) {
  359. if (card.sdprinting) {
  360. card.pauseSDPrint();
  361. }
  362. setTargetHotend0(0);
  363. /*lcd_update();
  364. WRITE(BEEPER, HIGH);
  365. delayMicroseconds(500);
  366. WRITE(BEEPER, LOW);
  367. delayMicroseconds(100);*/
  368. SERIAL_ERROR_START;
  369. switch (_fan) {
  370. case 0:
  371. SERIAL_ERRORLNPGM("ERROR: Extruder fan speed is lower then expected");
  372. LCD_ALERTMESSAGEPGM("Err: EXTR. FAN ERROR");
  373. break;
  374. case 1:
  375. SERIAL_ERRORLNPGM("ERROR: Print fan speed is lower then expected");
  376. LCD_ALERTMESSAGEPGM("Err: PRINT FAN ERROR");
  377. break;
  378. }
  379. }
  380. void checkExtruderAutoFans()
  381. {
  382. uint8_t fanState = 0;
  383. // which fan pins need to be turned on?
  384. #if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
  385. if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
  386. fanState |= 1;
  387. #endif
  388. #if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1
  389. if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
  390. {
  391. if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
  392. fanState |= 1;
  393. else
  394. fanState |= 2;
  395. }
  396. #endif
  397. #if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1
  398. if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
  399. {
  400. if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
  401. fanState |= 1;
  402. else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
  403. fanState |= 2;
  404. else
  405. fanState |= 4;
  406. }
  407. #endif
  408. // update extruder auto fan states
  409. #if defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1
  410. setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
  411. #endif
  412. #if defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1
  413. if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
  414. setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
  415. #endif
  416. #if defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1
  417. if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
  418. && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
  419. setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
  420. #endif
  421. }
  422. #endif // any extruder auto fan pins set
  423. void manage_heater()
  424. {
  425. float pid_input;
  426. float pid_output;
  427. if(temp_meas_ready != true) //better readability
  428. return;
  429. updateTemperaturesFromRawValues();
  430. #ifdef TEMP_RUNAWAY_BED_HYSTERESIS
  431. temp_runaway_check(0, target_temperature_bed, current_temperature_bed, (int)soft_pwm_bed, true);
  432. #endif
  433. for(int e = 0; e < EXTRUDERS; e++)
  434. {
  435. #ifdef TEMP_RUNAWAY_EXTRUDER_HYSTERESIS
  436. temp_runaway_check(e+1, target_temperature[e], current_temperature[e], (int)soft_pwm[e], false);
  437. #endif
  438. #ifdef PIDTEMP
  439. pid_input = current_temperature[e];
  440. #ifndef PID_OPENLOOP
  441. pid_error[e] = target_temperature[e] - pid_input;
  442. if(pid_error[e] > PID_FUNCTIONAL_RANGE) {
  443. pid_output = BANG_MAX;
  444. pid_reset[e] = true;
  445. }
  446. else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
  447. pid_output = 0;
  448. pid_reset[e] = true;
  449. }
  450. else {
  451. if(pid_reset[e] == true) {
  452. temp_iState[e] = 0.0;
  453. pid_reset[e] = false;
  454. }
  455. pTerm[e] = Kp * pid_error[e];
  456. temp_iState[e] += pid_error[e];
  457. temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
  458. iTerm[e] = Ki * temp_iState[e];
  459. //K1 defined in Configuration.h in the PID settings
  460. #define K2 (1.0-K1)
  461. dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
  462. pid_output = pTerm[e] + iTerm[e] - dTerm[e];
  463. if (pid_output > PID_MAX) {
  464. if (pid_error[e] > 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
  465. pid_output=PID_MAX;
  466. } else if (pid_output < 0){
  467. if (pid_error[e] < 0 ) temp_iState[e] -= pid_error[e]; // conditional un-integration
  468. pid_output=0;
  469. }
  470. }
  471. temp_dState[e] = pid_input;
  472. #else
  473. pid_output = constrain(target_temperature[e], 0, PID_MAX);
  474. #endif //PID_OPENLOOP
  475. #ifdef PID_DEBUG
  476. SERIAL_ECHO_START;
  477. SERIAL_ECHO(" PID_DEBUG ");
  478. SERIAL_ECHO(e);
  479. SERIAL_ECHO(": Input ");
  480. SERIAL_ECHO(pid_input);
  481. SERIAL_ECHO(" Output ");
  482. SERIAL_ECHO(pid_output);
  483. SERIAL_ECHO(" pTerm ");
  484. SERIAL_ECHO(pTerm[e]);
  485. SERIAL_ECHO(" iTerm ");
  486. SERIAL_ECHO(iTerm[e]);
  487. SERIAL_ECHO(" dTerm ");
  488. SERIAL_ECHOLN(dTerm[e]);
  489. #endif //PID_DEBUG
  490. #else /* PID off */
  491. pid_output = 0;
  492. if(current_temperature[e] < target_temperature[e]) {
  493. pid_output = PID_MAX;
  494. }
  495. #endif
  496. // Check if temperature is within the correct range
  497. if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
  498. {
  499. soft_pwm[e] = (int)pid_output >> 1;
  500. }
  501. else {
  502. soft_pwm[e] = 0;
  503. }
  504. #ifdef WATCH_TEMP_PERIOD
  505. if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD)
  506. {
  507. if(degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE)
  508. {
  509. setTargetHotend(0, e);
  510. LCD_MESSAGEPGM("Heating failed");
  511. SERIAL_ECHO_START;
  512. SERIAL_ECHOLN("Heating failed");
  513. }else{
  514. watchmillis[e] = 0;
  515. }
  516. }
  517. #endif
  518. #ifdef TEMP_SENSOR_1_AS_REDUNDANT
  519. if(fabs(current_temperature[0] - redundant_temperature) > MAX_REDUNDANT_TEMP_SENSOR_DIFF) {
  520. disable_heater();
  521. if(IsStopped() == false) {
  522. SERIAL_ERROR_START;
  523. SERIAL_ERRORLNPGM("Extruder switched off. Temperature difference between temp sensors is too high !");
  524. LCD_ALERTMESSAGEPGM("Err: REDUNDANT TEMP ERROR");
  525. }
  526. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  527. Stop();
  528. #endif
  529. }
  530. #endif
  531. } // End extruder for loop
  532. #if (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN > -1) || \
  533. (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN > -1) || \
  534. (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN > -1)
  535. if(millis() - extruder_autofan_last_check > 1000) // only need to check fan state very infrequently
  536. {
  537. countFanSpeed();
  538. checkFanSpeed();
  539. checkExtruderAutoFans();
  540. extruder_autofan_last_check = millis();
  541. }
  542. #endif
  543. #ifndef PIDTEMPBED
  544. if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
  545. return;
  546. previous_millis_bed_heater = millis();
  547. #endif
  548. #if TEMP_SENSOR_BED != 0
  549. #ifdef PIDTEMPBED
  550. pid_input = current_temperature_bed;
  551. #ifndef PID_OPENLOOP
  552. pid_error_bed = target_temperature_bed - pid_input;
  553. pTerm_bed = bedKp * pid_error_bed;
  554. temp_iState_bed += pid_error_bed;
  555. temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
  556. iTerm_bed = bedKi * temp_iState_bed;
  557. //K1 defined in Configuration.h in the PID settings
  558. #define K2 (1.0-K1)
  559. dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
  560. temp_dState_bed = pid_input;
  561. pid_output = pTerm_bed + iTerm_bed - dTerm_bed;
  562. if (pid_output > MAX_BED_POWER) {
  563. if (pid_error_bed > 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
  564. pid_output=MAX_BED_POWER;
  565. } else if (pid_output < 0){
  566. if (pid_error_bed < 0 ) temp_iState_bed -= pid_error_bed; // conditional un-integration
  567. pid_output=0;
  568. }
  569. #else
  570. pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
  571. #endif //PID_OPENLOOP
  572. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  573. {
  574. soft_pwm_bed = (int)pid_output >> 1;
  575. }
  576. else {
  577. soft_pwm_bed = 0;
  578. }
  579. #elif !defined(BED_LIMIT_SWITCHING)
  580. // Check if temperature is within the correct range
  581. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  582. {
  583. if(current_temperature_bed >= target_temperature_bed)
  584. {
  585. soft_pwm_bed = 0;
  586. }
  587. else
  588. {
  589. soft_pwm_bed = MAX_BED_POWER>>1;
  590. }
  591. }
  592. else
  593. {
  594. soft_pwm_bed = 0;
  595. WRITE(HEATER_BED_PIN,LOW);
  596. }
  597. #else //#ifdef BED_LIMIT_SWITCHING
  598. // Check if temperature is within the correct band
  599. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  600. {
  601. if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
  602. {
  603. soft_pwm_bed = 0;
  604. }
  605. else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
  606. {
  607. soft_pwm_bed = MAX_BED_POWER>>1;
  608. }
  609. }
  610. else
  611. {
  612. soft_pwm_bed = 0;
  613. WRITE(HEATER_BED_PIN,LOW);
  614. }
  615. #endif
  616. #endif
  617. //code for controlling the extruder rate based on the width sensor
  618. #ifdef FILAMENT_SENSOR
  619. if(filament_sensor)
  620. {
  621. meas_shift_index=delay_index1-meas_delay_cm;
  622. if(meas_shift_index<0)
  623. meas_shift_index = meas_shift_index + (MAX_MEASUREMENT_DELAY+1); //loop around buffer if needed
  624. //get the delayed info and add 100 to reconstitute to a percent of the nominal filament diameter
  625. //then square it to get an area
  626. if(meas_shift_index<0)
  627. meas_shift_index=0;
  628. else if (meas_shift_index>MAX_MEASUREMENT_DELAY)
  629. meas_shift_index=MAX_MEASUREMENT_DELAY;
  630. volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] = pow((float)(100+measurement_delay[meas_shift_index])/100.0,2);
  631. if (volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM] <0.01)
  632. volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]=0.01;
  633. }
  634. #endif
  635. }
  636. #define PGM_RD_W(x) (short)pgm_read_word(&x)
  637. // Derived from RepRap FiveD extruder::getTemperature()
  638. // For hot end temperature measurement.
  639. static float analog2temp(int raw, uint8_t e) {
  640. #ifdef TEMP_SENSOR_1_AS_REDUNDANT
  641. if(e > EXTRUDERS)
  642. #else
  643. if(e >= EXTRUDERS)
  644. #endif
  645. {
  646. SERIAL_ERROR_START;
  647. SERIAL_ERROR((int)e);
  648. SERIAL_ERRORLNPGM(" - Invalid extruder number !");
  649. kill();
  650. return 0.0;
  651. }
  652. #ifdef HEATER_0_USES_MAX6675
  653. if (e == 0)
  654. {
  655. return 0.25 * raw;
  656. }
  657. #endif
  658. if(heater_ttbl_map[e] != NULL)
  659. {
  660. float celsius = 0;
  661. uint8_t i;
  662. short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
  663. for (i=1; i<heater_ttbllen_map[e]; i++)
  664. {
  665. if (PGM_RD_W((*tt)[i][0]) > raw)
  666. {
  667. celsius = PGM_RD_W((*tt)[i-1][1]) +
  668. (raw - PGM_RD_W((*tt)[i-1][0])) *
  669. (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /
  670. (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0]));
  671. break;
  672. }
  673. }
  674. // Overflow: Set to last value in the table
  675. if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i-1][1]);
  676. return celsius;
  677. }
  678. return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
  679. }
  680. // Derived from RepRap FiveD extruder::getTemperature()
  681. // For bed temperature measurement.
  682. static float analog2tempBed(int raw) {
  683. #ifdef BED_USES_THERMISTOR
  684. float celsius = 0;
  685. byte i;
  686. for (i=1; i<BEDTEMPTABLE_LEN; i++)
  687. {
  688. if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw)
  689. {
  690. celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) +
  691. (raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) *
  692. (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) /
  693. (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i-1][0]));
  694. break;
  695. }
  696. }
  697. // Overflow: Set to last value in the table
  698. if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]);
  699. // temperature offset adjustment
  700. #ifdef BED_OFFSET
  701. float _offset = BED_OFFSET;
  702. float _offset_center = BED_OFFSET_CENTER;
  703. float _offset_start = BED_OFFSET_START;
  704. float _first_koef = (_offset / 2) / (_offset_center - _offset_start);
  705. float _second_koef = (_offset / 2) / (100 - _offset_center);
  706. if (celsius >= _offset_start && celsius <= _offset_center)
  707. {
  708. celsius = celsius + (_first_koef * (celsius - _offset_start));
  709. }
  710. else if (celsius > _offset_center && celsius <= 100)
  711. {
  712. celsius = celsius + (_first_koef * (_offset_center - _offset_start)) + ( _second_koef * ( celsius - ( 100 - _offset_center ) )) ;
  713. }
  714. else if (celsius > 100)
  715. {
  716. celsius = celsius + _offset;
  717. }
  718. #endif
  719. return celsius;
  720. #elif defined BED_USES_AD595
  721. return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
  722. #else
  723. return 0;
  724. #endif
  725. }
  726. /* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
  727. and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
  728. static void updateTemperaturesFromRawValues()
  729. {
  730. for(uint8_t e=0;e<EXTRUDERS;e++)
  731. {
  732. current_temperature[e] = analog2temp(current_temperature_raw[e], e);
  733. }
  734. current_temperature_bed = analog2tempBed(current_temperature_bed_raw);
  735. #ifdef TEMP_SENSOR_1_AS_REDUNDANT
  736. redundant_temperature = analog2temp(redundant_temperature_raw, 1);
  737. #endif
  738. #if defined (FILAMENT_SENSOR) && (FILWIDTH_PIN > -1) //check if a sensor is supported
  739. filament_width_meas = analog2widthFil();
  740. #endif
  741. //Reset the watchdog after we know we have a temperature measurement.
  742. watchdog_reset();
  743. CRITICAL_SECTION_START;
  744. temp_meas_ready = false;
  745. CRITICAL_SECTION_END;
  746. }
  747. // For converting raw Filament Width to milimeters
  748. #ifdef FILAMENT_SENSOR
  749. float analog2widthFil() {
  750. return current_raw_filwidth/16383.0*5.0;
  751. //return current_raw_filwidth;
  752. }
  753. // For converting raw Filament Width to a ratio
  754. int widthFil_to_size_ratio() {
  755. float temp;
  756. temp=filament_width_meas;
  757. if(filament_width_meas<MEASURED_LOWER_LIMIT)
  758. temp=filament_width_nominal; //assume sensor cut out
  759. else if (filament_width_meas>MEASURED_UPPER_LIMIT)
  760. temp= MEASURED_UPPER_LIMIT;
  761. return(filament_width_nominal/temp*100);
  762. }
  763. #endif
  764. void tp_init()
  765. {
  766. #if MB(RUMBA) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
  767. //disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
  768. MCUCR=(1<<JTD);
  769. MCUCR=(1<<JTD);
  770. #endif
  771. // Finish init of mult extruder arrays
  772. for(int e = 0; e < EXTRUDERS; e++) {
  773. // populate with the first value
  774. maxttemp[e] = maxttemp[0];
  775. #ifdef PIDTEMP
  776. temp_iState_min[e] = 0.0;
  777. temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
  778. #endif //PIDTEMP
  779. #ifdef PIDTEMPBED
  780. temp_iState_min_bed = 0.0;
  781. temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
  782. #endif //PIDTEMPBED
  783. }
  784. #if defined(HEATER_0_PIN) && (HEATER_0_PIN > -1)
  785. SET_OUTPUT(HEATER_0_PIN);
  786. #endif
  787. #if defined(HEATER_1_PIN) && (HEATER_1_PIN > -1)
  788. SET_OUTPUT(HEATER_1_PIN);
  789. #endif
  790. #if defined(HEATER_2_PIN) && (HEATER_2_PIN > -1)
  791. SET_OUTPUT(HEATER_2_PIN);
  792. #endif
  793. #if defined(HEATER_BED_PIN) && (HEATER_BED_PIN > -1)
  794. SET_OUTPUT(HEATER_BED_PIN);
  795. #endif
  796. #if defined(FAN_PIN) && (FAN_PIN > -1)
  797. SET_OUTPUT(FAN_PIN);
  798. #ifdef FAST_PWM_FAN
  799. setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  800. #endif
  801. #ifdef FAN_SOFT_PWM
  802. soft_pwm_fan = fanSpeedSoftPwm / 2;
  803. #endif
  804. #endif
  805. #ifdef HEATER_0_USES_MAX6675
  806. #ifndef SDSUPPORT
  807. SET_OUTPUT(SCK_PIN);
  808. WRITE(SCK_PIN,0);
  809. SET_OUTPUT(MOSI_PIN);
  810. WRITE(MOSI_PIN,1);
  811. SET_INPUT(MISO_PIN);
  812. WRITE(MISO_PIN,1);
  813. #endif
  814. /* Using pinMode and digitalWrite, as that was the only way I could get it to compile */
  815. //Have to toggle SD card CS pin to low first, to enable firmware to talk with SD card
  816. pinMode(SS_PIN, OUTPUT);
  817. digitalWrite(SS_PIN,0);
  818. pinMode(MAX6675_SS, OUTPUT);
  819. digitalWrite(MAX6675_SS,1);
  820. #endif
  821. // Set analog inputs
  822. ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
  823. DIDR0 = 0;
  824. #ifdef DIDR2
  825. DIDR2 = 0;
  826. #endif
  827. #if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
  828. #if TEMP_0_PIN < 8
  829. DIDR0 |= 1 << TEMP_0_PIN;
  830. #else
  831. DIDR2 |= 1<<(TEMP_0_PIN - 8);
  832. #endif
  833. #endif
  834. #if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
  835. #if TEMP_1_PIN < 8
  836. DIDR0 |= 1<<TEMP_1_PIN;
  837. #else
  838. DIDR2 |= 1<<(TEMP_1_PIN - 8);
  839. #endif
  840. #endif
  841. #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
  842. #if TEMP_2_PIN < 8
  843. DIDR0 |= 1 << TEMP_2_PIN;
  844. #else
  845. DIDR2 |= 1<<(TEMP_2_PIN - 8);
  846. #endif
  847. #endif
  848. #if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
  849. #if TEMP_BED_PIN < 8
  850. DIDR0 |= 1<<TEMP_BED_PIN;
  851. #else
  852. DIDR2 |= 1<<(TEMP_BED_PIN - 8);
  853. #endif
  854. #endif
  855. //Added for Filament Sensor
  856. #ifdef FILAMENT_SENSOR
  857. #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN > -1)
  858. #if FILWIDTH_PIN < 8
  859. DIDR0 |= 1<<FILWIDTH_PIN;
  860. #else
  861. DIDR2 |= 1<<(FILWIDTH_PIN - 8);
  862. #endif
  863. #endif
  864. #endif
  865. // Use timer0 for temperature measurement
  866. // Interleave temperature interrupt with millies interrupt
  867. OCR0B = 128;
  868. TIMSK0 |= (1<<OCIE0B);
  869. // Wait for temperature measurement to settle
  870. delay(250);
  871. #ifdef HEATER_0_MINTEMP
  872. minttemp[0] = HEATER_0_MINTEMP;
  873. while(analog2temp(minttemp_raw[0], 0) < HEATER_0_MINTEMP) {
  874. #if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
  875. minttemp_raw[0] += OVERSAMPLENR;
  876. #else
  877. minttemp_raw[0] -= OVERSAMPLENR;
  878. #endif
  879. }
  880. #endif //MINTEMP
  881. #ifdef HEATER_0_MAXTEMP
  882. maxttemp[0] = HEATER_0_MAXTEMP;
  883. while(analog2temp(maxttemp_raw[0], 0) > HEATER_0_MAXTEMP) {
  884. #if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
  885. maxttemp_raw[0] -= OVERSAMPLENR;
  886. #else
  887. maxttemp_raw[0] += OVERSAMPLENR;
  888. #endif
  889. }
  890. #endif //MAXTEMP
  891. #if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
  892. minttemp[1] = HEATER_1_MINTEMP;
  893. while(analog2temp(minttemp_raw[1], 1) < HEATER_1_MINTEMP) {
  894. #if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
  895. minttemp_raw[1] += OVERSAMPLENR;
  896. #else
  897. minttemp_raw[1] -= OVERSAMPLENR;
  898. #endif
  899. }
  900. #endif // MINTEMP 1
  901. #if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
  902. maxttemp[1] = HEATER_1_MAXTEMP;
  903. while(analog2temp(maxttemp_raw[1], 1) > HEATER_1_MAXTEMP) {
  904. #if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
  905. maxttemp_raw[1] -= OVERSAMPLENR;
  906. #else
  907. maxttemp_raw[1] += OVERSAMPLENR;
  908. #endif
  909. }
  910. #endif //MAXTEMP 1
  911. #if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
  912. minttemp[2] = HEATER_2_MINTEMP;
  913. while(analog2temp(minttemp_raw[2], 2) < HEATER_2_MINTEMP) {
  914. #if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
  915. minttemp_raw[2] += OVERSAMPLENR;
  916. #else
  917. minttemp_raw[2] -= OVERSAMPLENR;
  918. #endif
  919. }
  920. #endif //MINTEMP 2
  921. #if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
  922. maxttemp[2] = HEATER_2_MAXTEMP;
  923. while(analog2temp(maxttemp_raw[2], 2) > HEATER_2_MAXTEMP) {
  924. #if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
  925. maxttemp_raw[2] -= OVERSAMPLENR;
  926. #else
  927. maxttemp_raw[2] += OVERSAMPLENR;
  928. #endif
  929. }
  930. #endif //MAXTEMP 2
  931. #ifdef BED_MINTEMP
  932. /* No bed MINTEMP error implemented?!? */
  933. while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
  934. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  935. bed_minttemp_raw += OVERSAMPLENR;
  936. #else
  937. bed_minttemp_raw -= OVERSAMPLENR;
  938. #endif
  939. }
  940. #endif //BED_MINTEMP
  941. #ifdef BED_MAXTEMP
  942. while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) {
  943. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  944. bed_maxttemp_raw -= OVERSAMPLENR;
  945. #else
  946. bed_maxttemp_raw += OVERSAMPLENR;
  947. #endif
  948. }
  949. #endif //BED_MAXTEMP
  950. }
  951. void setWatch()
  952. {
  953. #ifdef WATCH_TEMP_PERIOD
  954. for (int e = 0; e < EXTRUDERS; e++)
  955. {
  956. if(degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2))
  957. {
  958. watch_start_temp[e] = degHotend(e);
  959. watchmillis[e] = millis();
  960. }
  961. }
  962. #endif
  963. }
  964. #if (defined (TEMP_RUNAWAY_BED_HYSTERESIS) && TEMP_RUNAWAY_BED_TIMEOUT > 0) || (defined (TEMP_RUNAWAY_EXTRUDER_HYSTERESIS) && TEMP_RUNAWAY_EXTRUDER_TIMEOUT > 0)
  965. void temp_runaway_check(int _heater_id, float _target_temperature, float _current_temperature, float _output, bool _isbed)
  966. {
  967. float __hysteresis = 0;
  968. int __timeout = 0;
  969. bool temp_runaway_check_active = false;
  970. static float __preheat_start = 0;
  971. static int __preheat_counter = 0;
  972. static int __preheat_errors = 0;
  973. _heater_id = (_isbed) ? _heater_id++ : _heater_id;
  974. #ifdef TEMP_RUNAWAY_BED_TIMEOUT
  975. if (_isbed)
  976. {
  977. __hysteresis = TEMP_RUNAWAY_BED_HYSTERESIS;
  978. __timeout = TEMP_RUNAWAY_BED_TIMEOUT;
  979. }
  980. #endif
  981. #ifdef TEMP_RUNAWAY_EXTRUDER_TIMEOUT
  982. if (!_isbed)
  983. {
  984. __hysteresis = TEMP_RUNAWAY_EXTRUDER_HYSTERESIS;
  985. __timeout = TEMP_RUNAWAY_EXTRUDER_TIMEOUT;
  986. }
  987. #endif
  988. if (millis() - temp_runaway_timer[_heater_id] > 2000)
  989. {
  990. temp_runaway_timer[_heater_id] = millis();
  991. if (_output == 0)
  992. {
  993. temp_runaway_check_active = false;
  994. temp_runaway_error_counter[_heater_id] = 0;
  995. }
  996. if (temp_runaway_target[_heater_id] != _target_temperature)
  997. {
  998. if (_target_temperature > 0)
  999. {
  1000. temp_runaway_status[_heater_id] = TempRunaway_PREHEAT;
  1001. temp_runaway_target[_heater_id] = _target_temperature;
  1002. __preheat_start = _current_temperature;
  1003. __preheat_counter = 0;
  1004. }
  1005. else
  1006. {
  1007. temp_runaway_status[_heater_id] = TempRunaway_INACTIVE;
  1008. temp_runaway_target[_heater_id] = _target_temperature;
  1009. }
  1010. }
  1011. if (temp_runaway_status[_heater_id] == TempRunaway_PREHEAT)
  1012. {
  1013. if (_current_temperature < 150)
  1014. {
  1015. __preheat_counter++;
  1016. if (__preheat_counter > 8)
  1017. {
  1018. if (_current_temperature - __preheat_start < 2) {
  1019. __preheat_errors++;
  1020. }
  1021. else {
  1022. __preheat_errors = 0;
  1023. }
  1024. if (__preheat_errors > 5)
  1025. {
  1026. if (farm_mode) { prusa_statistics(0); }
  1027. temp_runaway_stop(true);
  1028. if (farm_mode) { prusa_statistics(91); }
  1029. }
  1030. __preheat_start = _current_temperature;
  1031. __preheat_counter = 0;
  1032. }
  1033. }
  1034. }
  1035. if (_current_temperature >= _target_temperature && temp_runaway_status[_heater_id] == TempRunaway_PREHEAT)
  1036. {
  1037. temp_runaway_status[_heater_id] = TempRunaway_ACTIVE;
  1038. temp_runaway_check_active = false;
  1039. }
  1040. if (!temp_runaway_check_active && _output > 0)
  1041. {
  1042. temp_runaway_check_active = true;
  1043. }
  1044. if (temp_runaway_check_active)
  1045. {
  1046. // we are in range
  1047. if (_target_temperature - __hysteresis < _current_temperature && _current_temperature < _target_temperature + __hysteresis)
  1048. {
  1049. temp_runaway_check_active = false;
  1050. temp_runaway_error_counter[_heater_id] = 0;
  1051. }
  1052. else
  1053. {
  1054. if (temp_runaway_status[_heater_id] > TempRunaway_PREHEAT)
  1055. {
  1056. temp_runaway_error_counter[_heater_id]++;
  1057. if (temp_runaway_error_counter[_heater_id] * 2 > __timeout)
  1058. {
  1059. if (farm_mode) { prusa_statistics(0); }
  1060. temp_runaway_stop(false);
  1061. if (farm_mode) { prusa_statistics(90); }
  1062. }
  1063. }
  1064. }
  1065. }
  1066. }
  1067. }
  1068. void temp_runaway_stop(bool isPreheat)
  1069. {
  1070. cancel_heatup = true;
  1071. quickStop();
  1072. if (card.sdprinting)
  1073. {
  1074. card.sdprinting = false;
  1075. card.closefile();
  1076. }
  1077. disable_heater();
  1078. disable_x();
  1079. disable_y();
  1080. disable_e0();
  1081. disable_e1();
  1082. disable_e2();
  1083. manage_heater();
  1084. lcd_update();
  1085. WRITE(BEEPER, HIGH);
  1086. delayMicroseconds(500);
  1087. WRITE(BEEPER, LOW);
  1088. delayMicroseconds(100);
  1089. if (isPreheat)
  1090. {
  1091. Stop();
  1092. LCD_ALERTMESSAGEPGM(" PREHEAT ERROR");
  1093. SERIAL_ERROR_START;
  1094. SERIAL_ERRORLNPGM(": THERMAL RUNAWAY ( PREHEAT )");
  1095. SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
  1096. SET_OUTPUT(FAN_PIN);
  1097. WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
  1098. analogWrite(FAN_PIN, 255);
  1099. fanSpeed = 255;
  1100. delayMicroseconds(2000);
  1101. }
  1102. else
  1103. {
  1104. LCD_ALERTMESSAGEPGM("THERMAL RUNAWAY");
  1105. SERIAL_ERROR_START;
  1106. SERIAL_ERRORLNPGM(": THERMAL RUNAWAY");
  1107. }
  1108. }
  1109. #endif
  1110. void disable_heater()
  1111. {
  1112. for(int i=0;i<EXTRUDERS;i++)
  1113. setTargetHotend(0,i);
  1114. setTargetBed(0);
  1115. #if defined(TEMP_0_PIN) && TEMP_0_PIN > -1
  1116. target_temperature[0]=0;
  1117. soft_pwm[0]=0;
  1118. #if defined(HEATER_0_PIN) && HEATER_0_PIN > -1
  1119. WRITE(HEATER_0_PIN,LOW);
  1120. #endif
  1121. #endif
  1122. #if defined(TEMP_1_PIN) && TEMP_1_PIN > -1 && EXTRUDERS > 1
  1123. target_temperature[1]=0;
  1124. soft_pwm[1]=0;
  1125. #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1
  1126. WRITE(HEATER_1_PIN,LOW);
  1127. #endif
  1128. #endif
  1129. #if defined(TEMP_2_PIN) && TEMP_2_PIN > -1 && EXTRUDERS > 2
  1130. target_temperature[2]=0;
  1131. soft_pwm[2]=0;
  1132. #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1
  1133. WRITE(HEATER_2_PIN,LOW);
  1134. #endif
  1135. #endif
  1136. #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
  1137. target_temperature_bed=0;
  1138. soft_pwm_bed=0;
  1139. #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
  1140. WRITE(HEATER_BED_PIN,LOW);
  1141. #endif
  1142. #endif
  1143. }
  1144. void max_temp_error(uint8_t e) {
  1145. disable_heater();
  1146. if(IsStopped() == false) {
  1147. SERIAL_ERROR_START;
  1148. SERIAL_ERRORLN((int)e);
  1149. SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !");
  1150. LCD_ALERTMESSAGEPGM("Err: MAXTEMP");
  1151. }
  1152. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  1153. Stop();
  1154. #endif
  1155. SET_OUTPUT(EXTRUDER_0_AUTO_FAN_PIN);
  1156. SET_OUTPUT(FAN_PIN);
  1157. SET_OUTPUT(BEEPER);
  1158. WRITE(FAN_PIN, 1);
  1159. WRITE(EXTRUDER_0_AUTO_FAN_PIN, 1);
  1160. WRITE(BEEPER, 1);
  1161. // fanSpeed will consumed by the check_axes_activity() routine.
  1162. fanSpeed=255;
  1163. if (farm_mode) { prusa_statistics(93); }
  1164. }
  1165. void min_temp_error(uint8_t e) {
  1166. disable_heater();
  1167. if(IsStopped() == false) {
  1168. SERIAL_ERROR_START;
  1169. SERIAL_ERRORLN((int)e);
  1170. SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !");
  1171. LCD_ALERTMESSAGEPGM("Err: MINTEMP");
  1172. }
  1173. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  1174. Stop();
  1175. #endif
  1176. if (farm_mode) { prusa_statistics(92); }
  1177. }
  1178. void bed_max_temp_error(void) {
  1179. #if HEATER_BED_PIN > -1
  1180. WRITE(HEATER_BED_PIN, 0);
  1181. #endif
  1182. if(IsStopped() == false) {
  1183. SERIAL_ERROR_START;
  1184. SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !");
  1185. LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED");
  1186. }
  1187. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  1188. Stop();
  1189. #endif
  1190. }
  1191. void bed_min_temp_error(void) {
  1192. #if HEATER_BED_PIN > -1
  1193. WRITE(HEATER_BED_PIN, 0);
  1194. #endif
  1195. if(IsStopped() == false) {
  1196. SERIAL_ERROR_START;
  1197. SERIAL_ERRORLNPGM("Temperature heated bed switched off. MINTEMP triggered !");
  1198. LCD_ALERTMESSAGEPGM("Err: MINTEMP BED");
  1199. }
  1200. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  1201. Stop();
  1202. #endif
  1203. }
  1204. #ifdef HEATER_0_USES_MAX6675
  1205. #define MAX6675_HEAT_INTERVAL 250
  1206. long max6675_previous_millis = MAX6675_HEAT_INTERVAL;
  1207. int max6675_temp = 2000;
  1208. int read_max6675()
  1209. {
  1210. if (millis() - max6675_previous_millis < MAX6675_HEAT_INTERVAL)
  1211. return max6675_temp;
  1212. max6675_previous_millis = millis();
  1213. max6675_temp = 0;
  1214. #ifdef PRR
  1215. PRR &= ~(1<<PRSPI);
  1216. #elif defined PRR0
  1217. PRR0 &= ~(1<<PRSPI);
  1218. #endif
  1219. SPCR = (1<<MSTR) | (1<<SPE) | (1<<SPR0);
  1220. // enable TT_MAX6675
  1221. WRITE(MAX6675_SS, 0);
  1222. // ensure 100ns delay - a bit extra is fine
  1223. asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
  1224. asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
  1225. // read MSB
  1226. SPDR = 0;
  1227. for (;(SPSR & (1<<SPIF)) == 0;);
  1228. max6675_temp = SPDR;
  1229. max6675_temp <<= 8;
  1230. // read LSB
  1231. SPDR = 0;
  1232. for (;(SPSR & (1<<SPIF)) == 0;);
  1233. max6675_temp |= SPDR;
  1234. // disable TT_MAX6675
  1235. WRITE(MAX6675_SS, 1);
  1236. if (max6675_temp & 4)
  1237. {
  1238. // thermocouple open
  1239. max6675_temp = 2000;
  1240. }
  1241. else
  1242. {
  1243. max6675_temp = max6675_temp >> 3;
  1244. }
  1245. return max6675_temp;
  1246. }
  1247. #endif
  1248. // Timer 0 is shared with millies
  1249. ISR(TIMER0_COMPB_vect)
  1250. {
  1251. //these variables are only accesible from the ISR, but static, so they don't lose their value
  1252. static unsigned char temp_count = 0;
  1253. static unsigned long raw_temp_0_value = 0;
  1254. static unsigned long raw_temp_1_value = 0;
  1255. static unsigned long raw_temp_2_value = 0;
  1256. static unsigned long raw_temp_bed_value = 0;
  1257. static unsigned char temp_state = 10;
  1258. static unsigned char pwm_count = (1 << SOFT_PWM_SCALE);
  1259. static unsigned char soft_pwm_0;
  1260. #ifdef SLOW_PWM_HEATERS
  1261. static unsigned char slow_pwm_count = 0;
  1262. static unsigned char state_heater_0 = 0;
  1263. static unsigned char state_timer_heater_0 = 0;
  1264. #endif
  1265. #if (EXTRUDERS > 1) || defined(HEATERS_PARALLEL)
  1266. static unsigned char soft_pwm_1;
  1267. #ifdef SLOW_PWM_HEATERS
  1268. static unsigned char state_heater_1 = 0;
  1269. static unsigned char state_timer_heater_1 = 0;
  1270. #endif
  1271. #endif
  1272. #if EXTRUDERS > 2
  1273. static unsigned char soft_pwm_2;
  1274. #ifdef SLOW_PWM_HEATERS
  1275. static unsigned char state_heater_2 = 0;
  1276. static unsigned char state_timer_heater_2 = 0;
  1277. #endif
  1278. #endif
  1279. #if HEATER_BED_PIN > -1
  1280. static unsigned char soft_pwm_b;
  1281. #ifdef SLOW_PWM_HEATERS
  1282. static unsigned char state_heater_b = 0;
  1283. static unsigned char state_timer_heater_b = 0;
  1284. #endif
  1285. #endif
  1286. #if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
  1287. static unsigned long raw_filwidth_value = 0; //added for filament width sensor
  1288. #endif
  1289. #ifndef SLOW_PWM_HEATERS
  1290. /*
  1291. * standard PWM modulation
  1292. */
  1293. if(pwm_count == 0){
  1294. soft_pwm_0 = soft_pwm[0];
  1295. if(soft_pwm_0 > 0) {
  1296. WRITE(HEATER_0_PIN,1);
  1297. #ifdef HEATERS_PARALLEL
  1298. WRITE(HEATER_1_PIN,1);
  1299. #endif
  1300. } else WRITE(HEATER_0_PIN,0);
  1301. #if EXTRUDERS > 1
  1302. soft_pwm_1 = soft_pwm[1];
  1303. if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1); else WRITE(HEATER_1_PIN,0);
  1304. #endif
  1305. #if EXTRUDERS > 2
  1306. soft_pwm_2 = soft_pwm[2];
  1307. if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1); else WRITE(HEATER_2_PIN,0);
  1308. #endif
  1309. #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
  1310. soft_pwm_b = soft_pwm_bed;
  1311. if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1); else WRITE(HEATER_BED_PIN,0);
  1312. #endif
  1313. #ifdef FAN_SOFT_PWM
  1314. soft_pwm_fan = fanSpeedSoftPwm / 2;
  1315. if(soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
  1316. #endif
  1317. }
  1318. if(soft_pwm_0 < pwm_count) {
  1319. WRITE(HEATER_0_PIN,0);
  1320. #ifdef HEATERS_PARALLEL
  1321. WRITE(HEATER_1_PIN,0);
  1322. #endif
  1323. }
  1324. #if EXTRUDERS > 1
  1325. if(soft_pwm_1 < pwm_count) WRITE(HEATER_1_PIN,0);
  1326. #endif
  1327. #if EXTRUDERS > 2
  1328. if(soft_pwm_2 < pwm_count) WRITE(HEATER_2_PIN,0);
  1329. #endif
  1330. #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
  1331. if(soft_pwm_b < pwm_count) WRITE(HEATER_BED_PIN,0);
  1332. #endif
  1333. #ifdef FAN_SOFT_PWM
  1334. if(soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
  1335. #endif
  1336. pwm_count += (1 << SOFT_PWM_SCALE);
  1337. pwm_count &= 0x7f;
  1338. #else //ifndef SLOW_PWM_HEATERS
  1339. /*
  1340. * SLOW PWM HEATERS
  1341. *
  1342. * for heaters drived by relay
  1343. */
  1344. #ifndef MIN_STATE_TIME
  1345. #define MIN_STATE_TIME 16 // MIN_STATE_TIME * 65.5 = time in milliseconds
  1346. #endif
  1347. if (slow_pwm_count == 0) {
  1348. // EXTRUDER 0
  1349. soft_pwm_0 = soft_pwm[0];
  1350. if (soft_pwm_0 > 0) {
  1351. // turn ON heather only if the minimum time is up
  1352. if (state_timer_heater_0 == 0) {
  1353. // if change state set timer
  1354. if (state_heater_0 == 0) {
  1355. state_timer_heater_0 = MIN_STATE_TIME;
  1356. }
  1357. state_heater_0 = 1;
  1358. WRITE(HEATER_0_PIN, 1);
  1359. #ifdef HEATERS_PARALLEL
  1360. WRITE(HEATER_1_PIN, 1);
  1361. #endif
  1362. }
  1363. } else {
  1364. // turn OFF heather only if the minimum time is up
  1365. if (state_timer_heater_0 == 0) {
  1366. // if change state set timer
  1367. if (state_heater_0 == 1) {
  1368. state_timer_heater_0 = MIN_STATE_TIME;
  1369. }
  1370. state_heater_0 = 0;
  1371. WRITE(HEATER_0_PIN, 0);
  1372. #ifdef HEATERS_PARALLEL
  1373. WRITE(HEATER_1_PIN, 0);
  1374. #endif
  1375. }
  1376. }
  1377. #if EXTRUDERS > 1
  1378. // EXTRUDER 1
  1379. soft_pwm_1 = soft_pwm[1];
  1380. if (soft_pwm_1 > 0) {
  1381. // turn ON heather only if the minimum time is up
  1382. if (state_timer_heater_1 == 0) {
  1383. // if change state set timer
  1384. if (state_heater_1 == 0) {
  1385. state_timer_heater_1 = MIN_STATE_TIME;
  1386. }
  1387. state_heater_1 = 1;
  1388. WRITE(HEATER_1_PIN, 1);
  1389. }
  1390. } else {
  1391. // turn OFF heather only if the minimum time is up
  1392. if (state_timer_heater_1 == 0) {
  1393. // if change state set timer
  1394. if (state_heater_1 == 1) {
  1395. state_timer_heater_1 = MIN_STATE_TIME;
  1396. }
  1397. state_heater_1 = 0;
  1398. WRITE(HEATER_1_PIN, 0);
  1399. }
  1400. }
  1401. #endif
  1402. #if EXTRUDERS > 2
  1403. // EXTRUDER 2
  1404. soft_pwm_2 = soft_pwm[2];
  1405. if (soft_pwm_2 > 0) {
  1406. // turn ON heather only if the minimum time is up
  1407. if (state_timer_heater_2 == 0) {
  1408. // if change state set timer
  1409. if (state_heater_2 == 0) {
  1410. state_timer_heater_2 = MIN_STATE_TIME;
  1411. }
  1412. state_heater_2 = 1;
  1413. WRITE(HEATER_2_PIN, 1);
  1414. }
  1415. } else {
  1416. // turn OFF heather only if the minimum time is up
  1417. if (state_timer_heater_2 == 0) {
  1418. // if change state set timer
  1419. if (state_heater_2 == 1) {
  1420. state_timer_heater_2 = MIN_STATE_TIME;
  1421. }
  1422. state_heater_2 = 0;
  1423. WRITE(HEATER_2_PIN, 0);
  1424. }
  1425. }
  1426. #endif
  1427. #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
  1428. // BED
  1429. soft_pwm_b = soft_pwm_bed;
  1430. if (soft_pwm_b > 0) {
  1431. // turn ON heather only if the minimum time is up
  1432. if (state_timer_heater_b == 0) {
  1433. // if change state set timer
  1434. if (state_heater_b == 0) {
  1435. state_timer_heater_b = MIN_STATE_TIME;
  1436. }
  1437. state_heater_b = 1;
  1438. WRITE(HEATER_BED_PIN, 1);
  1439. }
  1440. } else {
  1441. // turn OFF heather only if the minimum time is up
  1442. if (state_timer_heater_b == 0) {
  1443. // if change state set timer
  1444. if (state_heater_b == 1) {
  1445. state_timer_heater_b = MIN_STATE_TIME;
  1446. }
  1447. state_heater_b = 0;
  1448. WRITE(HEATER_BED_PIN, 0);
  1449. }
  1450. }
  1451. #endif
  1452. } // if (slow_pwm_count == 0)
  1453. // EXTRUDER 0
  1454. if (soft_pwm_0 < slow_pwm_count) {
  1455. // turn OFF heather only if the minimum time is up
  1456. if (state_timer_heater_0 == 0) {
  1457. // if change state set timer
  1458. if (state_heater_0 == 1) {
  1459. state_timer_heater_0 = MIN_STATE_TIME;
  1460. }
  1461. state_heater_0 = 0;
  1462. WRITE(HEATER_0_PIN, 0);
  1463. #ifdef HEATERS_PARALLEL
  1464. WRITE(HEATER_1_PIN, 0);
  1465. #endif
  1466. }
  1467. }
  1468. #if EXTRUDERS > 1
  1469. // EXTRUDER 1
  1470. if (soft_pwm_1 < slow_pwm_count) {
  1471. // turn OFF heather only if the minimum time is up
  1472. if (state_timer_heater_1 == 0) {
  1473. // if change state set timer
  1474. if (state_heater_1 == 1) {
  1475. state_timer_heater_1 = MIN_STATE_TIME;
  1476. }
  1477. state_heater_1 = 0;
  1478. WRITE(HEATER_1_PIN, 0);
  1479. }
  1480. }
  1481. #endif
  1482. #if EXTRUDERS > 2
  1483. // EXTRUDER 2
  1484. if (soft_pwm_2 < slow_pwm_count) {
  1485. // turn OFF heather only if the minimum time is up
  1486. if (state_timer_heater_2 == 0) {
  1487. // if change state set timer
  1488. if (state_heater_2 == 1) {
  1489. state_timer_heater_2 = MIN_STATE_TIME;
  1490. }
  1491. state_heater_2 = 0;
  1492. WRITE(HEATER_2_PIN, 0);
  1493. }
  1494. }
  1495. #endif
  1496. #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
  1497. // BED
  1498. if (soft_pwm_b < slow_pwm_count) {
  1499. // turn OFF heather only if the minimum time is up
  1500. if (state_timer_heater_b == 0) {
  1501. // if change state set timer
  1502. if (state_heater_b == 1) {
  1503. state_timer_heater_b = MIN_STATE_TIME;
  1504. }
  1505. state_heater_b = 0;
  1506. WRITE(HEATER_BED_PIN, 0);
  1507. }
  1508. }
  1509. #endif
  1510. #ifdef FAN_SOFT_PWM
  1511. if (pwm_count == 0){
  1512. soft_pwm_fan = fanSpeedSoftPwm / 2;
  1513. if (soft_pwm_fan > 0) WRITE(FAN_PIN,1); else WRITE(FAN_PIN,0);
  1514. }
  1515. if (soft_pwm_fan < pwm_count) WRITE(FAN_PIN,0);
  1516. #endif
  1517. pwm_count += (1 << SOFT_PWM_SCALE);
  1518. pwm_count &= 0x7f;
  1519. // increment slow_pwm_count only every 64 pwm_count circa 65.5ms
  1520. if ((pwm_count % 64) == 0) {
  1521. slow_pwm_count++;
  1522. slow_pwm_count &= 0x7f;
  1523. // Extruder 0
  1524. if (state_timer_heater_0 > 0) {
  1525. state_timer_heater_0--;
  1526. }
  1527. #if EXTRUDERS > 1
  1528. // Extruder 1
  1529. if (state_timer_heater_1 > 0)
  1530. state_timer_heater_1--;
  1531. #endif
  1532. #if EXTRUDERS > 2
  1533. // Extruder 2
  1534. if (state_timer_heater_2 > 0)
  1535. state_timer_heater_2--;
  1536. #endif
  1537. #if defined(HEATER_BED_PIN) && HEATER_BED_PIN > -1
  1538. // Bed
  1539. if (state_timer_heater_b > 0)
  1540. state_timer_heater_b--;
  1541. #endif
  1542. } //if ((pwm_count % 64) == 0) {
  1543. #endif //ifndef SLOW_PWM_HEATERS
  1544. switch(temp_state) {
  1545. case 0: // Prepare TEMP_0
  1546. #if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
  1547. #if TEMP_0_PIN > 7
  1548. ADCSRB = 1<<MUX5;
  1549. #else
  1550. ADCSRB = 0;
  1551. #endif
  1552. ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
  1553. ADCSRA |= 1<<ADSC; // Start conversion
  1554. #endif
  1555. lcd_buttons_update();
  1556. temp_state = 1;
  1557. break;
  1558. case 1: // Measure TEMP_0
  1559. #if defined(TEMP_0_PIN) && (TEMP_0_PIN > -1)
  1560. raw_temp_0_value += ADC;
  1561. #endif
  1562. #ifdef HEATER_0_USES_MAX6675 // TODO remove the blocking
  1563. raw_temp_0_value = read_max6675();
  1564. #endif
  1565. temp_state = 2;
  1566. break;
  1567. case 2: // Prepare TEMP_BED
  1568. #if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
  1569. #if TEMP_BED_PIN > 7
  1570. ADCSRB = 1<<MUX5;
  1571. #else
  1572. ADCSRB = 0;
  1573. #endif
  1574. ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
  1575. ADCSRA |= 1<<ADSC; // Start conversion
  1576. #endif
  1577. lcd_buttons_update();
  1578. temp_state = 3;
  1579. break;
  1580. case 3: // Measure TEMP_BED
  1581. #if defined(TEMP_BED_PIN) && (TEMP_BED_PIN > -1)
  1582. raw_temp_bed_value += ADC;
  1583. #endif
  1584. temp_state = 4;
  1585. break;
  1586. case 4: // Prepare TEMP_1
  1587. #if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
  1588. #if TEMP_1_PIN > 7
  1589. ADCSRB = 1<<MUX5;
  1590. #else
  1591. ADCSRB = 0;
  1592. #endif
  1593. ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
  1594. ADCSRA |= 1<<ADSC; // Start conversion
  1595. #endif
  1596. lcd_buttons_update();
  1597. temp_state = 5;
  1598. break;
  1599. case 5: // Measure TEMP_1
  1600. #if defined(TEMP_1_PIN) && (TEMP_1_PIN > -1)
  1601. raw_temp_1_value += ADC;
  1602. #endif
  1603. temp_state = 6;
  1604. break;
  1605. case 6: // Prepare TEMP_2
  1606. #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
  1607. #if TEMP_2_PIN > 7
  1608. ADCSRB = 1<<MUX5;
  1609. #else
  1610. ADCSRB = 0;
  1611. #endif
  1612. ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
  1613. ADCSRA |= 1<<ADSC; // Start conversion
  1614. #endif
  1615. lcd_buttons_update();
  1616. temp_state = 7;
  1617. break;
  1618. case 7: // Measure TEMP_2
  1619. #if defined(TEMP_2_PIN) && (TEMP_2_PIN > -1)
  1620. raw_temp_2_value += ADC;
  1621. #endif
  1622. temp_state = 8;//change so that Filament Width is also measured
  1623. break;
  1624. case 8: //Prepare FILWIDTH
  1625. #if defined(FILWIDTH_PIN) && (FILWIDTH_PIN> -1)
  1626. #if FILWIDTH_PIN>7
  1627. ADCSRB = 1<<MUX5;
  1628. #else
  1629. ADCSRB = 0;
  1630. #endif
  1631. ADMUX = ((1 << REFS0) | (FILWIDTH_PIN & 0x07));
  1632. ADCSRA |= 1<<ADSC; // Start conversion
  1633. #endif
  1634. lcd_buttons_update();
  1635. temp_state = 9;
  1636. break;
  1637. case 9: //Measure FILWIDTH
  1638. #if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
  1639. //raw_filwidth_value += ADC; //remove to use an IIR filter approach
  1640. if(ADC>102) //check that ADC is reading a voltage > 0.5 volts, otherwise don't take in the data.
  1641. {
  1642. raw_filwidth_value= raw_filwidth_value-(raw_filwidth_value>>7); //multipliy raw_filwidth_value by 127/128
  1643. raw_filwidth_value= raw_filwidth_value + ((unsigned long)ADC<<7); //add new ADC reading
  1644. }
  1645. #endif
  1646. temp_state = 0;
  1647. temp_count++;
  1648. break;
  1649. case 10: //Startup, delay initial temp reading a tiny bit so the hardware can settle.
  1650. temp_state = 0;
  1651. break;
  1652. // default:
  1653. // SERIAL_ERROR_START;
  1654. // SERIAL_ERRORLNPGM("Temp measurement error!");
  1655. // break;
  1656. }
  1657. if(temp_count >= OVERSAMPLENR) // 10 * 16 * 1/(16000000/64/256) = 164ms.
  1658. {
  1659. if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
  1660. {
  1661. current_temperature_raw[0] = raw_temp_0_value;
  1662. #if EXTRUDERS > 1
  1663. current_temperature_raw[1] = raw_temp_1_value;
  1664. #endif
  1665. #ifdef TEMP_SENSOR_1_AS_REDUNDANT
  1666. redundant_temperature_raw = raw_temp_1_value;
  1667. #endif
  1668. #if EXTRUDERS > 2
  1669. current_temperature_raw[2] = raw_temp_2_value;
  1670. #endif
  1671. current_temperature_bed_raw = raw_temp_bed_value;
  1672. }
  1673. //Add similar code for Filament Sensor - can be read any time since IIR filtering is used
  1674. #if defined(FILWIDTH_PIN) &&(FILWIDTH_PIN > -1)
  1675. current_raw_filwidth = raw_filwidth_value>>10; //need to divide to get to 0-16384 range since we used 1/128 IIR filter approach
  1676. #endif
  1677. temp_meas_ready = true;
  1678. temp_count = 0;
  1679. raw_temp_0_value = 0;
  1680. raw_temp_1_value = 0;
  1681. raw_temp_2_value = 0;
  1682. raw_temp_bed_value = 0;
  1683. #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
  1684. if(current_temperature_raw[0] <= maxttemp_raw[0]) {
  1685. #else
  1686. if(current_temperature_raw[0] >= maxttemp_raw[0]) {
  1687. #endif
  1688. max_temp_error(0);
  1689. }
  1690. #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
  1691. if(current_temperature_raw[0] >= minttemp_raw[0]) {
  1692. #else
  1693. if(current_temperature_raw[0] <= minttemp_raw[0]) {
  1694. #endif
  1695. min_temp_error(0);
  1696. }
  1697. #if EXTRUDERS > 1
  1698. #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
  1699. if(current_temperature_raw[1] <= maxttemp_raw[1]) {
  1700. #else
  1701. if(current_temperature_raw[1] >= maxttemp_raw[1]) {
  1702. #endif
  1703. max_temp_error(1);
  1704. }
  1705. #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
  1706. if(current_temperature_raw[1] >= minttemp_raw[1]) {
  1707. #else
  1708. if(current_temperature_raw[1] <= minttemp_raw[1]) {
  1709. #endif
  1710. min_temp_error(1);
  1711. }
  1712. #endif
  1713. #if EXTRUDERS > 2
  1714. #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
  1715. if(current_temperature_raw[2] <= maxttemp_raw[2]) {
  1716. #else
  1717. if(current_temperature_raw[2] >= maxttemp_raw[2]) {
  1718. #endif
  1719. max_temp_error(2);
  1720. }
  1721. #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
  1722. if(current_temperature_raw[2] >= minttemp_raw[2]) {
  1723. #else
  1724. if(current_temperature_raw[2] <= minttemp_raw[2]) {
  1725. #endif
  1726. min_temp_error(2);
  1727. }
  1728. #endif
  1729. /* No bed MINTEMP error? */
  1730. #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
  1731. # if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
  1732. if(current_temperature_bed_raw <= bed_maxttemp_raw) {
  1733. #else
  1734. if(current_temperature_bed_raw >= bed_maxttemp_raw) {
  1735. #endif
  1736. target_temperature_bed = 0;
  1737. bed_max_temp_error();
  1738. }
  1739. }
  1740. # if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
  1741. if(current_temperature_bed_raw >= bed_minttemp_raw) {
  1742. #else
  1743. if(current_temperature_bed_raw <= bed_minttemp_raw) {
  1744. #endif
  1745. bed_min_temp_error();
  1746. }
  1747. #endif
  1748. #ifdef BABYSTEPPING
  1749. for(uint8_t axis=0;axis<3;axis++)
  1750. {
  1751. int curTodo=babystepsTodo[axis]; //get rid of volatile for performance
  1752. if(curTodo>0)
  1753. {
  1754. babystep(axis,/*fwd*/true);
  1755. babystepsTodo[axis]--; //less to do next time
  1756. }
  1757. else
  1758. if(curTodo<0)
  1759. {
  1760. babystep(axis,/*fwd*/false);
  1761. babystepsTodo[axis]++; //less to do next time
  1762. }
  1763. }
  1764. #endif //BABYSTEPPING
  1765. }
  1766. #ifdef PIDTEMP
  1767. // Apply the scale factors to the PID values
  1768. float scalePID_i(float i)
  1769. {
  1770. return i*PID_dT;
  1771. }
  1772. float unscalePID_i(float i)
  1773. {
  1774. return i/PID_dT;
  1775. }
  1776. float scalePID_d(float d)
  1777. {
  1778. return d/PID_dT;
  1779. }
  1780. float unscalePID_d(float d)
  1781. {
  1782. return d*PID_dT;
  1783. }
  1784. #endif //PIDTEMP