bed pid
Conflicts: Marlin/Configuration.h
This commit is contained in:
		@@ -95,10 +95,11 @@
 | 
				
			|||||||
// PID settings:
 | 
					// PID settings:
 | 
				
			||||||
// Comment the following line to disable PID and enable bang-bang.
 | 
					// Comment the following line to disable PID and enable bang-bang.
 | 
				
			||||||
#define PIDTEMP
 | 
					#define PIDTEMP
 | 
				
			||||||
 | 
					#define PIDTEMPBED
 | 
				
			||||||
#define PID_MAX 255 // limits current to nozzle; 255=full current
 | 
					#define PID_MAX 255 // limits current to nozzle; 255=full current
 | 
				
			||||||
#ifdef PIDTEMP
 | 
					#ifdef PIDTEMP
 | 
				
			||||||
  //#define PID_DEBUG // Sends debug data to the serial port. 
 | 
					  //#define PID_DEBUG // Sends debug data to the serial port. 
 | 
				
			||||||
  //#define PID_OPENLOOP 1 // Puts PID in open loop. M104 sets the output power in %
 | 
					  //#define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
 | 
				
			||||||
  #define PID_INTEGRAL_DRIVE_MAX 255  //limit for the integral term
 | 
					  #define PID_INTEGRAL_DRIVE_MAX 255  //limit for the integral term
 | 
				
			||||||
  #define K1 0.95 //smoothing factor withing the PID
 | 
					  #define K1 0.95 //smoothing factor withing the PID
 | 
				
			||||||
  #define PID_dT ((16.0 * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the
 | 
					  #define PID_dT ((16.0 * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the
 | 
				
			||||||
@@ -114,6 +115,16 @@
 | 
				
			|||||||
//    #define  DEFAULT_Ki 0.1  
 | 
					//    #define  DEFAULT_Ki 0.1  
 | 
				
			||||||
//    #define  DEFAULT_Kd 12  
 | 
					//    #define  DEFAULT_Kd 12  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, argressive factor of .15 (vs .1, 1, 10)
 | 
				
			||||||
 | 
					    #define  DEFAULT_bedKp 10.00
 | 
				
			||||||
 | 
					    #define  DEFAULT_bedKi .023
 | 
				
			||||||
 | 
					    #define  DEFAULT_bedKd 305.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//mark from pidautotune
 | 
				
			||||||
 | 
					//    #define  DEFAULT_bedKp 97.1
 | 
				
			||||||
 | 
					//    #define  DEFAULT_bedKi 1.41
 | 
				
			||||||
 | 
					//    #define  DEFAULT_bedKd 1675.16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Mendel Parts V9 on 12V    
 | 
					// Mendel Parts V9 on 12V    
 | 
				
			||||||
//    #define  DEFAULT_Kp 63.0
 | 
					//    #define  DEFAULT_Kp 63.0
 | 
				
			||||||
//    #define  DEFAULT_Ki 2.25
 | 
					//    #define  DEFAULT_Ki 2.25
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -113,6 +113,7 @@
 | 
				
			|||||||
// M221 S<factor in percent>- set extrude factor override percentage
 | 
					// M221 S<factor in percent>- set extrude factor override percentage
 | 
				
			||||||
// M240 - Trigger a camera to take a photograph
 | 
					// M240 - Trigger a camera to take a photograph
 | 
				
			||||||
// M301 - Set PID parameters P I and D
 | 
					// M301 - Set PID parameters P I and D
 | 
				
			||||||
 | 
					// M304 - Set bed PID parameters P I and D
 | 
				
			||||||
// M302 - Allow cold extrudes
 | 
					// M302 - Allow cold extrudes
 | 
				
			||||||
// M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
 | 
					// M303 - PID relay autotune S<temperature> sets the target temperature. (default target temperature = 150C)
 | 
				
			||||||
// M400 - Finish all moves
 | 
					// M400 - Finish all moves
 | 
				
			||||||
