chiark / gitweb /
Fixed AUTOTEMP (M109 S215 B260 F1 starts autotemp)
authorErik van der Zalm <erik@vdzalm.eu>
Sun, 15 Apr 2012 17:17:33 +0000 (19:17 +0200)
committerErik van der Zalm <erik@vdzalm.eu>
Sun, 15 Apr 2012 17:17:33 +0000 (19:17 +0200)
Changed SLOWDOWN. IF this does not work ok OLD_SLOWDOWN is the old algo.

Marlin/Configuration.h
Marlin/Configuration_adv.h
Marlin/Marlin.h
Marlin/Marlin.pde
Marlin/planner.cpp
Marlin/stepper.cpp
Marlin/temperature.cpp

index 2adda3fd612074cc7af8ec030a2fc15924ef7513..18942a5a6c9f535ee8c244c20d0e9d1b48283163 100644 (file)
 const bool X_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops. 
 const bool Y_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops. 
 const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of the endstops. 
-#define DISABLE_MAX_ENDSTOPS
+//#define DISABLE_MAX_ENDSTOPS
 
 // For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
 #define X_ENABLE_ON 0
@@ -165,7 +165,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
 
 // default settings 
 
-#define DEFAULT_AXIS_STEPS_PER_UNIT   {78.7402,78.7402,200*8/3,760*1.1}                    // default steps per unit for ultimaker 
+#define DEFAULT_AXIS_STEPS_PER_UNIT   {78.7402,78.7402,200*8/3,760*1.1}  // default steps per unit for ultimaker 
 #define DEFAULT_MAX_FEEDRATE          {500, 500, 5, 45}    // (mm/sec)    
 #define DEFAULT_MAX_ACCELERATION      {9000,9000,100,10000}    // X, Y, Z, E maximum start speed for accelerated moves. E default values are good for skeinforge 40+, for older versions raise them a lot.
 
@@ -196,7 +196,7 @@ const bool Z_ENDSTOPS_INVERTING = true; // set to true to invert the logic of th
 //#define ULTRA_LCD  //general lcd support, also 16x2
 //#define SDSUPPORT // Enable SD Card Support in Hardware Console
 
-//#define ULTIPANEL
+#define ULTIPANEL
 #ifdef ULTIPANEL
 //  #define NEWPANEL  //enable this if you have a click-encoder panel
   #define SDSUPPORT
index 9a7acdf943bbb81167d2d5937bd1d80c0cc36820..d796a0829127ba3e23230d713d04814e0351b1fb 100644 (file)
@@ -41,8 +41,8 @@
 // the target temperature is set to mintemp+factor*se[steps/sec] and limited by mintemp and maxtemp
 // you exit the value by any M109 without F*
 // Also, if the temperature is set to a value <mintemp, it is not changed by autotemp.
-// on an ultimaker, some initial testing worked with M109 S215 T260 F0.1 in the start.gcode
-//#define AUTOTEMP
+// on an ultimaker, some initial testing worked with M109 S215 B260 F1 in the start.gcode
+#define AUTOTEMP
 #ifdef AUTOTEMP
   #define AUTOTEMP_OLDWEIGHT 0.98
 #endif
@@ -94,8 +94,8 @@
 #define DEFAULT_MINIMUMFEEDRATE       0.0     // minimum feedrate
 #define DEFAULT_MINTRAVELFEEDRATE     0.0
 
-// minimum time in microseconds that a movement needs to take if the buffer is emptied.   Increase this number if you see blobs while printing high speed & high detail.  It will slowdown on the detailed stuff.
-#define DEFAULT_MINSEGMENTTIME        20000   // Obsolete delete this
+// minimum time in microseconds that a movement needs to take if the buffer is emptied.
+#define DEFAULT_MINSEGMENTTIME        20000
 
 // If defined the movements slow down when the look ahead buffer is only half full
 #define SLOWDOWN
 
 #endif // ADVANCE
 
