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 35KB

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