@@ -1002,6 +1003,10 @@ void process_commands()
 | 
				
			|||||||
      #ifdef PIDTEMP
 | 
					      #ifdef PIDTEMP
 | 
				
			||||||
        SERIAL_PROTOCOLPGM(" @:");
 | 
					        SERIAL_PROTOCOLPGM(" @:");
 | 
				
			||||||
        SERIAL_PROTOCOL(getHeaterPower(tmp_extruder));  
 | 
					        SERIAL_PROTOCOL(getHeaterPower(tmp_extruder));  
 | 
				
			||||||
 | 
					      #endif
 | 
				
			||||||
 | 
					      #ifdef PIDTEMPBED
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOLPGM(" B@:");
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOL(getHeaterPower(-1));  
 | 
				
			||||||
      #endif
 | 
					      #endif
 | 
				
			||||||
        SERIAL_PROTOCOLLN("");
 | 
					        SERIAL_PROTOCOLLN("");
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
@@ -1405,6 +1410,24 @@ void process_commands()
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    #endif //PIDTEMP
 | 
					    #endif //PIDTEMP
 | 
				
			||||||
 | 
					    #ifdef PIDTEMPBED
 | 
				
			||||||
 | 
					    case 304: // M304
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        if(code_seen('P')) bedKp = code_value();
 | 
				
			||||||
 | 
					        if(code_seen('I')) bedKi = code_value()*PID_dT;
 | 
				
			||||||
 | 
					        if(code_seen('D')) bedKd = code_value()/PID_dT;
 | 
				
			||||||
 | 
					        updatePID();
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOL(MSG_OK);
 | 
				
			||||||
 | 
							SERIAL_PROTOCOL(" p:");
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOL(Kp);
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOL(" i:");
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOL(Ki/PID_dT);
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOL(" d:");
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOL(Kd*PID_dT);
 | 
				
			||||||
 | 
					        SERIAL_PROTOCOLLN("");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    #endif //PIDTEMP
 | 
				
			||||||
    case 240: // M240  Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/
 | 
					    case 240: // M240  Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/
 | 
				
			||||||
     {
 | 
					     {
 | 
				
			||||||
      #ifdef PHOTOGRAPH_PIN
 | 
					      #ifdef PHOTOGRAPH_PIN
 | 
				
			||||||
@@ -1437,8 +1460,14 @@ void process_commands()
 | 
				
			|||||||
    case 303: // M303 PID autotune
 | 
					    case 303: // M303 PID autotune
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      float temp = 150.0;
 | 
					      float temp = 150.0;
 | 
				
			||||||
 | 
					      int e=0;
 | 
				
			||||||
 | 
					      int c=5;
 | 
				
			||||||
 | 
					      if (code_seen('E')) e=code_value();
 | 
				
			||||||
 | 
								if (e<0)
 | 
				
			||||||
 | 
									temp=70;
 | 
				
			||||||
      if (code_seen('S')) temp=code_value();
 | 
					      if (code_seen('S')) temp=code_value();
 | 
				
			||||||
      PID_autotune(temp);
 | 
					      if (code_seen('C')) c=code_value();
 | 
				
			||||||
 | 
					      PID_autotune(temp, e, c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    break;
 | 
					    break;
 | 
				
			||||||
    case 400: // M400 finish all moves
 | 
					    case 400: // M400 finish all moves
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,15 +58,21 @@ int current_raw_bed = 0;
 | 
				
			|||||||
  #endif
 | 
					  #endif
 | 
				
			||||||
#endif //PIDTEMP
 | 
					#endif //PIDTEMP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef PIDTEMPBED
 | 
				
			||||||
 | 
					  // used external
 | 
				
			||||||
 | 
					  float pid_setpoint_bed = { 0.0 };
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  float bedKp=DEFAULT_bedKp;
 | 
				
			||||||
 | 
					  float bedKi=(DEFAULT_bedKi*PID_dT);
 | 
				
			||||||
 | 
					  float bedKd=(DEFAULT_bedKd/PID_dT);
 | 
				
			||||||
 | 
					#endif //PIDTEMPBED
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
//===========================================================================
 | 
					//===========================================================================
 | 
				
			||||||
//=============================private variables============================
 | 
					//=============================private variables============================
 | 
				
			||||||
//===========================================================================
 | 
					//===========================================================================
 | 
				
			||||||
static volatile bool temp_meas_ready = false;
 | 
					static volatile bool temp_meas_ready = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static unsigned long  previous_millis_bed_heater;
 | 
					 | 
				
			||||||
//static unsigned long previous_millis_heater;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef PIDTEMP
 | 
					#ifdef PIDTEMP
 | 
				
			||||||
  //static cannot be external:
 | 
					  //static cannot be external:
 | 
				
			||||||
  static float temp_iState[EXTRUDERS] = { 0 };
 | 
					  static float temp_iState[EXTRUDERS] = { 0 };
 | 
				
			||||||
@@ -82,7 +88,20 @@ static unsigned long  previous_millis_bed_heater;
 | 
				
			|||||||
  // static float pid_output[EXTRUDERS];
 | 
					  // static float pid_output[EXTRUDERS];
 | 
				
			||||||
  static bool pid_reset[EXTRUDERS];
 | 
					  static bool pid_reset[EXTRUDERS];
 | 
				
			||||||
#endif //PIDTEMP
 | 
					#endif //PIDTEMP
 | 
				
			||||||
 | 
					#ifdef PIDTEMPBED
 | 
				
			||||||
 | 
					  //static cannot be external:
 | 
				
			||||||
 | 
					  static float temp_iState_bed = { 0 };
 | 
				
			||||||
 | 
					  static float temp_dState_bed = { 0 };
 | 
				
			||||||
 | 
					  static float pTerm_bed;
 | 
				
			||||||
 | 
					  static float iTerm_bed;
 | 
				
			||||||
 | 
					  static float dTerm_bed;
 | 
				
			||||||
 | 
					  //int output;
 | 
				
			||||||
 | 
					  static float pid_error_bed;
 | 
				
			||||||
 | 
					  static float temp_iState_min_bed;
 | 
				
			||||||
 | 
					  static float temp_iState_max_bed;
 | 
				
			||||||
 | 
					#endif //PIDTEMPBED
 | 
				
			||||||
  static unsigned char soft_pwm[EXTRUDERS];
 | 
					  static unsigned char soft_pwm[EXTRUDERS];
 | 
				
			||||||
 | 
					  static unsigned char soft_pwm_bed;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
#ifdef WATCHPERIOD
 | 
					#ifdef WATCHPERIOD
 | 
				
			||||||
  int watch_raw[EXTRUDERS] = { -1000 }; // the first value used for all
 | 
					  int watch_raw[EXTRUDERS] = { -1000 }; // the first value used for all
 | 
				
			||||||
@@ -122,7 +141,7 @@ static unsigned long  previous_millis_bed_heater;
 | 
				
			|||||||
//=============================   functions      ============================
 | 
					//=============================   functions      ============================
 | 
				
			||||||
//===========================================================================
 | 
					//===========================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PID_autotune(float temp)
 | 
					void PID_autotune(float temp, int extruder, int ncycles)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  float input;
 | 
					  float input;
 | 
				
			||||||
  int cycles=0;
 | 
					  int cycles=0;
 | 
				
			||||||
@@ -140,11 +159,26 @@ void PID_autotune(float temp)
 | 
				
			|||||||
  float Kp, Ki, Kd;
 | 
					  float Kp, Ki, Kd;
 | 
				
			||||||
  float max, min;
 | 
					  float max, min;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((extruder > EXTRUDERS)
 | 
				
			||||||
 | 
					  #if (TEMP_BED_PIN <= -1)
 | 
				
			||||||
 | 
							||(extruder < 0)
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
						){
 | 
				
			||||||
 | 
					  	SERIAL_ECHOLN("PID Autotune failed. Bad extruder number.");
 | 
				
			||||||
 | 
					  	return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
  SERIAL_ECHOLN("PID Autotune start");
 | 
					  SERIAL_ECHOLN("PID Autotune start");
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  disable_heater(); // switch off all heaters.
 | 
					  disable_heater(); // switch off all heaters.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  soft_pwm[0] = PID_MAX/2;
 | 
						if (extruder<0)
 | 
				
			||||||
 | 
						  soft_pwm_bed = PID_MAX/2;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						  soft_pwm[extruder] = PID_MAX/2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 for(;;) {
 | 
					 for(;;) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -152,14 +186,17 @@ void PID_autotune(float temp)
 | 
				
			|||||||
      CRITICAL_SECTION_START;
 | 
					      CRITICAL_SECTION_START;
 | 
				
			||||||
      temp_meas_ready = false;
 | 
					      temp_meas_ready = false;
 | 
				
			||||||
      CRITICAL_SECTION_END;
 | 
					      CRITICAL_SECTION_END;
 | 
				
			||||||
      input = analog2temp(current_raw[0], 0);
 | 
					      input = (extruder<0)?analog2tempBed(current_raw_bed):analog2temp(current_raw[extruder], extruder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      max=max(max,input);
 | 
					      max=max(max,input);
 | 
				
			||||||
      min=min(min,input);
 | 
					      min=min(min,input);
 | 
				
			||||||
      if(heating == true && input > temp) {
 | 
					      if(heating == true && input > temp) {
 | 
				
			||||||
        if(millis() - t2 > 5000) { 
 | 
					        if(millis() - t2 > 5000) { 
 | 
				
			||||||
          heating=false;
 | 
					          heating=false;
 | 
				
			||||||
          soft_pwm[0] = (bias - d) >> 1;
 | 
										if (extruder<0)
 | 
				
			||||||
 | 
											soft_pwm_bed = (bias - d) >> 1;
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
											soft_pwm[extruder] = (bias - d) >> 1;
 | 
				
			||||||
          t1=millis();
 | 
					          t1=millis();
 | 
				
			||||||
          t_high=t1 - t2;
 | 
					          t_high=t1 - t2;
 | 
				
			||||||
          max=temp;
 | 
					          max=temp;
 | 
				
			||||||
@@ -210,7 +247,10 @@ void PID_autotune(float temp)
 | 
				
			|||||||
              */
 | 
					              */
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          soft_pwm[0] = (bias + d) >> 1;
 | 
										if (extruder<0)
 | 
				
			||||||
 | 
											soft_pwm_bed = (bias + d) >> 1;
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
											soft_pwm[extruder] = (bias + d) >> 1;
 | 
				
			||||||
          cycles++;
 | 
					          cycles++;
 | 
				
			||||||
          min=temp;
 | 
					          min=temp;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -221,17 +261,26 @@ void PID_autotune(float temp)
 | 
				
			|||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(millis() - temp_millis > 2000) {
 | 
					    if(millis() - temp_millis > 2000) {
 | 
				
			||||||
      temp_millis = millis();
 | 
								int p;
 | 
				
			||||||
 | 
								if (extruder<0){
 | 
				
			||||||
 | 
						      p=soft_pwm_bed;       
 | 
				
			||||||
 | 
						      SERIAL_PROTOCOLPGM("ok B:");
 | 
				
			||||||
 | 
								}else{
 | 
				
			||||||
 | 
						      p=soft_pwm[extruder];       
 | 
				
			||||||
	      SERIAL_PROTOCOLPGM("ok T:");
 | 
						      SERIAL_PROTOCOLPGM("ok T:");
 | 
				
			||||||
      SERIAL_PROTOCOL(degHotend(0));   
 | 
								}
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
					      SERIAL_PROTOCOL(input);   
 | 
				
			||||||
      SERIAL_PROTOCOLPGM(" @:");
 | 
					      SERIAL_PROTOCOLPGM(" @:");
 | 
				
			||||||
      SERIAL_PROTOCOLLN(getHeaterPower(0));       
 | 
					      SERIAL_PROTOCOLLN(p);       
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      temp_millis = millis();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
 | 
					    if(((millis() - t1) + (millis() - t2)) > (10L*60L*1000L*2L)) {
 | 
				
			||||||
      SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
 | 
					      SERIAL_PROTOCOLLNPGM("PID Autotune failed! timeout");
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(cycles > 5) {
 | 
					    if(cycles > ncycles) {
 | 
				
			||||||
      SERIAL_PROTOCOLLNPGM("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h");
 | 
					      SERIAL_PROTOCOLLNPGM("PID Autotune finished ! Place the Kp, Ki and Kd constants in the configuration.h");
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -245,19 +294,18 @@ void updatePID()
 | 
				
			|||||||
  for(int e = 0; e < EXTRUDERS; e++) { 
 | 
					  for(int e = 0; e < EXTRUDERS; e++) { 
 | 
				
			||||||
     temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;  
 | 
					     temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;  
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;  
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
int getHeaterPower(int heater) {
 | 
					int getHeaterPower(int heater) {
 | 
				
			||||||
 | 
						if (heater<0)
 | 
				
			||||||
 | 
							return soft_pwm_bed;
 | 
				
			||||||
  return soft_pwm[heater];
 | 
					  return soft_pwm[heater];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void manage_heater()
 | 
					void manage_heater()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
 | 
					 | 
				
			||||||
  static int bed_needs_heating=0;
 | 
					 | 
				
			||||||
  static int bed_is_on=0;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #ifdef USE_WATCHDOG
 | 
					  #ifdef USE_WATCHDOG
 | 
				
			||||||
    wd_reset();
 | 
					    wd_reset();
 | 
				
			||||||
@@ -298,12 +346,16 @@ void manage_heater()
 | 
				
			|||||||
          temp_iState[e] += pid_error[e];
 | 
					          temp_iState[e] += pid_error[e];
 | 
				
			||||||
          temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
 | 
					          temp_iState[e] = constrain(temp_iState[e], temp_iState_min[e], temp_iState_max[e]);
 | 
				
			||||||
          iTerm[e] = Ki * temp_iState[e];
 | 
					          iTerm[e] = Ki * temp_iState[e];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          //K1 defined in Configuration.h in the PID settings
 | 
					          //K1 defined in Configuration.h in the PID settings
 | 
				
			||||||
          #define K2 (1.0-K1)
 | 
					          #define K2 (1.0-K1)
 | 
				
			||||||
          dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
 | 
					          dTerm[e] = (Kd * (pid_input - temp_dState[e]))*K2 + (K1 * dTerm[e]);
 | 
				
			||||||
          temp_dState[e] = pid_input;
 | 
					          temp_dState[e] = pid_input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX);
 | 
					          pid_output = constrain(pTerm[e] + iTerm[e] - dTerm[e], 0, PID_MAX);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    #else 
 | 
				
			||||||
 | 
					          pid_output = constrain(pid_setpoint[e], 0, PID_MAX);
 | 
				
			||||||
    #endif //PID_OPENLOOP
 | 
					    #endif //PID_OPENLOOP
 | 
				
			||||||
    #ifdef PID_DEBUG
 | 
					    #ifdef PID_DEBUG
 | 
				
			||||||
    SERIAL_ECHOLN(" PIDDEBUG "<<e<<": Input "<<pid_input<<" Output "<<pid_output" pTerm "<<pTerm[e]<<" iTerm "<<iTerm[e]<<" dTerm "<<dTerm[e]);  
 | 
					    SERIAL_ECHOLN(" PIDDEBUG "<<e<<": Input "<<pid_input<<" Output "<<pid_output" pTerm "<<pTerm[e]<<" iTerm "<<iTerm[e]<<" dTerm "<<dTerm[e]);  
 | 
				
			||||||
@@ -338,42 +390,58 @@ void manage_heater()
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  #endif
 | 
					  #endif
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
#ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
 | 
					 | 
				
			||||||
  if (bed_needs_heating){
 | 
					 | 
				
			||||||
    if (bed_is_on==0)
 | 
					 | 
				
			||||||
        WRITE(HEATER_BED_PIN,HIGH);
 | 
					 | 
				
			||||||
    if (bed_is_on==1)
 | 
					 | 
				
			||||||
        WRITE(HEATER_BED_PIN,LOW);
 | 
					 | 
				
			||||||
    bed_is_on=(bed_is_on+1) % HEATER_BED_DUTY_CYCLE_DIVIDER;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#ifndef PIDTEMPBED
 | 
				
			||||||
  if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
 | 
					  if(millis() - previous_millis_bed_heater < BED_CHECK_INTERVAL)
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  previous_millis_bed_heater = millis();
 | 
					  previous_millis_bed_heater = millis();
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #if TEMP_BED_PIN > -1
 | 
					  #if TEMP_BED_PIN > -1
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    #ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
 | 
							#ifdef PIDTEMPBED
 | 
				
			||||||
    bed_needs_heating=0;
 | 
					    pid_input = analog2tempBed(current_raw_bed);
 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #ifndef BED_LIMIT_SWITCHING
 | 
					    #ifndef PID_OPENLOOP
 | 
				
			||||||
 | 
							  pid_error_bed = pid_setpoint_bed - pid_input;
 | 
				
			||||||
 | 
							  pTerm_bed = bedKp * pid_error_bed;
 | 
				
			||||||
 | 
							  temp_iState_bed += pid_error_bed;
 | 
				
			||||||
 | 
							  temp_iState_bed = constrain(temp_iState_bed, temp_iState_min_bed, temp_iState_max_bed);
 | 
				
			||||||
 | 
							  iTerm_bed = bedKi * temp_iState_bed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							  //K1 defined in Configuration.h in the PID settings
 | 
				
			||||||
 | 
							  #define K2 (1.0-K1)
 | 
				
			||||||
 | 
							  dTerm_bed= (bedKd * (pid_input - temp_dState_bed))*K2 + (K1 * dTerm_bed);
 | 
				
			||||||
 | 
							  temp_dState_bed = pid_input;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							  pid_output = constrain(pTerm_bed + iTerm_bed - dTerm_bed, 0, PID_MAX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #else 
 | 
				
			||||||
 | 
					      pid_output = constrain(pid_setpoint_bed, 0, PID_MAX);
 | 
				
			||||||
 | 
					    #endif //PID_OPENLOOP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						  if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) 
 | 
				
			||||||
 | 
						  {
 | 
				
			||||||
 | 
						    soft_pwm_bed = (int)pid_output >> 1;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
						  else {
 | 
				
			||||||
 | 
						    soft_pwm_bed = 0;
 | 
				
			||||||
 | 
						  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #elif not defined BED_LIMIT_SWITCHING
 | 
				
			||||||
      // Check if temperature is within the correct range
 | 
					      // Check if temperature is within the correct range
 | 
				
			||||||
      if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
 | 
					      if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
 | 
				
			||||||
        if(current_raw_bed >= target_raw_bed)
 | 
					        if(current_raw_bed >= target_raw_bed)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          WRITE(HEATER_BED_PIN,LOW);
 | 
										soft_pwm_bed = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else 
 | 
					        else 
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          #ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
 | 
										soft_pwm_bed = 100;
 | 
				
			||||||
          bed_needs_heating=1;
 | 
					 | 
				
			||||||
          #endif
 | 
					 | 
				
			||||||
          WRITE(HEATER_BED_PIN,HIGH);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
 | 
										soft_pwm_bed = 0;
 | 
				
			||||||
        WRITE(HEATER_BED_PIN,LOW);
 | 
					        WRITE(HEATER_BED_PIN,LOW);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    #else //#ifdef BED_LIMIT_SWITCHING
 | 
					    #else //#ifdef BED_LIMIT_SWITCHING
 | 
				
			||||||
@@ -381,18 +449,16 @@ void manage_heater()
 | 
				
			|||||||
      if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
 | 
					      if((current_raw_bed > bed_minttemp) && (current_raw_bed < bed_maxttemp)) {
 | 
				
			||||||
        if(current_raw_bed > target_bed_high_temp)
 | 
					        if(current_raw_bed > target_bed_high_temp)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          WRITE(HEATER_BED_PIN,LOW);
 | 
										soft_pwm_bed = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else 
 | 
					        else 
 | 
				
			||||||
          if(current_raw_bed <= target_bed_low_temp)
 | 
					          if(current_raw_bed <= target_bed_low_temp)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          #ifdef HEATER_BED_DUTY_CYCLE_DIVIDER
 | 
										soft_pwm_bed = 100;
 | 
				
			||||||
          bed_needs_heating=1;
 | 
					 | 
				
			||||||
          #endif
 | 
					 | 
				
			||||||
          WRITE(HEATER_BED_PIN,HIGH);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else {
 | 
					      else {
 | 
				
			||||||
 | 
										soft_pwm_bed = 0;
 | 
				
			||||||
        WRITE(HEATER_BED_PIN,LOW);
 | 
					        WRITE(HEATER_BED_PIN,LOW);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    #endif
 | 
					    #endif
 | 
				
			||||||
@@ -567,6 +633,8 @@ void tp_init()
 | 
				
			|||||||
#ifdef PIDTEMP
 | 
					#ifdef PIDTEMP
 | 
				
			||||||
    temp_iState_min[e] = 0.0;
 | 
					    temp_iState_min[e] = 0.0;
 | 
				
			||||||
    temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
 | 
					    temp_iState_max[e] = PID_INTEGRAL_DRIVE_MAX / Ki;
 | 
				
			||||||
 | 
					    temp_iState_min_bed = 0.0;
 | 
				
			||||||
 | 
					    temp_iState_max_bed = PID_INTEGRAL_DRIVE_MAX / bedKi;
 | 
				
			||||||
#endif //PIDTEMP
 | 
					#endif //PIDTEMP
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -728,6 +796,7 @@ void disable_heater()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  #if TEMP_BED_PIN > -1
 | 
					  #if TEMP_BED_PIN > -1
 | 
				
			||||||
    target_raw_bed=0;
 | 
					    target_raw_bed=0;
 | 
				
			||||||
 | 
					    soft_pwm_bed=0;
 | 
				
			||||||
    #if HEATER_BED_PIN > -1  
 | 
					    #if HEATER_BED_PIN > -1  
 | 
				
			||||||
      WRITE(HEATER_BED_PIN,LOW);
 | 
					      WRITE(HEATER_BED_PIN,LOW);
 | 
				
			||||||
    #endif
 | 
					    #endif
 | 
				
			||||||
@@ -832,6 +901,7 @@ ISR(TIMER0_COMPB_vect)
 | 
				
			|||||||
  static unsigned char soft_pwm_0;
 | 
					  static unsigned char soft_pwm_0;
 | 
				
			||||||
  static unsigned char soft_pwm_1;
 | 
					  static unsigned char soft_pwm_1;
 | 
				
			||||||
  static unsigned char soft_pwm_2;
 | 
					  static unsigned char soft_pwm_2;
 | 
				
			||||||
 | 
					  static unsigned char soft_pwm_b;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if(pwm_count == 0){
 | 
					  if(pwm_count == 0){
 | 
				
			||||||
    soft_pwm_0 = soft_pwm[0];
 | 
					    soft_pwm_0 = soft_pwm[0];
 | 
				
			||||||
@@ -844,6 +914,10 @@ ISR(TIMER0_COMPB_vect)
 | 
				
			|||||||
    soft_pwm_2 = soft_pwm[2];
 | 
					    soft_pwm_2 = soft_pwm[2];
 | 
				
			||||||
    if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1);
 | 
					    if(soft_pwm_2 > 0) WRITE(HEATER_2_PIN,1);
 | 
				
			||||||
    #endif
 | 
					    #endif
 | 
				
			||||||
 | 
					    #if HEATER_BED_PIN > -1
 | 
				
			||||||
 | 
					    soft_pwm_b = soft_pwm_bed;
 | 
				
			||||||
 | 
					    if(soft_pwm_b > 0) WRITE(HEATER_BED_PIN,1);
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0);
 | 
					  if(soft_pwm_0 <= pwm_count) WRITE(HEATER_0_PIN,0);
 | 
				
			||||||
  #if EXTRUDERS > 1
 | 
					  #if EXTRUDERS > 1
 | 
				
			||||||
@@ -852,6 +926,9 @@ ISR(TIMER0_COMPB_vect)
 | 
				
			|||||||
  #if EXTRUDERS > 2
 | 
					  #if EXTRUDERS > 2
 | 
				
			||||||
  if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0);
 | 
					  if(soft_pwm_2 <= pwm_count) WRITE(HEATER_2_PIN,0);
 | 
				
			||||||
  #endif
 | 
					  #endif
 | 
				
			||||||
 | 
					  #if HEATER_BED_PIN > -1
 | 
				
			||||||
 | 
					  if(soft_pwm_b <= pwm_count) WRITE(HEATER_BED_PIN,0);
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  pwm_count++;
 | 
					  pwm_count++;
 | 
				
			||||||
  pwm_count &= 0x7f;
 | 
					  pwm_count &= 0x7f;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,11 +46,15 @@ extern int current_raw_bed;
 | 
				
			|||||||
  extern int target_bed_low_temp ;  
 | 
					  extern int target_bed_low_temp ;  
 | 
				
			||||||
  extern int target_bed_high_temp ;
 | 
					  extern int target_bed_high_temp ;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
extern float Kp,Ki,Kd,Kc;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef PIDTEMP
 | 
					#ifdef PIDTEMP
 | 
				
			||||||
 | 
					  extern float Kp,Ki,Kd,Kc;
 | 
				
			||||||
  extern float pid_setpoint[EXTRUDERS];
 | 
					  extern float pid_setpoint[EXTRUDERS];
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#ifdef PIDTEMPBED
 | 
				
			||||||
 | 
					  extern float bedKp,bedKi,bedKd;
 | 
				
			||||||
 | 
					  extern float pid_setpoint_bed;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
// #ifdef WATCHPERIOD
 | 
					// #ifdef WATCHPERIOD
 | 
				
			||||||
  extern int watch_raw[EXTRUDERS] ;
 | 
					  extern int watch_raw[EXTRUDERS] ;
 | 
				
			||||||
@@ -88,7 +92,9 @@ FORCE_INLINE void setTargetHotend(const float &celsius, uint8_t extruder) {
 | 
				
			|||||||
FORCE_INLINE void setTargetBed(const float &celsius) {  
 | 
					FORCE_INLINE void setTargetBed(const float &celsius) {  
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  target_raw_bed = temp2analogBed(celsius);
 | 
					  target_raw_bed = temp2analogBed(celsius);
 | 
				
			||||||
  #ifdef BED_LIMIT_SWITCHING
 | 
						#ifdef PIDTEMPBED
 | 
				
			||||||
 | 
					  pid_setpoint_bed = celsius;
 | 
				
			||||||
 | 
					  #elif defined BED_LIMIT_SWITCHING
 | 
				
			||||||
    if(celsius>BED_HYSTERESIS)
 | 
					    if(celsius>BED_HYSTERESIS)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    target_bed_low_temp= temp2analogBed(celsius-BED_HYSTERESIS);
 | 
					    target_bed_low_temp= temp2analogBed(celsius-BED_HYSTERESIS);
 | 
				
			||||||
@@ -163,7 +169,7 @@ FORCE_INLINE void autotempShutdown(){
 | 
				
			|||||||
 #endif
 | 
					 #endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void PID_autotune(float temp);
 | 
					void PID_autotune(float temp, int extruder, int ncycles);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user