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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242
  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 > 0 || EXTRUDER_1_AUTO_FAN_PIN > 0 || EXTRUDER_2_AUTO_FAN_PIN > 0
  88. static unsigned long extruder_autofan_last_check;
  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. #if EXTRUDER_0_AUTO_FAN_PIN > 0 || EXTRUDER_1_AUTO_FAN_PIN > 0 || EXTRUDER_2_AUTO_FAN_PIN > 0
  271. #if FAN_PIN > 0
  272. #if EXTRUDER_0_AUTO_FAN_PIN == FAN_PIN
  273. #error "You cannot set EXTRUDER_0_AUTO_FAN_PIN equal to FAN_PIN"
  274. #endif
  275. #if EXTRUDER_1_AUTO_FAN_PIN == FAN_PIN
  276. #error "You cannot set EXTRUDER_1_AUTO_FAN_PIN equal to FAN_PIN"
  277. #endif
  278. #if EXTRUDER_2_AUTO_FAN_PIN == FAN_PIN
  279. #error "You cannot set EXTRUDER_2_AUTO_FAN_PIN equal to FAN_PIN"
  280. #endif
  281. #endif
  282. void setExtruderAutoFanState(int pin, bool state)
  283. {
  284. unsigned char newFanSpeed = (state != 0) ? EXTRUDER_AUTO_FAN_SPEED : 0;
  285. // this idiom allows both digital and PWM fan outputs (see M42 handling).
  286. pinMode(pin, OUTPUT);
  287. digitalWrite(pin, newFanSpeed);
  288. analogWrite(pin, newFanSpeed);
  289. }
  290. void checkExtruderAutoFans()
  291. {
  292. uint8_t fanState = 0;
  293. // which fan pins need to be turned on?
  294. #if EXTRUDER_0_AUTO_FAN_PIN > 0
  295. if (current_temperature[0] > EXTRUDER_AUTO_FAN_TEMPERATURE)
  296. fanState |= 1;
  297. #endif
  298. #if EXTRUDER_1_AUTO_FAN_PIN > 0
  299. if (current_temperature[1] > EXTRUDER_AUTO_FAN_TEMPERATURE)
  300. {
  301. if (EXTRUDER_1_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
  302. fanState |= 1;
  303. else
  304. fanState |= 2;
  305. }
  306. #endif
  307. #if EXTRUDER_2_AUTO_FAN_PIN > 0
  308. if (current_temperature[2] > EXTRUDER_AUTO_FAN_TEMPERATURE)
  309. {
  310. if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_0_AUTO_FAN_PIN)
  311. fanState |= 1;
  312. else if (EXTRUDER_2_AUTO_FAN_PIN == EXTRUDER_1_AUTO_FAN_PIN)
  313. fanState |= 2;
  314. else
  315. fanState |= 4;
  316. }
  317. #endif
  318. // update extruder auto fan states
  319. #if EXTRUDER_0_AUTO_FAN_PIN > 0
  320. setExtruderAutoFanState(EXTRUDER_0_AUTO_FAN_PIN, (fanState & 1) != 0);
  321. #endif
  322. #if EXTRUDER_1_AUTO_FAN_PIN > 0
  323. if (EXTRUDER_1_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN)
  324. setExtruderAutoFanState(EXTRUDER_1_AUTO_FAN_PIN, (fanState & 2) != 0);
  325. #endif
  326. #if EXTRUDER_2_AUTO_FAN_PIN > 0
  327. if (EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_0_AUTO_FAN_PIN
  328. && EXTRUDER_2_AUTO_FAN_PIN != EXTRUDER_1_AUTO_FAN_PIN)
  329. setExtruderAutoFanState(EXTRUDER_2_AUTO_FAN_PIN, (fanState & 4) != 0);
  330. #endif
  331. }
  332. #endif // any extruder auto fan pins set
  333. void manage_heater()
  334. {
  335. float pid_input;
  336. float pid_output;
  337. if(temp_meas_ready != true) //better readability
  338. return;
  339. updateTemperaturesFromRawValues();
  340. for(int e = 0; e < EXTRUDERS; e++)
  341. {
  342. #ifdef PIDTEMP
  343. pid_input = current_temperature[e];
  344. #ifndef PID_OPENLOOP
  345. pid_error[e] = target_temperature[e] - pid_input;
  346. if(pid_error[e] > PID_FUNCTIONAL_RANGE) {
  347. pid_output = BANG_MAX;
  348. pid_reset[e] = true;
  349. }
  350. else if(pid_error[e] < -PID_FUNCTIONAL_RANGE || target_temperature[e] == 0) {
  351. pid_output = 0;
  352. pid_reset[e] = true;
  353. }
  354. else {
  355. if(pid_reset[e] == true) {
  356. temp_iState[e] = 0.0;
  357. pid_reset[e] = false;
  358. }
  359. pTerm[e] = Kp * pid_error[e];
  360. temp_iState[e] += pid_error[e];
  361. temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
  362. iTerm[e] = Ki * temp_iState[e];
  363. //K1 defined in Configuration.h in the PID settings
  364. #define K2 (1.0-K1)
  365. dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
  366. temp_dState[e] = pid_input;
  367. pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX);
  368. }
  369. #else
  370. pid_output = constrain(target_temperature[e], 0, PID_MAX);
  371. #endif //PID_OPENLOOP
  372. #ifdef PID_DEBUG
  373. SERIAL_ECHO_START(" PIDDEBUG ");
  374. SERIAL_ECHO(e);
  375. SERIAL_ECHO(": Input ");
  376. SERIAL_ECHO(pid_input);
  377. SERIAL_ECHO(" Output ");
  378. SERIAL_ECHO(pid_output);
  379. SERIAL_ECHO(" pTerm ");
  380. SERIAL_ECHO(pTerm[e]);
  381. SERIAL_ECHO(" iTerm ");
  382. SERIAL_ECHO(iTerm[e]);
  383. SERIAL_ECHO(" dTerm ");
  384. SERIAL_ECHOLN(dTerm[e]);
  385. #endif //PID_DEBUG
  386. #else /* PID off */
  387. pid_output = 0;
  388. if(current_temperature[e] < target_temperature[e]) {
  389. pid_output = PID_MAX;
  390. }
  391. #endif
  392. // Check if temperature is within the correct range
  393. if((current_temperature[e] > minttemp[e]) && (current_temperature[e] < maxttemp[e]))
  394. {
  395. soft_pwm[e] = (int)pid_output >> 1;
  396. }
  397. else {
  398. soft_pwm[e] = 0;
  399. }
  400. #ifdef WATCH_TEMP_PERIOD
  401. if(watchmillis[e] && millis() - watchmillis[e] > WATCH_TEMP_PERIOD)
  402. {
  403. if(degHotend(e) < watch_start_temp[e] + WATCH_TEMP_INCREASE)
  404. {
  405. setTargetHotend(0, e);
  406. LCD_MESSAGEPGM("Heating failed");
  407. SERIAL_ECHO_START;
  408. SERIAL_ECHOLN("Heating failed");
  409. }else{
  410. watchmillis[e] = 0;
  411. }
  412. }
  413. #endif
  414. } // End extruder for loop
  415. #if EXTRUDER_0_AUTO_FAN_PIN > 0 || EXTRUDER_1_AUTO_FAN_PIN > 0 || EXTRUDER_2_AUTO_FAN_PIN > 0
  416. if(millis() - extruder_autofan_last_check > 2500) // only need to check fan state very infrequently
  417. {
  418. checkExtruderAutoFans();
  419. extruder_autofan_last_check = millis();
  420. }
  421. #endif
  422. #ifndef PIDTEMPBED
  423. if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
  424. return;
  425. previous_millis_bed_heater = millis();
  426. #endif
  427. #if TEMP_SENSOR_BED != 0
  428. #ifdef PIDTEMPBED
  429. pid_input = current_temperature_bed;
  430. #ifndef PID_OPENLOOP
  431. pid_error_bed = target_temperature_bed - pid_input;
  432. pTerm_bed = bedKp * pid_error_bed;
  433. temp_iState_bed += pid_error_bed;
  434. temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
  435. iTerm_bed = bedKi * temp_iState_bed;
  436. //K1 defined in Configuration.h in the PID settings
  437. #define K2 (1.0-K1)
  438. dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
  439. temp_dState_bed = pid_input;
  440. pid_output = constrain(pTerm_bed + iTerm_bed - dTerm_bed, 0, MAX_BED_POWER);
  441. #else
  442. pid_output = constrain(target_temperature_bed, 0, MAX_BED_POWER);
  443. #endif //PID_OPENLOOP
  444. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  445. {
  446. soft_pwm_bed = (int)pid_output >> 1;
  447. }
  448. else {
  449. soft_pwm_bed = 0;
  450. }
  451. #elif !defined(BED_LIMIT_SWITCHING)
  452. // Check if temperature is within the correct range
  453. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  454. {
  455. if(current_temperature_bed >= target_temperature_bed)
  456. {
  457. soft_pwm_bed = 0;
  458. }
  459. else
  460. {
  461. soft_pwm_bed = MAX_BED_POWER>>1;
  462. }
  463. }
  464. else
  465. {
  466. soft_pwm_bed = 0;
  467. WRITE(HEATER_BED_PIN,LOW);
  468. }
  469. #else //#ifdef BED_LIMIT_SWITCHING
  470. // Check if temperature is within the correct band
  471. if((current_temperature_bed > BED_MINTEMP) && (current_temperature_bed < BED_MAXTEMP))
  472. {
  473. if(current_temperature_bed > target_temperature_bed + BED_HYSTERESIS)
  474. {
  475. soft_pwm_bed = 0;
  476. }
  477. else if(current_temperature_bed <= target_temperature_bed - BED_HYSTERESIS)
  478. {
  479. soft_pwm_bed = MAX_BED_POWER>>1;
  480. }
  481. }
  482. else
  483. {
  484. soft_pwm_bed = 0;
  485. WRITE(HEATER_BED_PIN,LOW);
  486. }
  487. #endif
  488. #endif
  489. }
  490. #define PGM_RD_W(x) (short)pgm_read_word(&x)
  491. // Derived from RepRap FiveD extruder::getTemperature()
  492. // For hot end temperature measurement.
  493. static float analog2temp(int raw, uint8_t e) {
  494. if(e >= EXTRUDERS)
  495. {
  496. SERIAL_ERROR_START;
  497. SERIAL_ERROR((int)e);
  498. SERIAL_ERRORLNPGM(" - Invalid extruder number !");
  499. kill();
  500. }
  501. #ifdef HEATER_0_USES_MAX6675
  502. if (e == 0)
  503. {
  504. return 0.25 * raw;
  505. }
  506. #endif
  507. if(heater_ttbl_map[e] != NULL)
  508. {
  509. float celsius = 0;
  510. uint8_t i;
  511. short (*tt)[][2] = (short (*)[][2])(heater_ttbl_map[e]);
  512. for (i=1; i<heater_ttbllen_map[e]; i++)
  513. {
  514. if (PGM_RD_W((*tt)[i][0]) > raw)
  515. {
  516. celsius = PGM_RD_W((*tt)[i-1][1]) +
  517. (raw - PGM_RD_W((*tt)[i-1][0])) *
  518. (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /
  519. (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0]));
  520. break;
  521. }
  522. }
  523. // Overflow: Set to last value in the table
  524. if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i-1][1]);
  525. return celsius;
  526. }
  527. return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
  528. }
  529. // Derived from RepRap FiveD extruder::getTemperature()
  530. // For bed temperature measurement.
  531. static float analog2tempBed(int raw) {
  532. #ifdef BED_USES_THERMISTOR
  533. float celsius = 0;
  534. byte i;
  535. for (i=1; i<BEDTEMPTABLE_LEN; i++)
  536. {
  537. if (PGM_RD_W(BEDTEMPTABLE[i][0]) > raw)
  538. {
  539. celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]) +
  540. (raw - PGM_RD_W(BEDTEMPTABLE[i-1][0])) *
  541. (float)(PGM_RD_W(BEDTEMPTABLE[i][1]) - PGM_RD_W(BEDTEMPTABLE[i-1][1])) /
  542. (float)(PGM_RD_W(BEDTEMPTABLE[i][0]) - PGM_RD_W(BEDTEMPTABLE[i-1][0]));
  543. break;
  544. }
  545. }
  546. // Overflow: Set to last value in the table
  547. if (i == BEDTEMPTABLE_LEN) celsius = PGM_RD_W(BEDTEMPTABLE[i-1][1]);
  548. return celsius;
  549. #elif defined BED_USES_AD595
  550. return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;
  551. #else
  552. return 0;
  553. #endif
  554. }
  555. /* Called to get the raw values into the the actual temperatures. The raw values are created in interrupt context,
  556. and this function is called from normal context as it is too slow to run in interrupts and will block the stepper routine otherwise */
  557. static void updateTemperaturesFromRawValues()
  558. {
  559. for(uint8_t e=0;e<EXTRUDERS;e++)
  560. {
  561. current_temperature[e] = analog2temp(current_temperature_raw[e], e);
  562. }
  563. current_temperature_bed = analog2tempBed(current_temperature_bed_raw);
  564. //Reset the watchdog after we know we have a temperature measurement.
  565. watchdog_reset();
  566. CRITICAL_SECTION_START;
  567. temp_meas_ready = false;
  568. CRITICAL_SECTION_END;
  569. }
  570. void tp_init()
  571. {
  572. #if (MOTHERBOARD == 80) && ((TEMP_SENSOR_0==-1)||(TEMP_SENSOR_1==-1)||(TEMP_SENSOR_2==-1)||(TEMP_SENSOR_BED==-1))
  573. //disable RUMBA JTAG in case the thermocouple extension is plugged on top of JTAG connector
  574. MCUCR=(1<<JTD);
  575. MCUCR=(1<<JTD);
  576. #endif
  577. // Finish init of mult extruder arrays
  578. for(int e = 0; e < EXTRUDERS; e++) {
  579. // populate with the first value
  580. maxttemp[e] = maxttemp[0];
  581. #ifdef PIDTEMP
  582. temp_iState_min[e] = 0.0;
  583. temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
  584. #endif //PIDTEMP
  585. #ifdef PIDTEMPBED
  586. temp_iState_min_bed = 0.0;
  587. temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
  588. #endif //PIDTEMPBED
  589. }
  590. #if (HEATER_0_PIN > -1)
  591. SET_OUTPUT(HEATER_0_PIN);
  592. #endif
  593. #if (HEATER_1_PIN > -1)
  594. SET_OUTPUT(HEATER_1_PIN);
  595. #endif
  596. #if (HEATER_2_PIN > -1)
  597. SET_OUTPUT(HEATER_2_PIN);
  598. #endif
  599. #if (HEATER_BED_PIN > -1)
  600. SET_OUTPUT(HEATER_BED_PIN);
  601. #endif
  602. #if (FAN_PIN > -1)
  603. SET_OUTPUT(FAN_PIN);
  604. #ifdef FAST_PWM_FAN
  605. setPwmFrequency(FAN_PIN, 1); // No prescaling. Pwm frequency = F_CPU/256/8
  606. #endif
  607. #ifdef FAN_SOFT_PWM
  608. soft_pwm_fan=(unsigned char)fanSpeed;
  609. #endif
  610. #endif
  611. #ifdef HEATER_0_USES_MAX6675
  612. #ifndef SDSUPPORT
  613. SET_OUTPUT(MAX_SCK_PIN);
  614. WRITE(MAX_SCK_PIN,0);
  615. SET_OUTPUT(MAX_MOSI_PIN);
  616. WRITE(MAX_MOSI_PIN,1);
  617. SET_INPUT(MAX_MISO_PIN);
  618. WRITE(MAX_MISO_PIN,1);
  619. #endif
  620. SET_OUTPUT(MAX6675_SS);
  621. WRITE(MAX6675_SS,1);
  622. #endif
  623. // Set analog inputs
  624. ADCSRA = 1<<ADEN | 1<<ADSC | 1<<ADIF | 0x07;
  625. DIDR0 = 0;
  626. #ifdef DIDR2
  627. DIDR2 = 0;
  628. #endif
  629. #if (TEMP_0_PIN > -1)
  630. #if TEMP_0_PIN < 8
  631. DIDR0 |= 1 << TEMP_0_PIN;
  632. #else
  633. DIDR2 |= 1<<(TEMP_0_PIN - 8);
  634. #endif
  635. #endif
  636. #if (TEMP_1_PIN > -1)
  637. #if TEMP_1_PIN < 8
  638. DIDR0 |= 1<<TEMP_1_PIN;
  639. #else
  640. DIDR2 |= 1<<(TEMP_1_PIN - 8);
  641. #endif
  642. #endif
  643. #if (TEMP_2_PIN > -1)
  644. #if TEMP_2_PIN < 8
  645. DIDR0 |= 1 << TEMP_2_PIN;
  646. #else
  647. DIDR2 |= 1<<(TEMP_2_PIN - 8);
  648. #endif
  649. #endif
  650. #if (TEMP_BED_PIN > -1)
  651. #if TEMP_BED_PIN < 8
  652. DIDR0 |= 1<<TEMP_BED_PIN;
  653. #else
  654. DIDR2 |= 1<<(TEMP_BED_PIN - 8);
  655. #endif
  656. #endif
  657. // Use timer0 for temperature measurement
  658. // Interleave temperature interrupt with millies interrupt
  659. OCR0B = 128;
  660. TIMSK0 |= (1<<OCIE0B);
  661. // Wait for temperature measurement to settle
  662. delay(250);
  663. #ifdef HEATER_0_MINTEMP
  664. minttemp[0] = HEATER_0_MINTEMP;
  665. while(analog2temp(minttemp_raw[0], 0) < HEATER_0_MINTEMP) {
  666. #if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
  667. minttemp_raw[0] += OVERSAMPLENR;
  668. #else
  669. minttemp_raw[0] -= OVERSAMPLENR;
  670. #endif
  671. }
  672. #endif //MINTEMP
  673. #ifdef HEATER_0_MAXTEMP
  674. maxttemp[0] = HEATER_0_MAXTEMP;
  675. while(analog2temp(maxttemp_raw[0], 0) > HEATER_0_MAXTEMP) {
  676. #if HEATER_0_RAW_LO_TEMP < HEATER_0_RAW_HI_TEMP
  677. maxttemp_raw[0] -= OVERSAMPLENR;
  678. #else
  679. maxttemp_raw[0] += OVERSAMPLENR;
  680. #endif
  681. }
  682. #endif //MAXTEMP
  683. #if (EXTRUDERS > 1) && defined(HEATER_1_MINTEMP)
  684. minttemp[1] = HEATER_1_MINTEMP;
  685. while(analog2temp(minttemp_raw[1], 1) < HEATER_1_MINTEMP) {
  686. #if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
  687. minttemp_raw[1] += OVERSAMPLENR;
  688. #else
  689. minttemp_raw[1] -= OVERSAMPLENR;
  690. #endif
  691. }
  692. #endif // MINTEMP 1
  693. #if (EXTRUDERS > 1) && defined(HEATER_1_MAXTEMP)
  694. maxttemp[1] = HEATER_1_MAXTEMP;
  695. while(analog2temp(maxttemp_raw[1], 1) > HEATER_1_MAXTEMP) {
  696. #if HEATER_1_RAW_LO_TEMP < HEATER_1_RAW_HI_TEMP
  697. maxttemp_raw[1] -= OVERSAMPLENR;
  698. #else
  699. maxttemp_raw[1] += OVERSAMPLENR;
  700. #endif
  701. }
  702. #endif //MAXTEMP 1
  703. #if (EXTRUDERS > 2) && defined(HEATER_2_MINTEMP)
  704. minttemp[2] = HEATER_2_MINTEMP;
  705. while(analog2temp(minttemp_raw[2], 2) < HEATER_2_MINTEMP) {
  706. #if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
  707. minttemp_raw[2] += OVERSAMPLENR;
  708. #else
  709. minttemp_raw[2] -= OVERSAMPLENR;
  710. #endif
  711. }
  712. #endif //MINTEMP 2
  713. #if (EXTRUDERS > 2) && defined(HEATER_2_MAXTEMP)
  714. maxttemp[2] = HEATER_2_MAXTEMP;
  715. while(analog2temp(maxttemp_raw[2], 2) > HEATER_2_MAXTEMP) {
  716. #if HEATER_2_RAW_LO_TEMP < HEATER_2_RAW_HI_TEMP
  717. maxttemp_raw[2] -= OVERSAMPLENR;
  718. #else
  719. maxttemp_raw[2] += OVERSAMPLENR;
  720. #endif
  721. }
  722. #endif //MAXTEMP 2
  723. #ifdef BED_MINTEMP
  724. /* No bed MINTEMP error implemented?!? */ /*
  725. while(analog2tempBed(bed_minttemp_raw) < BED_MINTEMP) {
  726. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  727. bed_minttemp_raw += OVERSAMPLENR;
  728. #else
  729. bed_minttemp_raw -= OVERSAMPLENR;
  730. #endif
  731. }
  732. */
  733. #endif //BED_MINTEMP
  734. #ifdef BED_MAXTEMP
  735. while(analog2tempBed(bed_maxttemp_raw) > BED_MAXTEMP) {
  736. #if HEATER_BED_RAW_LO_TEMP < HEATER_BED_RAW_HI_TEMP
  737. bed_maxttemp_raw -= OVERSAMPLENR;
  738. #else
  739. bed_maxttemp_raw += OVERSAMPLENR;
  740. #endif
  741. }
  742. #endif //BED_MAXTEMP
  743. }
  744. void setWatch()
  745. {
  746. #ifdef WATCH_TEMP_PERIOD
  747. for (int e = 0; e < EXTRUDERS; e++)
  748. {
  749. if(degHotend(e) < degTargetHotend(e) - (WATCH_TEMP_INCREASE * 2))
  750. {
  751. watch_start_temp[e] = degHotend(e);
  752. watchmillis[e] = millis();
  753. }
  754. }
  755. #endif
  756. }
  757. void disable_heater()
  758. {
  759. for(int i=0;i<EXTRUDERS;i++)
  760. setTargetHotend(0,i);
  761. setTargetBed(0);
  762. #if TEMP_0_PIN > -1
  763. target_temperature[0]=0;
  764. soft_pwm[0]=0;
  765. #if HEATER_0_PIN > -1
  766. WRITE(HEATER_0_PIN,LOW);
  767. #endif
  768. #endif
  769. #if TEMP_1_PIN > -1
  770. target_temperature[1]=0;
  771. soft_pwm[1]=0;
  772. #if HEATER_1_PIN > -1
  773. WRITE(HEATER_1_PIN,LOW);
  774. #endif
  775. #endif
  776. #if TEMP_2_PIN > -1
  777. target_temperature[2]=0;
  778. soft_pwm[2]=0;
  779. #if HEATER_2_PIN > -1
  780. WRITE(HEATER_2_PIN,LOW);
  781. #endif
  782. #endif
  783. #if TEMP_BED_PIN > -1
  784. target_temperature_bed=0;
  785. soft_pwm_bed=0;
  786. #if HEATER_BED_PIN > -1
  787. WRITE(HEATER_BED_PIN,LOW);
  788. #endif
  789. #endif
  790. }
  791. void max_temp_error(uint8_t e) {
  792. disable_heater();
  793. if(IsStopped() == false) {
  794. SERIAL_ERROR_START;
  795. SERIAL_ERRORLN((int)e);
  796. SERIAL_ERRORLNPGM(": Extruder switched off. MAXTEMP triggered !");
  797. LCD_ALERTMESSAGEPGM("Err: MAXTEMP");
  798. }
  799. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  800. Stop();
  801. #endif
  802. }
  803. void min_temp_error(uint8_t e) {
  804. disable_heater();
  805. if(IsStopped() == false) {
  806. SERIAL_ERROR_START;
  807. SERIAL_ERRORLN((int)e);
  808. SERIAL_ERRORLNPGM(": Extruder switched off. MINTEMP triggered !");
  809. LCD_ALERTMESSAGEPGM("Err: MINTEMP");
  810. }
  811. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  812. Stop();
  813. #endif
  814. }
  815. void bed_max_temp_error(void) {
  816. #if HEATER_BED_PIN > -1
  817. WRITE(HEATER_BED_PIN, 0);
  818. #endif
  819. if(IsStopped() == false) {
  820. SERIAL_ERROR_START;
  821. SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!");
  822. LCD_ALERTMESSAGEPGM("Err: MAXTEMP BED");
  823. }
  824. #ifndef BOGUS_TEMPERATURE_FAILSAFE_OVERRIDE
  825. Stop();
  826. #endif
  827. }
  828. #ifdef HEATER_0_USES_MAX6675
  829. #define MAX6675_HEAT_INTERVAL 250
  830. long max6675_previous_millis = -HEAT_INTERVAL;
  831. int max6675_temp = 2000;
  832. int read_max6675()
  833. {
  834. if (millis() - max6675_previous_millis < MAX6675_HEAT_INTERVAL)
  835. return max6675_temp;
  836. max6675_previous_millis = millis();
  837. max6675_temp = 0;
  838. #ifdef PRR
  839. PRR &= ~(1<<PRSPI);
  840. #elif defined PRR0
  841. PRR0 &= ~(1<<PRSPI);
  842. #endif
  843. SPCR = (1<<MSTR) | (1<<SPE) | (1<<SPR0);
  844. // enable TT_MAX6675
  845. WRITE(MAX6675_SS, 0);
  846. // ensure 100ns delay - a bit extra is fine
  847. asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
  848. asm("nop");//50ns on 20Mhz, 62.5ns on 16Mhz
  849. // read MSB
  850. SPDR = 0;
  851. for (;(SPSR & (1<<SPIF)) == 0;);
  852. max6675_temp = SPDR;
  853. max6675_temp <<= 8;
  854. // read LSB
  855. SPDR = 0;
  856. for (;(SPSR & (1<<SPIF)) == 0;);
  857. max6675_temp |= SPDR;
  858. // disable TT_MAX6675
  859. WRITE(MAX6675_SS, 1);
  860. if (max6675_temp & 4)
  861. {
  862. // thermocouple open
  863. max6675_temp = 2000;
  864. }
  865. else
  866. {
  867. max6675_temp = max6675_temp >> 3;
  868. }
  869. return max6675_temp;
  870. }
  871. #endif
  872. // Timer 0 is shared with millies
  873. ISR(TIMER0_COMPB_vect)
  874. {
  875. //these variables are only accesible from the ISR, but static, so they don't loose their value
  876. static unsigned char temp_count = 0;
  877. static unsigned long raw_temp_0_value = 0;
  878. static unsigned long raw_temp_1_value = 0;
  879. static unsigned long raw_temp_2_value = 0;
  880. static unsigned long raw_temp_bed_value = 0;
  881. static unsigned char temp_state = 0;
  882. static unsigned char pwm_count = 1;
  883. static unsigned char soft_pwm_0;
  884. #if EXTRUDERS > 1
  885. static unsigned char soft_pwm_1;
  886. #endif
  887. #if EXTRUDERS > 2
  888. static unsigned char soft_pwm_2;
  889. #endif
  890. #if HEATER_BED_PIN > -1
  891. static unsigned char soft_pwm_b;
  892. #endif
  893. if(pwm_count == 0){
  894. soft_pwm_0 = soft_pwm[0];
  895. if(soft_pwm_0 > 0) WRITE(HEATER_0_PIN,1);
  896. #if EXTRUDERS > 1
  897. soft_pwm_1 = soft_pwm[1];
  898. if(soft_pwm_1 > 0) WRITE(HEATER_1_PIN,1);
  899. #endif
  900. #if EXTRUDERS > 2
  901. soft_pwm_2 = soft_pwm[2];
  902. if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1);
  903. #endif
  904. #if HEATER_BED_PIN > -1
  905. soft_pwm_b = soft_pwm_bed;
  906. if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1);
  907. #endif
  908. #ifdef FAN_SOFT_PWM
  909. soft_pwm_fan =(unsigned char) fanSpeed;
  910. if(soft_pwm_fan > 0) WRITE(FAN_PIN,1);
  911. #endif
  912. }
  913. if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0);
  914. #if EXTRUDERS > 1
  915. if(soft_pwm_1 <= pwm_count) WRITE(HEATER_1_PIN,0);
  916. #endif
  917. #if EXTRUDERS > 2
  918. if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0);
  919. #endif
  920. #if HEATER_BED_PIN > -1
  921. if(soft_pwm_b <= pwm_count) WRITE(HEATER_BED_PIN,0);
  922. #endif
  923. #ifdef FAN_SOFT_PWM
  924. if(soft_pwm_fan <= pwm_count) WRITE(FAN_PIN,0);
  925. #endif
  926. pwm_count++;
  927. pwm_count &= 0x7f;
  928. switch(temp_state) {
  929. case 0: // Prepare TEMP_0
  930. #if (TEMP_0_PIN > -1)
  931. #if TEMP_0_PIN > 7
  932. ADCSRB = 1<<MUX5;
  933. #else
  934. ADCSRB = 0;
  935. #endif
  936. ADMUX = ((1 << REFS0) | (TEMP_0_PIN & 0x07));
  937. ADCSRA |= 1<<ADSC; // Start conversion
  938. #endif
  939. lcd_buttons_update();
  940. temp_state = 1;
  941. break;
  942. case 1: // Measure TEMP_0
  943. #if (TEMP_0_PIN > -1)
  944. raw_temp_0_value += ADC;
  945. #endif
  946. #ifdef HEATER_0_USES_MAX6675 // TODO remove the blocking
  947. raw_temp_0_value = read_max6675();
  948. #endif
  949. temp_state = 2;
  950. break;
  951. case 2: // Prepare TEMP_BED
  952. #if (TEMP_BED_PIN > -1)
  953. #if TEMP_BED_PIN > 7
  954. ADCSRB = 1<<MUX5;
  955. #else
  956. ADCSRB = 0;
  957. #endif
  958. ADMUX = ((1 << REFS0) | (TEMP_BED_PIN & 0x07));
  959. ADCSRA |= 1<<ADSC; // Start conversion
  960. #endif
  961. lcd_buttons_update();
  962. temp_state = 3;
  963. break;
  964. case 3: // Measure TEMP_BED
  965. #if (TEMP_BED_PIN > -1)
  966. raw_temp_bed_value += ADC;
  967. #endif
  968. temp_state = 4;
  969. break;
  970. case 4: // Prepare TEMP_1
  971. #if (TEMP_1_PIN > -1)
  972. #if TEMP_1_PIN > 7
  973. ADCSRB = 1<<MUX5;
  974. #else
  975. ADCSRB = 0;
  976. #endif
  977. ADMUX = ((1 << REFS0) | (TEMP_1_PIN & 0x07));
  978. ADCSRA |= 1<<ADSC; // Start conversion
  979. #endif
  980. lcd_buttons_update();
  981. temp_state = 5;
  982. break;
  983. case 5: // Measure TEMP_1
  984. #if (TEMP_1_PIN > -1)
  985. raw_temp_1_value += ADC;
  986. #endif
  987. temp_state = 6;
  988. break;
  989. case 6: // Prepare TEMP_2
  990. #if (TEMP_2_PIN > -1)
  991. #if TEMP_2_PIN > 7
  992. ADCSRB = 1<<MUX5;
  993. #else
  994. ADCSRB = 0;
  995. #endif
  996. ADMUX = ((1 << REFS0) | (TEMP_2_PIN & 0x07));
  997. ADCSRA |= 1<<ADSC; // Start conversion
  998. #endif
  999. lcd_buttons_update();
  1000. temp_state = 7;
  1001. break;
  1002. case 7: // Measure TEMP_2
  1003. #if (TEMP_2_PIN > -1)
  1004. raw_temp_2_value += ADC;
  1005. #endif
  1006. temp_state = 0;
  1007. temp_count++;
  1008. break;
  1009. // default:
  1010. // SERIAL_ERROR_START;
  1011. // SERIAL_ERRORLNPGM("Temp measurement error!");
  1012. // break;
  1013. }
  1014. if(temp_count >= 16) // 8 ms * 16 = 128ms.
  1015. {
  1016. if (!temp_meas_ready) //Only update the raw values if they have been read. Else we could be updating them during reading.
  1017. {
  1018. current_temperature_raw[0] = raw_temp_0_value;
  1019. #if EXTRUDERS > 1
  1020. current_temperature_raw[1] = raw_temp_1_value;
  1021. #endif
  1022. #if EXTRUDERS > 2
  1023. current_temperature_raw[2] = raw_temp_2_value;
  1024. #endif
  1025. current_temperature_bed_raw = raw_temp_bed_value;
  1026. }
  1027. temp_meas_ready = true;
  1028. temp_count = 0;
  1029. raw_temp_0_value = 0;
  1030. raw_temp_1_value = 0;
  1031. raw_temp_2_value = 0;
  1032. raw_temp_bed_value = 0;
  1033. #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
  1034. if(current_temperature_raw[0] <= maxttemp_raw[0]) {
  1035. #else
  1036. if(current_temperature_raw[0] >= maxttemp_raw[0]) {
  1037. #endif
  1038. max_temp_error(0);
  1039. }
  1040. #if HEATER_0_RAW_LO_TEMP > HEATER_0_RAW_HI_TEMP
  1041. if(current_temperature_raw[0] >= minttemp_raw[0]) {
  1042. #else
  1043. if(current_temperature_raw[0] <= minttemp_raw[0]) {
  1044. #endif
  1045. min_temp_error(0);
  1046. }
  1047. #if EXTRUDERS > 1
  1048. #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
  1049. if(current_temperature_raw[1] <= maxttemp_raw[1]) {
  1050. #else
  1051. if(current_temperature_raw[1] >= maxttemp_raw[1]) {
  1052. #endif
  1053. max_temp_error(1);
  1054. }
  1055. #if HEATER_1_RAW_LO_TEMP > HEATER_1_RAW_HI_TEMP
  1056. if(current_temperature_raw[1] >= minttemp_raw[1]) {
  1057. #else
  1058. if(current_temperature_raw[1] <= minttemp_raw[1]) {
  1059. #endif
  1060. min_temp_error(1);
  1061. }
  1062. #endif
  1063. #if EXTRUDERS > 2
  1064. #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
  1065. if(current_temperature_raw[2] <= maxttemp_raw[2]) {
  1066. #else
  1067. if(current_temperature_raw[2] >= maxttemp_raw[2]) {
  1068. #endif
  1069. max_temp_error(2);
  1070. }
  1071. #if HEATER_2_RAW_LO_TEMP > HEATER_2_RAW_HI_TEMP
  1072. if(current_temperature_raw[2] >= minttemp_raw[2]) {
  1073. #else
  1074. if(current_temperature_raw[2] <= minttemp_raw[2]) {
  1075. #endif
  1076. min_temp_error(2);
  1077. }
  1078. #endif
  1079. /* No bed MINTEMP error? */
  1080. #if defined(BED_MAXTEMP) && (TEMP_SENSOR_BED != 0)
  1081. # if HEATER_BED_RAW_LO_TEMP > HEATER_BED_RAW_HI_TEMP
  1082. if(current_temperature_bed_raw <= bed_maxttemp_raw) {
  1083. #else
  1084. if(current_temperature_bed_raw >= bed_maxttemp_raw) {
  1085. #endif
  1086. target_temperature_bed = 0;
  1087. bed_max_temp_error();
  1088. }
  1089. #endif
  1090. }
  1091. }
  1092. #ifdef PIDTEMP
  1093. // Apply the scale factors to the PID values
  1094. float scalePID_i(float i)
  1095. {
  1096. return i*PID_dT;
  1097. }
  1098. float unscalePID_i(float i)
  1099. {
  1100. return i/PID_dT;
  1101. }
  1102. float scalePID_d(float d)
  1103. {
  1104. return d/PID_dT;
  1105. }
  1106. float unscalePID_d(float d)
  1107. {
  1108. return d*PID_dT;
  1109. }
  1110. #endif //PIDTEMP