
M563 command extended to allow the tool number origin to be adjusted. If there is no P parameter in the command then the S parameter specifies an offset to be added to tool numbers in T, G10, M104 and M109 commands. This is so that multi-media gcode files generated by slic3r can be printed without having to edit all the tool numbers in the gcode file first. This extension is intended to be temporary, until slicer provides a mechanism for specifying the tool numbers. A separate offset is maintained for each data source (USB, web or SD card) and the offset for data from the SD card is reset to zero when a new file is started. To use this facility to print slic3r multi-media gcode files, add M563 S1 to your start gcode. M104 and M109 commands now accept an optional T parameter to specify the tool number, as generated by slic3r in multi-media gcode files. Movement code from RepRapPro's dev branch incorporated, including 5-point manual or automatic bed compensation mechanism. Heater status (off/standby/on) is included in the status poll response for the web interface. This will be used in a future version of the web interface. Incorporated code from RepRapPro dev branch to allow many more M-commands to return values as well as set them. Incorporated code from RepRapPro dev branch to implement the M119 and M135 commands. There is currently a bug in the M135 (set heat sample interval) command, which means that if you change the interval from its default value of 0.5 seconds then you need to adjust the I parameter by the same ratio and the D parameter by the inverse ratio. Extrusion totals are reset to zero when starting a new print from SD card.
246 lines
6.6 KiB
C++
246 lines
6.6 KiB
C++
/****************************************************************************************************
|
|
|
|
RepRapFirmware - Heat
|
|
|
|
This is all the code to deal with heat and temperature.
|
|
|
|
-----------------------------------------------------------------------------------------------------
|
|
|
|
Version 0.1
|
|
|
|
18 November 2012
|
|
|
|
Adrian Bowyer
|
|
RepRap Professional Ltd
|
|
http://reprappro.com
|
|
|
|
Licence: GPL
|
|
|
|
****************************************************************************************************/
|
|
|
|
#ifndef HEAT_H
|
|
#define HEAT_H
|
|
|
|
/**
|
|
* This class implements a PID controller for the heaters
|
|
*/
|
|
|
|
class PID
|
|
{
|
|
friend class Heat;
|
|
protected:
|
|
|
|
PID(Platform* p, int8_t h);
|
|
void Init(); // (Re)Set everything to start
|
|
void Spin(); // Called in a tight loop to keep things running
|
|
void SetActiveTemperature(float t);
|
|
float GetActiveTemperature() const;
|
|
void SetStandbyTemperature(float t);
|
|
float GetStandbyTemperature() const;
|
|
void Activate(); // Switch from idle to active
|
|
void Standby(); // Switch from active to idle
|
|
bool Active() const; // Are we active?
|
|
void SwitchOff(); // Not even standby - all heater power off
|
|
bool SwitchedOff() const; // Are we switched off?
|
|
void ResetFault(); // Reset a fault condition - only call this if you know what you are doing
|
|
float GetTemperature() const; // Get the current temperature
|
|
|
|
private:
|
|
|
|
void SwitchOn();
|
|
|
|
Platform* platform; // The instance of the class that is the RepRap hardware
|
|
float activeTemperature; // The required active temperature
|
|
float standbyTemperature; // The required standby temperature
|
|
float temperature; // The current temperature
|
|
float lastTemperature; // The previous current temperature
|
|
float temp_iState; // The integral PID component
|
|
bool active; // Are we active or standby?
|
|
bool switchedOff; // Becomes false when someone tells us our active or standby temperatures
|
|
int8_t heater; // The index of our heater
|
|
int8_t badTemperatureCount; // Count of sequential dud readings
|
|
bool temperatureFault; // Has our heater developed a fault?
|
|
};
|
|
|
|
/**
|
|
* The master class that controls all the heaters in the RepRap machine
|
|
*/
|
|
|
|
class Heat
|
|
{
|
|
public:
|
|
// Enumeration to describe the status of a heater. Note that the web interface returns the numerical values, so don't change them.
|
|
enum HeaterStatus { HS_off = 0, HS_standby = 1, HS_active = 2 };
|
|
|
|
Heat(Platform* p, GCodes* g);
|
|
void Spin(); // Called in a tight loop to keep everything going
|
|
void Init(); // Set everything up
|
|
void Exit(); // Shut everything down
|
|
void SetActiveTemperature(int8_t heater, float t);
|
|
float GetActiveTemperature(int8_t heater) const;
|
|
void SetStandbyTemperature(int8_t heater, float t);
|
|
float GetStandbyTemperature(int8_t heater) const;
|
|
void Activate(int8_t heater); // Turn on a heater
|
|
void Standby(int8_t heater); // Set a heater idle
|
|
float GetTemperature(int8_t heater) const; // Get the temperature of a heater
|
|
HeaterStatus GetStatus(int8_t heater) const; // Get the off/standby/active status
|
|
void SwitchOffAll(); // Turn all heaters off
|
|
void ResetFault(int8_t heater); // Reset a heater fault - only call this if you know what you are doing
|
|
bool AllHeatersAtSetTemperatures(bool includingBed) const; // Is everything at temperature within tolerance?
|
|
bool HeaterAtSetTemperature(int8_t heater) const; // Is a specific heater at temperature within tolerance?
|
|
void Diagnostics(); // Output useful information
|
|
|
|
private:
|
|
|
|
Platform* platform; // The instance of the RepRap hardware class
|
|
GCodes* gCodes; // The instance of the G Code interpreter class
|
|
bool active; // Are we active?
|
|
PID* pids[HEATERS]; // A PID controller for each heater
|
|
float lastTime; // The last time our Spin() was called
|
|
float longWait; // Long time for things that happen occasionally
|
|
};
|
|
|
|
|
|
//***********************************************************************************************************
|
|
|
|
inline bool PID::Active() const
|
|
{
|
|
return active;
|
|
}
|
|
|
|
inline void PID::SetActiveTemperature(float t)
|
|
{
|
|
SwitchOn();
|
|
activeTemperature = t;
|
|
}
|
|
|
|
inline float PID::GetActiveTemperature() const
|
|
{
|
|
return activeTemperature;
|
|
}
|
|
|
|
inline void PID::SetStandbyTemperature(float t)
|
|
{
|
|
SwitchOn();
|
|
standbyTemperature = t;
|
|
}
|
|
|
|
inline float PID::GetStandbyTemperature() const
|
|
{
|
|
return standbyTemperature;
|
|
}
|
|
|
|
inline float PID::GetTemperature() const
|
|
{
|
|
return temperature;
|
|
}
|
|
|
|
inline void PID::Activate()
|
|
{
|
|
SwitchOn();
|
|
active = true;
|
|
}
|
|
|
|
inline void PID::Standby()
|
|
{
|
|
SwitchOn();
|
|
active = false;
|
|
}
|
|
|
|
inline void PID::ResetFault()
|
|
{
|
|
temperatureFault = false;
|
|
badTemperatureCount = 0;
|
|
}
|
|
|
|
inline void PID::SwitchOff()
|
|
{
|
|
platform->SetHeater(heater, 0.0);
|
|
active = false;
|
|
switchedOff = true;
|
|
}
|
|
|
|
|
|
inline bool PID::SwitchedOff() const
|
|
{
|
|
return switchedOff;
|
|
}
|
|
|
|
//**********************************************************************************
|
|
|
|
// Heat
|
|
|
|
inline Heat::HeaterStatus Heat::GetStatus(int8_t heater) const
|
|
{
|
|
if (heater < 0 || heater >= HEATERS)
|
|
return HS_off;
|
|
return (pids[heater]->SwitchedOff()) ? HS_off
|
|
: (pids[heater]->Active()) ? HS_active
|
|
: HS_standby;
|
|
}
|
|
|
|
inline void Heat::SetActiveTemperature(int8_t heater, float t)
|
|
{
|
|
if (heater >= 0 && heater < HEATERS)
|
|
{
|
|
pids[heater]->SetActiveTemperature(t);
|
|
}
|
|
}
|
|
|
|
inline float Heat::GetActiveTemperature(int8_t heater) const
|
|
{
|
|
return (heater >= 0 && heater < HEATERS) ? pids[heater]->GetActiveTemperature() : ABS_ZERO;
|
|
}
|
|
|
|
inline void Heat::SetStandbyTemperature(int8_t heater, float t)
|
|
{
|
|
if (heater >= 0 && heater < HEATERS)
|
|
{
|
|
pids[heater]->SetStandbyTemperature(t);
|
|
}
|
|
}
|
|
|
|
inline float Heat::GetStandbyTemperature(int8_t heater) const
|
|
{
|
|
return (heater >= 0 && heater < HEATERS) ? pids[heater]->GetStandbyTemperature() : ABS_ZERO;
|
|
}
|
|
|
|
inline float Heat::GetTemperature(int8_t heater) const
|
|
{
|
|
return (heater >= 0 && heater < HEATERS) ? pids[heater]->GetTemperature() : ABS_ZERO;
|
|
}
|
|
|
|
inline void Heat::Activate(int8_t heater)
|
|
{
|
|
if (heater >= 0 && heater < HEATERS)
|
|
{
|
|
pids[heater]->Activate();
|
|
}
|
|
}
|
|
|
|
inline void Heat::SwitchOffAll()
|
|
{
|
|
for (int8_t heater = 0; heater < HEATERS; ++heater)
|
|
{
|
|
pids[heater]->SwitchOff();
|
|
}
|
|
}
|
|
|
|
inline void Heat::Standby(int8_t heater)
|
|
{
|
|
if (heater >= 0 && heater < HEATERS)
|
|
{
|
|
pids[heater]->Standby();
|
|
}
|
|
}
|
|
|
|
inline void Heat::ResetFault(int8_t heater)
|
|
{
|
|
if (heater >= 0 && heater < HEATERS)
|
|
{
|
|
pids[heater]->ResetFault();
|
|
}
|
|
}
|
|
|
|
|
|
#endif
|