-// A debugging feature to compare calculated vs performed steps, to see if steps are lost by the software.
-//#define DEBUG_STEPS
-
 // Arc interpretation settings:
 #define MM_PER_ARC_SEGMENT 1
 #define N_ARC_CORRECTION 25
index c30c5da43cffd6f1304a38aafdcb0bb613464fe1..d1169f4ef7a2b3005f5718e062a10f6cea0ab54b 100644 (file)
@@ -64,6 +64,7 @@
 
 
 #define SERIAL_PROTOCOL(x) MYSERIAL.print(x);
+#define SERIAL_PROTOCOL_F(x,y) MYSERIAL.print(x,y);
 #define SERIAL_PROTOCOLPGM(x) serialprintPGM(MYPGM(x));
 #define SERIAL_PROTOCOLLN(x) {MYSERIAL.print(x);MYSERIAL.write('\n');}
 #define SERIAL_PROTOCOLLNPGM(x) {serialprintPGM(MYPGM(x));MYSERIAL.write('\n');}
index 7d1c6457caccf93e28cdf8703e644ab2d77876d1..083e803524a38c15ae6642a5ef3fa52087ffba13 100644 (file)
@@ -849,14 +849,14 @@ void process_commands()
       }
       #if (TEMP_0_PIN > -1)
         SERIAL_PROTOCOLPGM("ok T:");
-        SERIAL_PROTOCOL(degHotend(tmp_extruder)); 
-        //SERIAL_PROTOCOLPGM("/");
-        //SERIAL_PROTOCOL(degTargetHotend(tmp_extruder)); 
+        SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1); 
+        SERIAL_PROTOCOLPGM(" /");
+        SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder),1); 
         #if TEMP_BED_PIN > -1
           SERIAL_PROTOCOLPGM(" B:");  
-          SERIAL_PROTOCOL(degBed());
-          //SERIAL_PROTOCOLPGM("/");
-          //SERIAL_PROTOCOL(degTargetBed());
+          SERIAL_PROTOCOL_F(degBed(),1);
+          SERIAL_PROTOCOLPGM(" /");
+          SERIAL_PROTOCOL_F(degTargetBed(),1);
         #endif //TEMP_BED_PIN
       #else
         SERIAL_ERROR_START;
@@ -888,7 +888,7 @@ void process_commands()
       if (code_seen('S')) setTargetHotend(code_value(), tmp_extruder);
       #ifdef AUTOTEMP
         if (code_seen('S')) autotemp_min=code_value();
-        if (code_seen('G')) autotemp_max=code_value();
+        if (code_seen('B')) autotemp_max=code_value();
         if (code_seen('F')) 
         {
           autotemp_factor=code_value();
@@ -915,9 +915,9 @@ void process_commands()
           if( (millis() - codenum) > 1000UL )
           { //Print Temp Reading and remaining time every 1 second while heating up/cooling down
             SERIAL_PROTOCOLPGM("T:");
-            SERIAL_PROTOCOL( degHotend(tmp_extruder) ); 
+            SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1); 
             SERIAL_PROTOCOLPGM(" E:");
-            SERIAL_PROTOCOL( (int)tmp_extruder ); 
+            SERIAL_PROTOCOL((int)tmp_extruder); 
             #ifdef TEMP_RESIDENCY_TIME
               SERIAL_PROTOCOLPGM(" W:");
               if(residencyStart > -1)
@@ -966,9 +966,10 @@ void process_commands()
             SERIAL_PROTOCOLPGM("T:");
             SERIAL_PROTOCOL(tt);
             SERIAL_PROTOCOLPGM(" E:");
-            SERIAL_PROTOCOL( (int)active_extruder ); 
+            SERIAL_PROTOCOL((int)active_extruder); 
             SERIAL_PROTOCOLPGM(" B:");
-            SERIAL_PROTOCOLLN(degBed()); 
+            SERIAL_PROTOCOL_F(degBed(),1); 
+            SERIAL_PROTOCOLLN(""); 
             codenum = millis(); 
           }
           manage_heater();
