My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

temperature.cpp 37KB

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