Welcome to mirror list, hosted at ThFree Co, Russian Federation.

Heater.h « Heating « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 008b9b547e9e84fb3b237aafea6701f2fc30353b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * Heater.h
 *
 *  Created on: 24 Jul 2019
 *      Author: David
 */

#ifndef SRC_HEATING_HEATER_H_
#define SRC_HEATING_HEATER_H_

#include <RepRapFirmware.h>
#include <General/NamedEnum.h>
#include "FOPDT.h"
#include "HeaterMonitor.h"
#include <ObjectModel/ObjectModel.h>
#include <Math/DeviationAccumulator.h>
#include <RRF3Common.h>

#if SUPPORT_CAN_EXPANSION
# include "CanId.h"
#endif

#define TUNE_WITH_HALF_FAN	0

class HeaterMonitor;
struct CanMessageHeaterTuningReport;
struct CanHeaterReport;

#if SUPPORT_REMOTE_COMMANDS
struct CanMessageHeaterModelNewNew;
struct CanMessageSetHeaterTemperature;
struct CanMessageSetHeaterMonitors;
struct CanMessageHeaterTuningCommand;
struct CanMessageSetHeaterFaultDetectionParameters;
#endif

// Enumeration to describe the status of a heater. Note that the web interface returns the numerical values, so don't change them.
NamedEnum(HeaterStatus, uint8_t, off, standby, active, fault, tuning, offline);

class Heater INHERIT_OBJECT_MODEL
{
public:
	Heater(unsigned int num) noexcept;
	virtual ~Heater() noexcept;
	Heater(const Heater&) = delete;

	// Configuration methods
	virtual GCodeResult ConfigurePortAndSensor(const char *portName, PwmFrequency freq, unsigned int sn, const StringRef& reply) = 0;
	virtual GCodeResult SetPwmFrequency(PwmFrequency freq, const StringRef& reply) = 0;
	virtual GCodeResult ReportDetails(const StringRef& reply) const noexcept = 0;

	virtual float GetTemperature() const noexcept = 0;					// Get the current temperature and error status
	virtual float GetAveragePWM() const noexcept = 0;					// Return the running average PWM to the heater. Answer is a fraction in [0, 1].
	virtual GCodeResult ResetFault(const StringRef& reply) noexcept = 0;	// Reset a fault condition - only call this if you know what you are doing
	virtual void SwitchOff() noexcept = 0;
	virtual void Spin() noexcept = 0;
	virtual void Suspend(bool sus) noexcept = 0;						// Suspend the heater to conserve power or while doing Z probing
	virtual float GetAccumulator() const noexcept = 0;					// Get the inertial term accumulator
	virtual void FeedForwardAdjustment(float fanPwmChange, float extrusionChange) noexcept = 0;
	virtual void SetExtrusionFeedForward(float pwm) noexcept = 0;

#if SUPPORT_CAN_EXPANSION
	virtual bool IsLocal() const noexcept = 0;
	virtual void UpdateRemoteStatus(CanAddress src, const CanHeaterReport& report) noexcept = 0;
	virtual void UpdateHeaterTuning(CanAddress src, const CanMessageHeaterTuningReport& msg) noexcept = 0;
#endif

	HeaterStatus GetStatus() const noexcept;							// Get the status of the heater
	unsigned int GetHeaterNumber() const noexcept { return heaterNumber; }
	const char *GetSensorName() const noexcept;							// Get the name of the sensor for this heater, or nullptr if it hasn't been named
	void SetTemperature(float t, bool activeNotStandby) THROWS(GCodeException);
	float GetActiveTemperature() const noexcept { return activeTemperature; }
	float GetStandbyTemperature() const noexcept { return standbyTemperature; }
	GCodeResult SetActiveOrStandby(bool setActive, const StringRef& reply) noexcept;	// Switch from idle to active or standby
	GCodeResult StartAutoTune(GCodeBuffer& gb, const StringRef& reply, FansBitmap fans) THROWS(GCodeException);
																		// Start an auto tune cycle for this heater
	void GetAutoTuneStatus(const StringRef& reply) const noexcept;		// Get the auto tune status or last result
	GCodeResult ConfigureFaultDetectionParameters(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException);
	GCodeResult ConfigureMonitor(GCodeBuffer &gb, const StringRef &reply) THROWS(GCodeException);

	float GetHighestTemperatureLimit() const noexcept;
	float GetLowestTemperatureLimit() const noexcept;					// Get the lowest temperature limit

	const FopDt& GetModel() const noexcept { return model; }			// Get the process model
	GCodeResult SetOrReportModel(unsigned int heater, GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeException);

#if SUPPORT_REMOTE_COMMANDS
	virtual GCodeResult TuningCommand(const CanMessageHeaterTuningCommand& msg, const StringRef& reply) noexcept = 0;
	GCodeResult SetModel(unsigned int heater, const CanMessageHeaterModelNewNew& msg, const StringRef& reply) noexcept;
	GCodeResult SetTemperature(const CanMessageSetHeaterTemperature& msg, const StringRef& reply) noexcept;
	GCodeResult SetFaultDetectionParameters(const CanMessageSetHeaterFaultDetectionParameters& msg, const StringRef& reply) noexcept;
	GCodeResult SetHeaterMonitors(const CanMessageSetHeaterMonitors& msg, const StringRef& reply) noexcept;
#endif

	bool IsHeaterEnabled() const noexcept								// Is this heater enabled?
		{ return model.IsEnabled(); }