@@ -1058,7 +1059,20 @@ void process_commands()
       for(int8_t i=0; i < NUM_AXIS; i++) 
       {
         if(code_seen(axis_codes[i])) 
-          axis_steps_per_unit[i] = code_value();
+          
+          if(i == 3) { // E
+            float value = code_value();
+            if(value < 20.0) {
+              float factor = axis_steps_per_unit[i] / value; // increase e constants if M92 E14 is given for netfab.
+              max_e_jerk *= factor;
+              max_feedrate[i] *= factor;
+              axis_steps_per_sqr_second[i] *= factor;
+            }
+            axis_steps_per_unit[i] = value;
+          }
+          else {
+            axis_steps_per_unit[i] = code_value();
+          }
       }
       break;
     case 115: // M115
index 46adece87b7f81d5c0a283af920e52f6f468a6f8..cfb503deb8138d08e57790250973c9d1a2f5a53d 100644 (file)
@@ -51,9 +51,6 @@
     IntersectionDistance[s1_, s2_, a_, d_] := (2 a d - s1^2 + s2^2)/(4 a)
 */
                                                                                                             
-
-
-
 #include "Marlin.h"
 #include "planner.h"
 #include "stepper.h"
@@ -377,20 +374,26 @@ void plan_init() {
 void getHighESpeed()
 {
   static float oldt=0;
-  if(!autotemp_enabled)
+  if(!autotemp_enabled){
     return;
-  if(degTargetHotend0()+2<autotemp_min)  //probably temperature set to zero.
+  }
+  if(degTargetHotend0()+2<autotemp_min) {  //probably temperature set to zero.
     return; //do nothing
+  }
   
-  float high=0;
+  float high=0.0;
   uint8_t block_index = block_buffer_tail;
   
   while(block_index != block_buffer_head) {
-    float se=block_buffer[block_index].steps_e/float(block_buffer[block_index].step_event_count)*block_buffer[block_index].nominal_rate;
-    //se; units steps/sec;
-    if(se>high)
-    {
-      high=se;
+    if((block_buffer[block_index].steps_x != 0) ||
+       (block_buffer[block_index].steps_y != 0) ||
+       (block_buffer[block_index].steps_z != 0)) {
+      float se=(float(block_buffer[block_index].steps_e)/float(block_buffer[block_index].step_event_count))*block_buffer[block_index].nominal_speed;
+      //se; mm/sec;
+      if(se>high)
+      {
+        high=se;
+      }
     }
     block_index = (block_index+1) & (BLOCK_BUFFER_SIZE - 1);
   }
@@ -407,10 +410,6 @@ void getHighESpeed()
   }
   oldt=t;
   setTargetHotend0(t);
-//   SERIAL_ECHO_START;
-//   SERIAL_ECHOPAIR("highe",high);
-//   SERIAL_ECHOPAIR(" t",t);
-//   SERIAL_ECHOLN("");
 }
 #endif
 
@@ -456,6 +455,9 @@ void check_axes_activity() {
     analogWrite(FAN_PIN,tail_fan_speed);
   }
   #endif
+  #ifdef AUTOTEMP
+    getHighESpeed();
+  #endif
 }
 
 
@@ -517,7 +519,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
   block->step_event_count = max(block->steps_x, max(block->steps_y, max(block->steps_z, block->steps_e)));
 
   // Bail if this is a zero-length block
-  if (block->step_event_count <=dropsegments) { return; };
+  if (block->step_event_count <= dropsegments) { return; };
 
   block->fan_speed = FanSpeed;
   
@@ -540,7 +542,6 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
   // Enable all
   if(block->steps_e != 0) { enable_e0();enable_e1();enable_e2(); }
 
-
   if (block->steps_e == 0) {
         if(feed_rate<mintravelfeedrate) feed_rate=mintravelfeedrate;
   }
@@ -548,12 +549,6 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
        if(feed_rate<minimumfeedrate) feed_rate=minimumfeedrate;
   } 
   
