My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

temperature.cpp 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  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. //===========================================================================
  28. //=============================public variables============================
  29. //===========================================================================
  30. int target_temperature[EXTRUDERS] = { 0 };
  31. int target_temperature_bed = 0;
  32. int current_temperature_raw[EXTRUDERS] = { 0 };
  33. float current_temperature[EXTRUDERS] = { 0 };
  34. int current_temperature_bed_raw = 0;
  35. float current_temperature_bed = 0;
  36. #ifdef PIDTEMP
  37. float Kp=DEFAULT_Kp;
  38. float Ki=(DEFAULT_Ki*PID_dT);
  39. float Kd=(DEFAULT_Kd/PID_dT);
  40. #ifdef PID_ADD_EXTRUSION_RATE
  41. float Kc=DEFAULT_Kc;
  42. #endif
  43. #endif //PIDTEMP
  44. #ifdef PIDTEMPBED
  45. float bedKp=DEFAULT_bedKp;
  46. float bedKi=(DEFAULT_bedKi*PID_dT);
  47. float bedKd=(DEFAULT_bedKd/PID_dT);
  48. #endif //PIDTEMPBED
  49. //===========================================================================
  50. //=============================private variables============================
  51. //===========================================================================
  52. static volatile bool temp_meas_ready = false;
  53. #ifdef PIDTEMP
  54. //static cannot be external:
  55. static float temp_iState[EXTRUDERS] = { 0 };
  56. static float temp_dState[EXTRUDERS] = { 0 };
  57. static float pTerm[EXTRUDERS];
  58. static float iTerm[EXTRUDERS];
  59. static float dTerm[EXTRUDERS];
  60. //int output;
  61. static float pid_error[EXTRUDERS];
  62. static float temp_iState_min[EXTRUDERS];
  63. static float temp_iState_max[EXTRUDERS];
  64. // static float pid_input[EXTRUDERS];
  65. // static float pid_output[EXTRUDERS];
  66. static bool pid_reset[EXTRUDERS];
  67. #endif //PIDTEMP
  68. #ifdef PIDTEMPBED
  69. //static cannot be external:
  70. static float temp_iState_bed = { 0 };
  71. static float temp_dState_bed = { 0 };
  72. static float pTerm_bed;
  73. static float iTerm_bed;
  74. static float dTerm_bed;
  75. //int output;
  76. static float pid_error_bed;
  77. static float temp_iState_min_bed;
  78. static float temp_iState_max_bed;
  79. #else //PIDTEMPBED
  80. static unsigned long previous_millis_bed_heater;
  81. #endif //PIDTEMPBED
  82. static unsigned char soft_pwm[EXTRUDERS];
  83. static unsigned char soft_pwm_bed;
  84. #ifdef FAN_SOFT_PWM
  85. static unsigned char soft_pwm_fan;
  86. #endif
  87. #if EXTRUDER_0_AUTO_FAN_PIN > -1 || EXTRUDER_1_AUTO_FAN_PIN > -1 || EXTRUDER_2_AUTO_FAN_PIN > -1
  88. static uint8_t extruderAutoFanState = 0; // extruder auto fan state stored as bitmap
  89. #endif
  90. #if EXTRUDERS > 3
  91. # error Unsupported number of extruders
  92. #elif EXTRUDERS > 2
  93. # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2, v3 }
  94. #elif EXTRUDERS > 1
  95. # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1, v2 }
  96. #else
  97. # define ARRAY_BY_EXTRUDERS(v1, v2, v3) { v1 }
  98. #endif
  99. // Init min and max temp with extreme values to prevent false errors during startup
  100. static int minttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_LO_TEMP , HEATER_1_RAW_LO_TEMP , HEATER_2_RAW_LO_TEMP );
  101. static int maxttemp_raw[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_RAW_HI_TEMP , HEATER_1_RAW_HI_TEMP , HEATER_2_RAW_HI_TEMP );
  102. static int minttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 0, 0, 0 );
  103. static int maxttemp[EXTRUDERS] = ARRAY_BY_EXTRUDERS( 16383, 16383, 16383 );
  104. //static int bed_minttemp_raw = HEATER_BED_RAW_LO_TEMP; /* No bed mintemp error implemented?!? */
  105. #ifdef BED_MAXTEMP
  106. static int bed_maxttemp_raw = HEATER_BED_RAW_HI_TEMP;
  107. #endif
  108. static void *heater_ttbl_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( (void *)HEATER_0_TEMPTABLE, (void *)HEATER_1_TEMPTABLE, (void *)HEATER_2_TEMPTABLE );
  109. static uint8_t heater_ttbllen_map[EXTRUDERS] = ARRAY_BY_EXTRUDERS( HEATER_0_TEMPTABLE_LEN, HEATER_1_TEMPTABLE_LEN, HEATER_2_TEMPTABLE_LEN );
  110. static float analog2temp(int raw, uint8_t e);
  111. static float analog2tempBed(int raw);
  112. static void updateTemperaturesFromRawValues();
  113. #ifdef WATCH_TEMP_PERIOD
  114. int watch_start_temp[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
  115. unsigned long watchmillis[EXTRUDERS] = ARRAY_BY_EXTRUDERS(0,0,0);
  116. #endif //WATCH_TEMP_PERIOD
  117. //===========================================================================
  118. //============================= functions ============================
  119. //===========================================================================
  120. void PID_autotune(float temp, int extruder, int ncycles)
  121. {
  122. float input = 0.0;
  123. int cycles=0;
  124. bool heating = true;
  125. unsigned long temp_millis = millis();
  126. unsigned long t1=temp_millis;
  127. unsigned long t2=temp_millis;
  128. long t_high = 0;
  129. long t_low = 0;
  130. long bias, d;
  131. float Ku, Tu;
  132. float Kp, Ki, Kd;
  133. float max = 0, min = 10000;
  134. if ((extruder > EXTRUDERS)
  135. #if (TEMP_BED_PIN <= -1)
  136. ||(extruder < 0)
  137. #endif
  138. ){
  139. SERIAL_ECHOLN("PID Autotune failed. Bad extruder number.");
  140. return;
  141. }
  142. SERIAL_ECHOLN("PID Autotune start");
  143. disable_heater(); // switch off all heaters.
  144. if (extruder<0)
  145. {
  146. soft_pwm_bed = (MAX_BED_POWER)/2;
  147. bias = d = (MAX_BED_POWER)/2;
  148. }
  149. else
  150. {
  151. soft_pwm[extruder] = (PID_MAX)/2;
  152. bias = d = (PID_MAX)/2;
  153. }
  154. for(;;) {
  155. if(temp_meas_ready == true) { // temp sample ready
  156. updateTemperaturesFromRawValues();
  157. input = (extruder<0)?current_temperature_bed:current_temperature[extruder];
  158. max=max(max,input);
  159. min=min(min,input);
  160. if(heating == true && input > temp) {
  161. if(millis() - t2 > 5000) {
  162. heating=false;
  163. if (extruder<0)
  164. soft_pwm_bed = (bias - d) >> 1;
  165. else
  166. soft_pwm[extruder] = (bias - d) >> 1;
  167. t1=millis();
  168. t_high=t1 - t2;
  169. max=temp;
  170. }
  171. }
  172. if(heating == false && input < temp) {
  173. if(millis() - t1 > 5000) {
  174. heating=true;
  175. t2=millis();
  176. t_low=t2 - t1;
  177. if(cycles > 0) {
  178. bias += (d*(t_high - t_low))/(t_low + t_high);
  179. bias = constrain(bias, 20 ,(extruder<0?(MAX_BED_POWER):(PID_MAX))-20);
  180. if(bias > (extruder<0?(MAX_BED_POWER):(PID_MAX))/2) d = (extruder<0?(MAX_BED_POWER):(PID_MAX)) - 1 - bias;
  181. else d = bias;
  182. SERIAL_PROTOCOLPGM(" bias: "); SERIAL_PROTOCOL(bias);
  183. SERIAL_PROTOCOLPGM(" d: "); SERIAL_PROTOCOL(d);
  184. SERIAL_PROTOCOLPGM(" min: "); SERIAL_PROTOCOL(min);
  185. SERIAL_PROTOCOLPGM(" max: "); SERIAL_PROTOCOLLN(max);
  186. if(cycles > 2) {
  187. Ku = (4.0*d)/(3.14159*(max-min)/2.0);
  188. Tu = ((float)(t_low + t_high)/1000.0);
  189. SERIAL_PROTOCOLPGM(" Ku: "); SERIAL_PROTOCOL(Ku);
  190. SERIAL_PROTOCOLPGM(" Tu: "); SERIAL_PROTOCOLLN(Tu);
  191. Kp = 0.6*Ku;
  192. Ki = 2*Kp/Tu;
  193. Kd = Kp*Tu/8;
  194. SERIAL_PROTOCOLLNPGM(" Clasic PID ")
  195. SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
  196. SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
  197. SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
  198. /*
  199. Kp = 0.33*Ku;
  200. Ki = Kp/Tu;
  201. Kd = Kp*Tu/3;
  202. SERIAL_PROTOCOLLNPGM(" Some overshoot ")
  203. SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
  204. SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
  205. SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
  206. Kp = 0.2*Ku;
  207. Ki = 2*Kp/Tu;
  208. Kd = Kp*Tu/3;
  209. SERIAL_PROTOCOLLNPGM(" No overshoot ")
  210. SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
  211. SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
  212. SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
  213. */
  214. }
  215. }
  216. if (extruder<0)
  217. soft_pwm_bed = (bias + d) >> 1;
  218. else
  219. soft_pwm[extruder] = (bias + d) >> 1;
  220. cycles++;
  221. min=temp;
  222. }
  223. }
  224. }
  225. if(input > (temp + 20)) {
  226. SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature to high");
  227. return;
  228. }
  229. if(millis() - temp_millis > 2000) {
  230. int p;
  231. if (extruder<0){
  232. p=soft_pwm_bed;
  233. SERIAL_PROTOCOLPGM("ok B:");
  234. }else{
  235. p=soft_pwm[extruder];
  236. SERIAL_PROTOCOLPGM("ok T:");
  237. }
  238. SERIAL_PROTOCOL(input);
  239. SERIAL_PROTOCOLPGM(" @:");
  240. SERIAL_PROTOCOLLN(p);
  241. temp_millis = millis();
  242. }
  243. if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
  244. SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
  245. return;
  246. }
  247. if(cycles > ncycles) {
  248. SERIAL_PROTOCOLLNPGM("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h");
  249. return;
  250. }
  251. lcd_update();
  252. }
  253. }
  254. void updatePID()
  255. {
  256. #ifdef PIDTEMP
  257. for(int e = 0; e < EXTRUDERS; e++) {
  258. temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
  259. }
  260. #endif
  261. #ifdef PIDTEMPBED
  262. temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
  263. #endif
  264. }
  265. int getHeaterPower(int heater) {
  266. if (heater<0)
  267. return soft_pwm_bed;
  268. return soft_pwm[heater];
  269. }
  270. void manage_heater()
  271. {
  272. float pid_input;
  273. float pid_output;
  274. if(temp_meas_ready != true) //better readability
  275. return;
  276. updateTemperaturesFromRawValues();
  277. for(int e = 0; e < EXTRUDERS; e++)
  278. {
  279. #ifdef PIDTEMP
  280. pid_input = current_temperature[e];
  281. #ifndef PID_OPENLOOP
  282. pid_error[e] = target_temperature[e] - pid_input;
  283. if(pid_error[e] > PID_FUNCTIONAL_RANGE) {
  284. pid_output = PID_MAX;
  285. pid_reset[e] = true;
  286. }
  287. else if(pid_error[e] < -PID_FUNCTIONAL_RANGE) {
  288. pid_output = 0;
  289. pid_reset[e] = true;
  290. }
  291. else {
  292. if(pid_reset[e] == true) {
  293. temp_iState[e] = 0.0;
  294. pid_reset[e] = false;
  295. }
  296. pTerm[e] = Kp * pid_error[e];
  297. temp_iState[e] += pid_error[e];
  298. temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
  299. iTerm[e] = Ki * temp_iState[e];
  300. //K1 defined in Configuration.h in the PID settings
  301. #define K2 (1.0-K1)
  302. dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
  303. temp_dState[e] = pid_input;
  304. pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX);
  305. }
  306. #else
  307. pid_output = constrain(target_temperature[e], 0, PID_MAX);
  308. #endif //PID_OPENLOOP
  309. #ifdef PID_DEBUG
  310. SERIAL_ECHO_START(" PIDDEBUG ");
  311. SERIAL_ECHO(e);
  312. SERIAL_ECHO(": Input ");
  313. SERIAL_ECHO(pid_input);
  314. SERIAL_ECHO(" Output ");
  315. SERIAL_ECHO(pid_output);
  316. SERIAL_ECHO(" pTerm ");
  317. SERIAL_ECHO(pTerm[e]);
  318. SERIAL_ECHO(" iTerm ");
  319. SERIAL_ECHO(iTerm[e]);
  320. SERIAL_ECHO(" dTerm ");
  321. SERIAL_ECHOLN(dTerm[e]);
  322. #endif //PID_DEBUG
  323. #else /* PID off */
  324. pid_output = 0;
  325. if(current_temperature[e] < target_temperature[e]) {
  326. pid_output = PID_MAX;
  327. }
  328. #endif
  329. // Check if temperature is within the correct range
  330. if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
  331. {
  332. soft_pwm[e] = (int)pid_output >> 1;
  333. }
  334. else {
  335. soft_pwm[e] = 0;
  336. }
  337. #ifdef WATCH_TEMP_PERIOD
  338. if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD)
  339. {
  340. if(degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE)
  341. {
  342. setTargetHotend(0, e);
  343. LCD_MESSAGEPGM("Heating failed");
  344. SERIAL_ECHO_START;
  345. SERIAL_ECHOLN("Heating failed");
  346. }else{
  347. watchmillis[e] = 0;
  348. }
  349. }
  350. #endif
  351. } // End extruder for loop
  352. #if EXTRUDER_0_AUTO_FAN_PIN > -1 || EXTRUDER_1_AUTO_FAN_PIN > -1 || EXTRUDER_2_AUTO_FAN_PIN > -1
  353. bool newFanState;
  354. #if EXTRUDER_0_AUTO_FAN_PIN > -1
  355. // check the extruder 0 setting (and any ganged auto fan outputs)
  356. newFanState = (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE ||
  357. (EXTRUDER_0_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN && current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE) ||
  358. (EXTRUDER_0_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN && current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE));
  359. if ((extruderAutoFanState & 1) != newFanState) // store state in first bit
  360. {
  361. int newFanSpeed = (newFanState ? EXTRUDER_AUTO_FAN_SPEED : 0);
  362. if (EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN)
  363. fanSpeed = newFanSpeed;
  364. pinMode(EXTRUDER_0_AUTO_FAN_PIN, OUTPUT);
  365. digitalWrite(EXTRUDER_0_AUTO_FAN_PIN, newFanSpeed);
  366. analogWrite(EXTRUDER_0_AUTO_FAN_PIN, newFanSpeed);
  367. extruderAutoFanState = newFanState | (extruderAutoFanState & ~1);
  368. }
  369. #endif //EXTRUDER_0_AUTO_FAN_PIN > -1
  370. #if EXTRUDER_1_AUTO_FAN_PIN > -1 && EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
  371. // check the extruder 1 setting (except when extruder 1 is the same as 0)
  372. newFanState = (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE ||
  373. (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_2_AUTO_FAN_PIN && current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE));
  374. if ((extruderAutoFanState & 2) != (newFanState<<1)) // use second bit
  375. {
  376. int newFanSpeed = (newFanState ? EXTRUDER_AUTO_FAN_SPEED : 0);
  377. if (EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN)
  378. fanSpeed = newFanSpeed;
  379. pinMode(EXTRUDER_1_AUTO_FAN_PIN, OUTPUT);
  380. digitalWrite(EXTRUDER_1_AUTO_FAN_PIN, newFanSpeed);
  381. analogWrite(EXTRUDER_1_AUTO_FAN_PIN, newFanSpeed);
  382. extruderAutoFanState = (newFanState<<1) | (extruderAutoFanState & ~2);
  383. }
  384. #endif //EXTRUDER_1_AUTO_FAN_PIN > -1
  385. #if EXTRUDER_2_AUTO_FAN_PIN > -1 && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN
  386. // check the extruder 2 setting (except when extruder 2 is the same as 1 or 0)
  387. newFanState = (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE);
  388. if ((extruderAutoFanState & 4) != (newFanState<<2)) // use third bit
  389. {
  390. int newFanSpeed = (newFanState ? EXTRUDER_AUTO_FAN_SPEED : 0);
  391. if (EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN)
  392. fanSpeed = newFanSpeed;
  393. pinMode(EXTRUDER_2_AUTO_FAN_PIN, OUTPUT);
  394. digitalWrite(EXTRUDER_2_AUTO_FAN_PIN, newFanSpeed);
  395. analogWrite(EXTRUDER_2_AUTO_FAN_PIN, newFanSpeed);
  396. extruderAutoFanState = (newFanState<<2) | (extruderAutoFanState & ~4);
  397. }
  398. #endif //EXTRUDER_2_AUTO_FAN_PIN > -1
  399. #endif // any AUTO_FAN_PIN enabled
  400. #ifndef PIDTEMPBED
  401. if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
  402. return;
  403. previous_millis_bed_heater = millis();
  404. #endif
  405. #if TEMP_SENSOR_BED != 0
  406. #ifdef PIDTEMPBED
  407. pid_input = current_temperature_bed;
  408. #ifndef PID_OPENLOOP
  409. pid_error_bed = target_temperature_bed - pid_input;
  410. pTerm_bed = bedKp * pid_error_bed;
  411. temp_iState_bed += pid_error_bed;
  412. temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
  413. iTerm_bed = bedKi * temp_iState_bed;
  414. //K1 defined in Configuration.h in the PID settings
  415. #define K2 (1.0-K1)
  416. dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
  417. temp_dState_bed = pid_input;
  418. pid_output = constrain(pTerm_bed + iTerm_bed - dTerm_bed, 0, MAX_BED_POWER);
  419. #else
  420. pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
  421. #endif //PID_OPENLOOP
  422. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  423. {
  424. soft_pwm_bed = (int)pid_output >> 1;
  425. }
  426. else {
  427. soft_pwm_bed = 0;
  428. }
  429. #elif !defined(BED_LIMIT_SWITCHING)
  430. // Check if temperature is within the correct range
  431. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  432. {
  433. if(current_temperature_bed >= target_temperature_bed)
  434. {
  435. soft_pwm_bed = 0;
  436. }
  437. else
  438. {
  439. soft_pwm_bed = MAX_BED_POWER>>1;
  440. }
  441. }
  442. else
  443. {
  444. soft_pwm_bed = 0;
  445. WRITE(HEATER_BED_PIN,LOW);
  446. }
  447. #else //#ifdef BED_LIMIT_SWITCHING
  448. // Check if temperature is within the correct band
  449. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  450. {
  451. if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
  452. {
  453. soft_pwm_bed = 0;
  454. }
  455. else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
  456. {
  457. soft_pwm_bed = MAX_BED_POWER>>1;
  458. }
  459. }
  460. else
  461. {
  462. soft_pwm_bed = 0;
  463. WRITE(HEATER_BED_PIN,LOW);
  464. }
  465. #endif
  466. #endif
  467. }
  468. #define PGM_RD_W(x) (short)pgm_read_word(&x)
  469. // Derived from RepRap FiveD extruder::getTemperature()
  470. // For hot end temperature measurement.
  471. static float analog2temp(int raw, uint8_t e) {
  472. if(e >= EXTRUDERS)
  473. {
  474. SERIAL_ERROR_START;
  475. SERIAL_ERROR((int)e);
  476. SERIAL_ERRORLNPGM(" - Invalid extruder number !");
  477. kill();
  478. }
  479. #ifdef HEATER_0_USES_MAX6675
  480. if (e == 0)
  481. {
  482. return 0.25 * raw;
  483. }
  484. #endif
  485. if(heater_ttbl_map[e] != NULL)
  486. {
  487. float celsius = 0;
  488. uint8_t i;
  489. short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
  490. for (i=1; i<heater_ttbllen_map[e]; i++)
  491. {
  492. if (PGM_RD_W((*tt)[i][0]) > raw)
  493. {
  494. celsius = PGM_RD_W((*tt)[i-1][1]) +
  495. (raw - PGM_RD_W((*tt)[i-1][0])) *
  496. (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /
  497. (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0]));
  498. break;
  499. }
  500. }
  501. // Overflow: Set to last value in the table
  502. if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i-1][1]);
  503. return celsius;
  504. }
  505. return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
  506. }
  507. // Derived from RepRap FiveD extruder::getTemperature()
  508. // For bed temperature measurement.
  509. static float analog2tempBed(int raw) {
  510. #ifdef BED_USES_THERMISTOR
  511. float celsius = 0;
  512. byte i;
  513. for (i=1; i<BEDTEMPTABLE_LEN; i++)
  514. {
  515. if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw)
  516. {
  517. celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) +
  518. (raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) *
  519. (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) /
  520. (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i-1][0]));
  521. break;
  522. }
  523. }
  524. // Overflow: Set to last value in the table
  525. if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]);
  526. return celsius;
  527. #elif defined BED_USES_AD595
  528. return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
  529. #else
  530. return 0;
  531. #endif
  532. }
  533. /* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
  534. and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
  535. static void updateTemperaturesFromRawValues()
  536. {
  537. for(uint8_t e=0;e<EXTRUDERS;e++)
  538. {
  539. current_temperature[e] = analog2temp(current_temperature_raw[e], e);
  540. }
  541. current_temperature_bed = analog2tempBed(current_temperature_bed_raw);
  542. //Reset the watchdog after we know we have a temperature measurement.
  543. watchdog_reset();
  544. CRITICAL_SECTION_START;
  545. temp_meas_ready = false;
  546. CRITICAL_SECTION_END;
  547. }
  548. void tp_init()
  549. {
  550. // Finish init of mult extruder arrays
  551. for(int e = 0; e < EXTRUDERS; e++) {
  552. // populate with the first value
  553. maxttemp[e] = maxttemp[0];
  554. #ifdef PIDTEMP
  555. temp_iState_min[e] = 0.0;
  556. temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
  557. #endif //PIDTEMP
  558. #ifdef PIDTEMPBED
  559. temp_iState_min_bed = 0.0;
  560. temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
  561. #endif //PIDTEMPBED
  562. }
  563. #if (HEATER_0_PIN > -1)
  564. SET_OUTPUT(HEATER_0_PIN);
  565. #endif
  566. #if (HEATER_1_PIN > -1)
  567. SET_OUTPUT(HEATER_1_PIN);
  568. #endif
  569. #if (HEATER_2_PIN > -1)
  570. SET_OUTPUT(HEATER_2_PIN);
  571. #endif
  572. #if (HEATER_BED_PIN > -1)
  573. SET_OUTPUT(HEATER_BED_PIN);
  574. #endif
  575. #if (FAN_PIN > -1)
  576. SET_OUTPUT(FAN_PIN);
  577. #ifdef FAST_PWM_FAN
  578. setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  579. #endif
  580. #ifdef FAN_SOFT_PWM
  581. soft_pwm_fan=(unsigned char)fanSpeed;
  582. #endif
  583. #endif
  584. #ifdef HEATER_0_USES_MAX6675
  585. #ifndef SDSUPPORT
  586. SET_OUTPUT(MAX_SCK_PIN);
  587. WRITE(MAX_SCK_PIN,0);
  588. SET_OUTPUT(MAX_MOSI_PIN);
  589. WRITE(MAX_MOSI_PIN,1);
  590. SET_INPUT(MAX_MISO_PIN);
  591. WRITE(MAX_MISO_PIN,1);
  592. #endif
  593. SET_OUTPUT(MAX6675_SS);
  594. WRITE(MAX6675_SS,1);
  595. #endif
  596. // Set analog inputs
  597. ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
  598. DIDR0 = 0;
  599. #ifdef DIDR2
  600. DIDR2 = 0;
  601. #endif
  602. #if (TEMP_0_PIN > -1)
  603. #if TEMP_0_PIN < 8
  604. DIDR0 |= 1 << TEMP_0_PIN;
  605. #else
  606. DIDR2 |= 1<<(TEMP_0_PIN - 8);
  607. #endif
  608. #endif
  609. #if (TEMP_1_PIN > -1)
  610. #if TEMP_1_PIN < 8
  611. DIDR0 |= 1<<TEMP_1_PIN;
  612. #else
  613. DIDR2 |= 1<<(TEMP_1_PIN - 8);
  614. #endif
  615. #endif
  616. #if (TEMP_2_PIN > -1)
  617. #if TEMP_2_PIN < 8
  618. DIDR0 |= 1 << TEMP_2_PIN;
  619. #else
  620. DIDR2 = 1<<(TEMP_2_PIN - 8);
  621. #endif
  622. #endif
  623. #if (TEMP_BED_PIN > -1)
  624. #if TEMP_BED_PIN < 8
  625. DIDR0 |= 1<<TEMP_BED_PIN;
  626. #else
  627. DIDR2 |= 1<<(TEMP_BED_PIN - 8);
  628. #endif
  629. #endif
  630. // Use timer0 for temperature measurement
  631. // Interleave temperature interrupt with millies interrupt
  632. OCR0B = 128;
  633. TIMSK0 |= (1<<OCIE0B);
  634. // Wait for temperature measurement to settle
  635. delay(250);
  636. #ifdef HEATER_0_MINTEMP
  637. minttemp[0] = HEATER_0_MINTEMP;
  638. while(analog2temp(minttemp_raw[0], 0) < HEATER_0_MINTEMP) {
  639. #if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
  640. minttemp_raw[0] += OVERSAMPLENR;
  641. #else
  642. minttemp_raw[0] -= OVERSAMPLENR;
  643. #endif
  644. }
  645. #endif //MINTEMP
  646. #ifdef HEATER_0_MAXTEMP
  647. maxttemp[0] = HEATER_0_MAXTEMP;
  648. while(analog2temp(maxttemp_raw[0], 0) > HEATER_0_MAXTEMP) {
  649. #if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
  650. maxttemp_raw[0] -= OVERSAMPLENR;
  651. #else
  652. maxttemp_raw[0] += OVERSAMPLENR;
  653. #endif
  654. }
  655. #endif //MAXTEMP
  656. #if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
  657. minttemp[1] = HEATER_1_MINTEMP;
  658. while(analog2temp(minttemp_raw[1], 1) > HEATER_1_MINTEMP) {
  659. #if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
  660. minttemp_raw[1] += OVERSAMPLENR;
  661. #else
  662. minttemp_raw[1] -= OVERSAMPLENR;
  663. #endif
  664. }
  665. #endif // MINTEMP 1
  666. #if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
  667. maxttemp[1] = HEATER_1_MAXTEMP;
  668. while(analog2temp(maxttemp_raw[1], 1) > HEATER_1_MAXTEMP) {
  669. #if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
  670. maxttemp_raw[1] -= OVERSAMPLENR;
  671. #else
  672. maxttemp_raw[1] += OVERSAMPLENR;
  673. #endif
  674. }
  675. #endif //MAXTEMP 1
  676. #if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
  677. minttemp[2] = HEATER_2_MINTEMP;
  678. while(analog2temp(minttemp_raw[2], 2) > HEATER_2_MINTEMP) {
  679. #if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
  680. minttemp_raw[2] += OVERSAMPLENR;
  681. #else
  682. minttemp_raw[2] -= OVERSAMPLENR;
  683. #endif
  684. }
  685. #endif //MINTEMP 2
  686. #if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
  687. maxttemp[2] = HEATER_2_MAXTEMP;
  688. while(analog2temp(maxttemp_raw[2], 2) > HEATER_2_MAXTEMP) {
  689. #if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
  690. maxttemp_raw[2] -= OVERSAMPLENR;
  691. #else
  692. maxttemp_raw[2] += OVERSAMPLENR;
  693. #endif
  694. }
  695. #endif //MAXTEMP 2
  696. #ifdef BED_MINTEMP
  697. /* No bed MINTEMP error implemented?!? */ /*
  698. while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
  699. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  700. bed_minttemp_raw += OVERSAMPLENR;
  701. #else
  702. bed_minttemp_raw -= OVERSAMPLENR;
  703. #endif
  704. }
  705. */
  706. #endif //BED_MINTEMP
  707. #ifdef BED_MAXTEMP
  708. while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) {
  709. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  710. bed_maxttemp_raw -= OVERSAMPLENR;
  711. #else
  712. bed_maxttemp_raw += OVERSAMPLENR;
  713. #endif
  714. }
  715. #endif //BED_MAXTEMP
  716. }
  717. void setWatch()
  718. {
  719. #ifdef WATCH_TEMP_PERIOD
  720. for (int e = 0; e < EXTRUDERS; e++)
  721. {
  722. if(degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2))
  723. {
  724. watch_start_temp[e] = degHotend(e);
  725. watchmillis[e] = millis();
  726. }
  727. }
  728. #endif
  729. }
  730. void disable_heater()
  731. {
  732. for(int i=0;i<EXTRUDERS;i++)
  733. setTargetHotend(0,i);
  734. setTargetBed(0);
  735. #if TEMP_0_PIN > -1
  736. target_temperature[0]=0;
  737. soft_pwm[0]=0;
  738. #if HEATER_0_PIN > -1
  739. WRITE(HEATER_0_PIN,LOW);
  740. #endif
  741. #endif
  742. #if TEMP_1_PIN > -1
  743. target_temperature[1]=0;
  744. soft_pwm[1]=0;
  745. #if HEATER_1_PIN > -1
  746. WRITE(HEATER_1_PIN,LOW);
  747. #endif
  748. #endif
  749. #if TEMP_2_PIN > -1
  750. target_temperature[2]=0;
  751. soft_pwm[2]=0;
  752. #if HEATER_2_PIN > -1
  753. WRITE(HEATER_2_PIN,LOW);
  754. #endif
  755. #endif
  756. #if TEMP_BED_PIN > -1
  757. target_temperature_bed=0;
  758. soft_pwm_bed=0;
  759. #if HEATER_BED_PIN > -1
  760. WRITE(HEATER_BED_PIN,LOW);
  761. #endif
  762. #endif
  763. }
  764. void max_temp_error(uint8_t e) {
  765. disable_heater();
  766. if(IsStopped() == false) {
  767. SERIAL_ERROR_START;
  768. SERIAL_ERRORLN((int)e);
  769. SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !");
  770. LCD_ALERTMESSAGEPGM("Err: MAXTEMP");
  771. }
  772. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  773. Stop();
  774. #endif
  775. }
  776. void min_temp_error(uint8_t e) {
  777. disable_heater();
  778. if(IsStopped() == false) {
  779. SERIAL_ERROR_START;
  780. SERIAL_ERRORLN((int)e);
  781. SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !");
  782. LCD_ALERTMESSAGEPGM("Err: MINTEMP");
  783. }
  784. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  785. Stop();
  786. #endif
  787. }
  788. void bed_max_temp_error(void) {
  789. #if HEATER_BED_PIN > -1
  790. WRITE(HEATER_BED_PIN, 0);
  791. #endif
  792. if(IsStopped() == false) {
  793. SERIAL_ERROR_START;
  794. SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!");
  795. LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED");
  796. }
  797. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  798. Stop();
  799. #endif
  800. }
  801. #ifdef HEATER_0_USES_MAX6675
  802. #define MAX6675_HEAT_INTERVAL 250
  803. long max6675_previous_millis = -HEAT_INTERVAL;
  804. int max6675_temp = 2000;
  805. int read_max6675()
  806. {
  807. if (millis() - max6675_previous_millis < MAX6675_HEAT_INTERVAL)
  808. return max6675_temp;
  809. max6675_previous_millis = millis();
  810. max6675_temp = 0;
  811. #ifdef PRR
  812. PRR &= ~(1<<PRSPI);
  813. #elif defined PRR0
  814. PRR0 &= ~(1<<PRSPI);
  815. #endif
  816. SPCR = (1<<MSTR) | (1<<SPE) | (1<<SPR0);
  817. // enable TT_MAX6675
  818. WRITE(MAX6675_SS, 0);
  819. // ensure 100ns delay - a bit extra is fine
  820. asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
  821. asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
  822. // read MSB
  823. SPDR = 0;
  824. for (;(SPSR & (1<<SPIF)) == 0;);
  825. max6675_temp = SPDR;
  826. max6675_temp <<= 8;
  827. // read LSB
  828. SPDR = 0;
  829. for (;(SPSR & (1<<SPIF)) == 0;);
  830. max6675_temp |= SPDR;
  831. // disable TT_MAX6675
  832. WRITE(MAX6675_SS, 1);
  833. if (max6675_temp & 4)
  834. {
  835. // thermocouple open
  836. max6675_temp = 2000;
  837. }
  838. else
  839. {
  840. max6675_temp = max6675_temp >> 3;
  841. }
  842. return max6675_temp;
  843. }
  844. #endif
  845. // Timer 0 is shared with millies
  846. ISR(TIMER0_COMPB_vect)
  847. {
  848. //these variables are only accesible from the ISR, but static, so they don't loose their value
  849. static unsigned char temp_count = 0;
  850. static unsigned long raw_temp_0_value = 0;
  851. static unsigned long raw_temp_1_value = 0;
  852. static unsigned long raw_temp_2_value = 0;
  853. static unsigned long raw_temp_bed_value = 0;
  854. static unsigned char temp_state = 0;
  855. static unsigned char pwm_count = 1;
  856. static unsigned char soft_pwm_0;
  857. #if EXTRUDERS > 1
  858. static unsigned char soft_pwm_1;
  859. #endif
  860. #if EXTRUDERS > 2
  861. static unsigned char soft_pwm_2;
  862. #endif
  863. #if HEATER_BED_PIN > -1
  864. static unsigned char soft_pwm_b;
  865. #endif
  866. if(pwm_count == 0){
  867. soft_pwm_0 = soft_pwm[0];
  868. if(soft_pwm_0 > 0) WRITE(HEATER_0_PIN,1);
  869. #if EXTRUDERS > 1
  870. soft_pwm_1 = soft_pwm[1];
  871. if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1);
  872. #endif
  873. #if EXTRUDERS > 2
  874. soft_pwm_2 = soft_pwm[2];
  875. if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1);
  876. #endif
  877. #if HEATER_BED_PIN > -1
  878. soft_pwm_b = soft_pwm_bed;
  879. if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1);
  880. #endif
  881. #ifdef FAN_SOFT_PWM
  882. soft_pwm_fan =(unsigned char) fanSpeed;
  883. if(soft_pwm_fan > 0) WRITE(FAN_PIN,1);
  884. #endif
  885. }
  886. if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0);
  887. #if EXTRUDERS > 1
  888. if(soft_pwm_1 <= pwm_count) WRITE(HEATER_1_PIN,0);
  889. #endif
  890. #if EXTRUDERS > 2
  891. if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0);
  892. #endif
  893. #if HEATER_BED_PIN > -1
  894. if(soft_pwm_b <= pwm_count) WRITE(HEATER_BED_PIN,0);
  895. #endif
  896. #ifdef FAN_SOFT_PWM
  897. if(soft_pwm_fan <= pwm_count) WRITE(FAN_PIN,0);
  898. #endif
  899. pwm_count++;
  900. pwm_count &= 0x7f;
  901. switch(temp_state) {
  902. case 0: // Prepare TEMP_0
  903. #if (TEMP_0_PIN > -1)
  904. #if TEMP_0_PIN > 7
  905. ADCSRB = 1<<MUX5;
  906. #else
  907. ADCSRB = 0;
  908. #endif
  909. ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
  910. ADCSRA |= 1<<ADSC; // Start conversion
  911. #endif
  912. lcd_buttons_update();
  913. temp_state = 1;
  914. break;
  915. case 1: // Measure TEMP_0
  916. #if (TEMP_0_PIN > -1)
  917. raw_temp_0_value += ADC;
  918. #endif
  919. #ifdef HEATER_0_USES_MAX6675 // TODO remove the blocking
  920. raw_temp_0_value = read_max6675();
  921. #endif
  922. temp_state = 2;
  923. break;
  924. case 2: // Prepare TEMP_BED
  925. #if (TEMP_BED_PIN > -1)
  926. #if TEMP_BED_PIN > 7
  927. ADCSRB = 1<<MUX5;
  928. #else
  929. ADCSRB = 0;
  930. #endif
  931. ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
  932. ADCSRA |= 1<<ADSC; // Start conversion
  933. #endif
  934. lcd_buttons_update();
  935. temp_state = 3;
  936. break;
  937. case 3: // Measure TEMP_BED
  938. #if (TEMP_BED_PIN > -1)
  939. raw_temp_bed_value += ADC;
  940. #endif
  941. temp_state = 4;
  942. break;
  943. case 4: // Prepare TEMP_1
  944. #if (TEMP_1_PIN > -1)
  945. #if TEMP_1_PIN > 7
  946. ADCSRB = 1<<MUX5;
  947. #else
  948. ADCSRB = 0;
  949. #endif
  950. ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
  951. ADCSRA |= 1<<ADSC; // Start conversion
  952. #endif
  953. lcd_buttons_update();
  954. temp_state = 5;
  955. break;
  956. case 5: // Measure TEMP_1
  957. #if (TEMP_1_PIN > -1)
  958. raw_temp_1_value += ADC;
  959. #endif
  960. temp_state = 6;
  961. break;
  962. case 6: // Prepare TEMP_2
  963. #if (TEMP_2_PIN > -1)
  964. #if TEMP_2_PIN > 7
  965. ADCSRB = 1<<MUX5;
  966. #else
  967. ADCSRB = 0;
  968. #endif
  969. ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
  970. ADCSRA |= 1<<ADSC; // Start conversion
  971. #endif
  972. lcd_buttons_update();
  973. temp_state = 7;
  974. break;
  975. case 7: // Measure TEMP_2
  976. #if (TEMP_2_PIN > -1)
  977. raw_temp_2_value += ADC;
  978. #endif
  979. temp_state = 0;
  980. temp_count++;
  981. break;
  982. // default:
  983. // SERIAL_ERROR_START;
  984. // SERIAL_ERRORLNPGM("Temp measurement error!");
  985. // break;
  986. }
  987. if(temp_count >= 16) // 8 ms * 16 = 128ms.
  988. {
  989. if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
  990. {
  991. current_temperature_raw[0] = raw_temp_0_value;
  992. #if EXTRUDERS > 1
  993. current_temperature_raw[1] = raw_temp_1_value;
  994. #endif
  995. #if EXTRUDERS > 2
  996. current_temperature_raw[2] = raw_temp_2_value;
  997. #endif
  998. current_temperature_bed_raw = raw_temp_bed_value;
  999. }
  1000. temp_meas_ready = true;
  1001. temp_count = 0;
  1002. raw_temp_0_value = 0;
  1003. raw_temp_1_value = 0;
  1004. raw_temp_2_value = 0;
  1005. raw_temp_bed_value = 0;
  1006. #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
  1007. if(current_temperature_raw[0] <= maxttemp_raw[0]) {
  1008. #else
  1009. if(current_temperature_raw[0] >= maxttemp_raw[0]) {
  1010. #endif
  1011. max_temp_error(0);
  1012. }
  1013. #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
  1014. if(current_temperature_raw[0] >= minttemp_raw[0]) {
  1015. #else
  1016. if(current_temperature_raw[0] <= minttemp_raw[0]) {
  1017. #endif
  1018. min_temp_error(0);
  1019. }
  1020. #if EXTRUDERS > 1
  1021. #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
  1022. if(current_temperature_raw[1] <= maxttemp_raw[1]) {
  1023. #else
  1024. if(current_temperature_raw[1] >= maxttemp_raw[1]) {
  1025. #endif
  1026. max_temp_error(1);
  1027. }
  1028. #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
  1029. if(current_temperature_raw[1] >= minttemp_raw[1]) {
  1030. #else
  1031. if(current_temperature_raw[1] <= minttemp_raw[1]) {
  1032. #endif
  1033. min_temp_error(1);
  1034. }
  1035. #endif
  1036. #if EXTRUDERS > 2
  1037. #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
  1038. if(current_temperature_raw[2] <= maxttemp_raw[2]) {
  1039. #else
  1040. if(current_temperature_raw[2] >= maxttemp_raw[2]) {
  1041. #endif
  1042. max_temp_error(2);
  1043. }
  1044. #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
  1045. if(current_temperature_raw[2] >= minttemp_raw[2]) {
  1046. #else
  1047. if(current_temperature_raw[2] <= minttemp_raw[2]) {
  1048. #endif
  1049. min_temp_error(2);
  1050. }
  1051. #endif
  1052. /* No bed MINTEMP error? */
  1053. #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
  1054. # if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
  1055. if(current_temperature_bed_raw <= bed_maxttemp_raw) {
  1056. #else
  1057. if(current_temperature_bed_raw >= bed_maxttemp_raw) {
  1058. #endif
  1059. target_temperature_bed = 0;
  1060. bed_max_temp_error();
  1061. }
  1062. #endif
  1063. }
  1064. }