	void SetM301PidParameters(const M301PidParameters& params) noexcept
		{ model.SetM301PidParameters(params); }

	void ClearModelAndMonitors() noexcept;
	void SetAsToolHeater() noexcept;
	void SetAsBedOrChamberHeater() noexcept;

	bool IsCoolingDevice() const noexcept { return model.IsInverted(); }

#if SUPPORT_REMOTE_COMMANDS
	uint8_t GetModeByte() const { return (uint8_t)GetMode(); }
#endif

protected:
	DECLARE_OBJECT_MODEL_WITH_ARRAYS

	struct HeaterParameters
	{
		float heatingRate;
		float coolingRate;
		float deadTime;
		float gain;
		unsigned int numCycles;

		float GetNormalGain() const noexcept { return heatingRate/coolingRate; }
	};

	virtual void ResetHeater() noexcept = 0;
	virtual HeaterMode GetMode() const noexcept = 0;
	virtual GCodeResult SwitchOn(const StringRef& reply) noexcept = 0;
	virtual GCodeResult UpdateModel(const StringRef& reply) noexcept = 0;
	virtual GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) noexcept = 0;
	virtual GCodeResult UpdateHeaterMonitors(const StringRef& reply) noexcept = 0;
	virtual GCodeResult StartAutoTune(const StringRef& reply, bool seenA, float ambientTemp) noexcept = 0;

	int GetSensorNumber() const noexcept { return sensorNumber; }
	void SetSensorNumber(int sn) noexcept;
	float GetMaxTemperatureExcursion() const noexcept { return maxTempExcursion; }
	float GetMaxHeatingFaultTime() const noexcept { return maxHeatingFaultTime; }
	uint32_t GetMaxBadTemperatureCount() const noexcept { return maxBadTemperatureCount; }
	float GetTargetTemperature() const noexcept { return (active) ? activeTemperature : standbyTemperature; }
	bool IsBedOrChamber() const noexcept { return isBedOrChamber; }

	GCodeResult SetModel(float hr, float bcr, float fcr, float coolingRateExponent, float td, float maxPwm, float voltage, bool usePid, bool inverted, const StringRef& reply) noexcept;
															// set the process model
	void ReportTuningUpdate() noexcept;						// tell the user what's happening
	void CalculateModel(HeaterParameters& params) noexcept;	// calculate G, td and tc from the accumulated readings
	void SetAndReportModelAfterTuning(bool usingFans) noexcept;

	HeaterMonitor monitors[MaxMonitorsPerHeater];			// embedding them in the Heater uses less memory than dynamic allocation
	bool tuned;												// true if tuning was successful

	// Constants used during heater tuning
	static constexpr uint32_t TempSettleTimeout = 20000;			// how long we allow the initial temperature to settle
	static constexpr unsigned int TuningHeaterMinIdleCycles = 3;	// minimum number of idle cycles after heating up, including the initial overshoot and cool down
	static constexpr unsigned int TuningHeaterMaxIdleCycles = 10;
	static constexpr unsigned int MinTuningHeaterCycles = 5;
	static constexpr unsigned int MaxTuningHeaterCycles = 25;
	static constexpr float DefaultTuningHysteresis = 5.0;
	static constexpr float DefaultTuningFanPwm = 0.7;
	static constexpr float TuningPeakTempDrop = 2.0;		// must be well below TuningHysteresis
	static constexpr float HeaterSettledCoolingTimeRatio = 0.93;

	// Variables used during heater tuning
	static float tuningPwm;									// the PWM to use, 0..1
	static float tuningTargetTemp;							// the target temperature
	static float tuningHysteresis;
	static float tuningFanPwm;

	static DeviationAccumulator tuningStartTemp;			// the temperature when we turned on the heater
	static uint32_t tuningBeginTime;						// when we started the tuning process
	static DeviationAccumulator dHigh;
	static DeviationAccumulator dLow;
	static DeviationAccumulator tOn;
	static DeviationAccumulator tOff;
	static DeviationAccumulator heatingRate;
	static DeviationAccumulator coolingRate;
	static DeviationAccumulator tuningVoltage;				// sum of the voltage readings we take during the heating phase

	static uint32_t lastOffTime;
	static uint32_t lastOnTime;
	static float peakTemp;									// max or min temperature
	static uint32_t peakTime;								// the time at which we recorded peakTemp
	static float afterPeakTemp;								// temperature after max from which we start timing the cooling rate
	static uint32_t afterPeakTime;							// the time at which we recorded afterPeakTemp
	static float lastCoolingRate;
	static FansBitmap tuningFans;
	static unsigned int tuningPhase;
	static uint8_t idleCyclesDone;
	static bool tuningQuietMode;

	static HeaterParameters fanOffParams, fanOnParams;

	static void ClearCounters() noexcept;

private:
	static const char* const TuningPhaseText[];

	FopDt model;
	unsigned int heaterNumber;
	int sensorNumber;								// the sensor number used by this heater
	float activeTemperature;						// the required active temperature
	float standbyTemperature;						// the required standby temperature
	float maxTempExcursion;							// the maximum temperature excursion permitted while maintaining the setpoint
	float maxHeatingFaultTime;						// how long a heater fault is permitted to persist before a heater fault is raised
	uint32_t maxBadTemperatureCount;				// the number of consecutive bad sensor readings we allow before raising a fault

	bool isBedOrChamber;							// true if this was a bed or chamber heater when we were switched on
	bool active;									// are we active or standby?
	bool modelSetByUser;
	bool monitorsSetByUser;
};

#endif /* SRC_HEATING_HEATER_H_ */