-  // slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill
-  int moves_queued=(block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1);
-  #ifdef SLOWDOWN
-    if(moves_queued < (BLOCK_BUFFER_SIZE * 0.5) && moves_queued > 1) feed_rate = feed_rate*moves_queued / (BLOCK_BUFFER_SIZE * 0.5); 
-  #endif
-
   float delta_mm[4];
   delta_mm[X_AXIS] = (target[X_AXIS]-position[X_AXIS])/axis_steps_per_unit[X_AXIS];
   delta_mm[Y_AXIS] = (target[Y_AXIS]-position[Y_AXIS])/axis_steps_per_unit[Y_AXIS];
@@ -569,34 +564,33 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
   // Calculate speed in mm/second for each axis. No divide by zero due to previous checks.
   float inverse_second = feed_rate * inverse_millimeters;
   
-  block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0
-  block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0
-
+  int moves_queued=(block_buffer_head-block_buffer_tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1);
+  // slow down when de buffer starts to empty, rather than wait at the corner for a buffer refill
+  #ifdef OLD_SLOWDOWN
+    if(moves_queued < (BLOCK_BUFFER_SIZE * 0.5) && moves_queued > 1) feed_rate = feed_rate*moves_queued / (BLOCK_BUFFER_SIZE * 0.5); 
+  #endif
 
-/*
+  #ifdef SLOWDOWN
   //  segment time im micro seconds
-  long segment_time = lround(1000000.0/inverse_second);
-  if ((blockcount>0) && (blockcount < (BLOCK_BUFFER_SIZE - 4))) {
-    if (segment_time<minsegmenttime)  { // buffer is draining, add extra time.  The amount of time added increases if the buffer is still emptied more.
-        segment_time=segment_time+lround(2*(minsegmenttime-segment_time)/blockcount);
+  unsigned long segment_time = lround(1000000.0/inverse_second);
+  if ((moves_queued > 1) && (moves_queued < (BLOCK_BUFFER_SIZE * 0.5))) {
+    if (segment_time < minsegmenttime)  { // buffer is draining, add extra time.  The amount of time added increases if the buffer is still emptied more.
+        inverse_second=1000000.0/(segment_time+lround(2*(minsegmenttime-segment_time)/moves_queued));
     }
   }
-  else {
-    if (segment_time<minsegmenttime) segment_time=minsegmenttime;
-  }
+  #endif
   //  END OF SLOW DOWN SECTION    
-*/
 
+  
+  block->nominal_speed = block->millimeters * inverse_second; // (mm/sec) Always > 0
+  block->nominal_rate = ceil(block->step_event_count * inverse_second); // (step/sec) Always > 0
 
- // Calculate speed in mm/sec for each axis
+ // Calculate and limit speed in mm/sec for each axis
   float current_speed[4];
-  for(int i=0; i < 4; i++) {
-    current_speed[i] = delta_mm[i] * inverse_second;
-  }
-
-  // Limit speed per axis
   float speed_factor = 1.0; //factor <=1 do decrease speed
   for(int i=0; i < 4; i++) {
+    current_speed[i] = delta_mm[i] * inverse_second;
     if(abs(current_speed[i]) > max_feedrate[i])
       speed_factor = min(speed_factor, max_feedrate[i] / abs(current_speed[i]));
   }
