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

LocalHeater.h « Heating « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 3ad48f5a43f69d4a1af7f7938ef0e49e39f474b1 (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
/*
 * Pid.h
 *
 *  Created on: 21 Jul 2016
 *      Author: David
 */

#ifndef SRC_LOCALHEATER_H_
#define SRC_LOCALHEATER_H_

/**
 * This class implements a PID controller for the heaters
 */

#include "Heater.h"
#include "FOPDT.h"
#include "TemperatureError.h"
#include "Hardware/IoPorts.h"
#include "GCodes/GCodeResult.h"

class HeaterProtection;

class LocalHeater : public Heater
{
	static const size_t NumPreviousTemperatures = 4; // How many samples we average the temperature derivative over

public:
	LocalHeater(unsigned int heaterNum) noexcept;
	~LocalHeater() noexcept;

	GCodeResult ConfigurePortAndSensor(const char *portName, PwmFrequency freq, unsigned int sensorNumber, const StringRef& reply) override;
	GCodeResult SetPwmFrequency(PwmFrequency freq, const StringRef& reply) noexcept override;
	GCodeResult ReportDetails(const StringRef& reply) const noexcept override;

	void Spin() noexcept override;							// Called in a tight loop to keep things running
	void SwitchOff() noexcept override;						// Not even standby - all heater power off
	GCodeResult ResetFault(const StringRef& reply) noexcept override;	// Reset a fault condition - only call this if you know what you are doing
	float GetTemperature() const noexcept override;			// Get the current temperature
	float GetAveragePWM() const noexcept override;			// Return the running average PWM to the heater. Answer is a fraction in [0, 1].
	float GetAccumulator() const noexcept override;			// Return the integral accumulator
	void StartAutoTune(float targetTemp, float maxPwm, const StringRef& reply) noexcept override;	// Start an auto tune cycle for this PID
	void GetAutoTuneStatus(const StringRef& reply) const noexcept override;	// Get the auto tune status or last result
	void Suspend(bool sus) noexcept override;				// Suspend the heater to conserve power or while doing Z probing

#if SUPPORT_CAN_EXPANSION
	void UpdateRemoteStatus(CanAddress src, const CanHeaterReport& report) noexcept override { }
#endif

protected:
	void ResetHeater() noexcept override;
	HeaterMode GetMode() const noexcept override { return mode; }
	GCodeResult SwitchOn(const StringRef& reply) noexcept override;	// Turn the heater on and set the mode
	GCodeResult UpdateModel(const StringRef& reply) noexcept override;	// Called when the heater model has been changed
	GCodeResult UpdateFaultDetectionParameters(const StringRef& reply) noexcept override { return GCodeResult::ok; }

private:
	void SetHeater(float power) const noexcept;				// Power is a fraction in [0,1]
	TemperatureError ReadTemperature() noexcept;				// Read and store the temperature of this heater
	void DoTuningStep() noexcept;							// Called on each temperature sample when auto tuning
	static bool ReadingsStable(size_t numReadings, float maxDiff) noexcept
		pre(numReadings >= 2; numReadings <= MaxTuningTempReadings);
	static int GetPeakTempIndex() noexcept;					// Auto tune helper function
	static int IdentifyPeak(size_t numToAverage) noexcept;	// Auto tune helper function
	void CalculateModel() noexcept;							// Calculate G, td and tc from the accumulated readings
	void DisplayBuffer(const char *intro) noexcept;			// Debug helper
	float GetExpectedHeatingRate() const noexcept;			// Get the minimum heating rate we expect

	PwmPort port;									// The port that drives the heater
	float temperature;								// The current temperature
	float previousTemperatures[NumPreviousTemperatures]; // The temperatures of the previous NumDerivativeSamples measurements, used for calculating the derivative
	size_t previousTemperatureIndex;				// Which slot in previousTemperature we fill in next
	float iAccumulator;								// The integral LocalHeater component
	float lastPwm;									// The last PWM value we output, before scaling by kS
	float averagePWM;								// The running average of the PWM, after scaling.
	uint32_t timeSetHeating;						// When we turned on the heater
	uint32_t lastSampleTime;						// Time when the temperature was last sampled by Spin()

	uint16_t heatingFaultCount;						// Count of questionable heating behaviours

	uint8_t previousTemperaturesGood;				// Bitmap indicating which previous temperature were good readings
	HeaterMode mode;								// Current state of the heater
	bool tuned;										// True if tuning was successful
	uint8_t badTemperatureCount;					// Count of sequential dud readings

	static_assert(sizeof(previousTemperaturesGood) * 8 >= NumPreviousTemperatures, "too few bits in previousTemperaturesGood");

	// Variables used during heater tuning
	static const size_t MaxTuningTempReadings = 128; // The maximum number of readings we keep. Must be an even number.

	static float *tuningTempReadings;				// the readings from the heater being tuned
	static float tuningStartTemp;					// the temperature when we turned on the heater
	static float tuningPwm;							// the PWM to use, 0..1
	static float tuningTargetTemp;						// the maximum temperature we are allowed to reach
	static uint32_t tuningBeginTime;				// when we started the tuning process
	static uint32_t tuningPhaseStartTime;			// when we started the current tuning phase
	static uint32_t tuningReadingInterval;			// how often we are sampling, in milliseconds
	static size_t tuningReadingsTaken;				// how many temperature samples we have taken
	static float tuningHeaterOffTemp;				// the temperature when we turned the heater off
	static float tuningPeakTemperature;				// the peak temperature reached, averaged over 3 readings (so slightly less than the true peak)
	static uint32_t tuningHeatingTime;				// how long we had the heating on for
	static uint32_t tuningPeakDelay;				// how many milliseconds the temperature continues to rise after turning the heater off
};

#endif /* SRC_LOCALHEATER_H_ */