@@ -633,17 +627,6 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
 
   // Correct the speed  
   if( speed_factor < 1.0) {
-//    Serial.print("speed factor : "); Serial.println(speed_factor);
-    for(int i=0; i < 4; i++) {
-    if(abs(current_speed[i]) > max_feedrate[i])
-      speed_factor = min(speed_factor, max_feedrate[i] / abs(current_speed[i]));
- /*     
-      if(speed_factor < 0.1) {
-        Serial.print("speed factor : "); Serial.println(speed_factor);
-        Serial.print("current_speed"); Serial.print(i); Serial.print(" : "); Serial.println(current_speed[i]);
-      }
- */
-  }
     for(unsigned char i=0; i < 4; i++) {
       current_speed[i] *= speed_factor;
     }
@@ -784,9 +767,6 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
     */
   #endif // ADVANCE
 
-
-
-
   calculate_trapezoid_for_block(block, block->entry_speed/block->nominal_speed,
     MINIMUM_PLANNER_SPEED/block->nominal_speed);
     
@@ -797,9 +777,7 @@ void plan_buffer_line(const float &x, const float &y, const float &z, const floa
   memcpy(position, target, sizeof(target)); // position[] = target[]
 
   planner_recalculate();
-  #ifdef AUTOTEMP
-    getHighESpeed();
-  #endif
+
   st_wake_up();
 }
 
index e9b42f45ded0aa546c36c7967ec1ce88db3ac485..29be5c6d9d972ad2ff50721b7a051adda10bf997 100644 (file)
@@ -54,7 +54,6 @@ volatile static unsigned long step_events_completed; // The number of step event
   static long old_advance = 0;
 #endif
 static long e_steps[3];
-static unsigned char busy = false; // TRUE when SIG_OUTPUT_COMPARE1A is being serviced. Used to avoid retriggering that handler.
 static long acceleration_time, deceleration_time;
 //static unsigned long accelerate_until, decelerate_after, acceleration_rate, initial_rate, final_rate, nominal_rate;
 static unsigned short acc_step_rate; // needed for deccelaration start point
@@ -216,7 +215,6 @@ void enable_endstops(bool check)
 
 void st_wake_up() {
   //  TCNT1 = 0;
-  if(busy == false) 
   ENABLE_STEPPER_DRIVER_INTERRUPT();  
 }
 
@@ -295,6 +293,7 @@ ISR(TIMER1_COMPA_vect)
     // Anything in the buffer?
     current_block = plan_get_current_block();
     if (current_block != NULL) {
+      current_block->busy = true;
       trapezoid_generator_reset();
       counter_x = -(current_block->step_event_count >> 1);
       counter_y = counter_x;
@@ -773,12 +772,7 @@ void st_init()
     TIMSK0 |= (1<<OCIE0A);
   #endif //ADVANCE
   
-  #ifdef ENDSTOPS_ONLY_FOR_HOMING
-    enable_endstops(false);
-  #else
-    enable_endstops(true);
-  #endif
-  
+  enable_endstops(true); // Start with endstops active. After homing they can be disabled
   sei();
 }
 
index 62e84b1fda6a4fc753c476f17019cd17082d7186..a8ec619a20db915f6a8b5f2d9f180c0ffad6710e 100644 (file)
@@ -95,17 +95,6 @@ static unsigned long  previous_millis_bed_heater;
   static int maxttemp[EXTRUDERS] = { 16383 }; // the first value used for all
   static int bed_minttemp = 0;
   static int bed_maxttemp = 16383;
-  static int heater_pin_map[EXTRUDERS] = { HEATER_0_PIN
-#if EXTRUDERS > 1
-                                         , HEATER_1_PIN
-#endif
-#if EXTRUDERS > 2
-                                         , HEATER_2_PIN
-#endif
-#if EXTRUDERS > 3
-  #error Unsupported number of extruders
-#endif
-  };
   static void *heater_ttbl_map[EXTRUDERS] = { (void *)heater_0_temptable
 #if EXTRUDERS > 1
                                             , (void *)heater_1_temptable
@@ -138,7 +127,6 @@ void PID_autotune(float temp)
   float input;
   int cycles=0;
   bool heating = true;
-  soft_pwm[0] = 255>>1;
 
   unsigned long temp_millis = millis();
   unsigned long t1=temp_millis;
@@ -154,8 +142,10 @@ void PID_autotune(float temp)
   
   SERIAL_ECHOLN("PID Autotune start");
   
-  //disable_heater(); // switch off all heaters.
+  disable_heater(); // switch off all heaters.
   
+  soft_pwm[0] = 255>>1;
+    
   for(;;) {
 
     if(temp_meas_ready == true) { // temp sample ready
@@ -202,6 +192,7 @@ void PID_autotune(float temp)
               SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
               SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
               SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
+              /*
               Kp = 0.33*Ku;
               Ki = Kp/Tu;
               Kd = Kp*Tu/3;
@@ -216,6 +207,7 @@ void PID_autotune(float temp)
               SERIAL_PROTOCOLPGM(" Kp: "); SERIAL_PROTOCOLLN(Kp);
               SERIAL_PROTOCOLPGM(" Ki: "); SERIAL_PROTOCOLLN(Ki);
               SERIAL_PROTOCOLPGM(" Kd: "); SERIAL_PROTOCOLLN(Kd);
+              */
             }
           }
           soft_pwm[0] = (bias + d) >> 1;
@@ -225,7 +217,7 @@ void PID_autotune(float temp)
       } 
     }
     if(input > (temp + 20)) {
-      SERIAL_PROTOCOLLNPGM("PID Autotune failed !, Temperature to high");
+      SERIAL_PROTOCOLLNPGM("PID Autotune failed! Temperature to high");
       return;
     }
     if(millis() - temp_millis > 2000) {
@@ -235,6 +227,14 @@ void PID_autotune(float temp)
       SERIAL_PROTOCOLPGM(" @:");
       SERIAL_PROTOCOLLN(getHeaterPower(0));       
     }
+    if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
+      SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
+      return;
+    }
+    if(cycles > 5) {
+      SERIAL_PROTOCOLLNPGM("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h");
+      return;
+    }
     LCD_STATUS;
   }
 }
@@ -313,11 +313,9 @@ void manage_heater()
     // Check if temperature is within the correct range
     if((current_raw[e] > minttemp[e]) && (current_raw[e] < maxttemp[e])) 
     {
-      //analogWrite(heater_pin_map[e], pid_output);
       soft_pwm[e] = (int)pid_output >> 1;
     }
     else {
-      //analogWrite(heater_pin_map[e], 0);
       soft_pwm[e] = 0;
     }
   } // End extruder for loop
@@ -680,7 +678,7 @@ void disable_heater()
   target_raw[0]=0;
   soft_pwm[0]=0;
    #if HEATER_0_PIN > -1  
-     digitalWrite(HEATER_0_PIN,LOW);
+     WRITE(HEATER_0_PIN,LOW);
    #endif
   #endif
      
@@ -688,7 +686,7 @@ void disable_heater()
     target_raw[1]=0;
     soft_pwm[1]=0;
     #if HEATER_1_PIN > -1 
-      digitalWrite(HEATER_1_PIN,LOW);
+      WRITE(HEATER_1_PIN,LOW);
     #endif
   #endif
       
@@ -696,20 +694,20 @@ void disable_heater()
     target_raw[2]=0;
     soft_pwm[2]=0;
     #if HEATER_2_PIN > -1  
-      digitalWrite(HEATER_2_PIN,LOW);
+      WRITE(HEATER_2_PIN,LOW);
     #endif
   #endif 
 
   #if TEMP_BED_PIN > -1
     target_raw_bed=0;
     #if HEATER_BED_PIN > -1  
-      digitalWrite(HEATER_BED_PIN,LOW);
+      WRITE(HEATER_BED_PIN,LOW);
     #endif
   #endif 
 }
 
 void max_temp_error(uint8_t e) {
-  digitalWrite(heater_pin_map[e], 0);
+  disable_heater();
   if(IsStopped() == false) {
     SERIAL_ERROR_START;
     SERIAL_ERRORLN(e);
@@ -718,7 +716,7 @@ void max_temp_error(uint8_t e) {
 }
 
 void min_temp_error(uint8_t e) {
-  digitalWrite(heater_pin_map[e], 0);
+  disable_heater();
   if(IsStopped() == false) {
     SERIAL_ERROR_START;
     SERIAL_ERRORLN(e);
@@ -727,7 +725,7 @@ void min_temp_error(uint8_t e) {
 }
 
 void bed_max_temp_error(void) {
-  digitalWrite(HEATER_BED_PIN, 0);
+  WRITE(HEATER_BED_PIN, 0);
   if(IsStopped() == false) {
     SERIAL_ERROR_START;
     SERIAL_ERRORLNPGM("Temperature heated bed switched off. MAXTEMP triggered !!");