Heater and cooler and fans are all controlled at the end by a signal that controls the intensity with an input value in range 0..255. Normally this is done using a PWM output. In rare cases it uses a pin function if only on/off is wanted.
This PWM output can be coupled with a temperature input and a controlling function, that defines how the frequency is controlled. For temperatures a PID controller is the most common function.
Apart from several PWM output methods, there are also meta solutions that take a pwm instance as input and define a enhanced function. One example is the kickstart function that at first sends a higher value and reduces it after a while to the set value. Useful for fans that need some start voltage to run. Also for fans is the min speed function. It enforces a minimum value or turns off. Imagine a fan that only turns with at least 25%. Anything below will hold the fan and strictly spoken a short.
Fakes a PWM output. Usefull for testing without having hardware or if the output is a unneeded side effect for the intended function.
IO_PWM_FAKE(name)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
Use the output for heater and cooler controls.
Digital output that converts a pwm frequency into an on/off signal.
IO_PWM_SWITCH(name, pinname, onLevel)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pinname | Pin variable used for output. |
onLevel | Treshold from which on the pin is turned on. |
Use the output for heater and cooler controls.
Use the pulse width modulation with software emulation to turn the signal. Works on every pin, but the frequency is low. You can increase frequency by reducing precision.
IO_PWM_SOFTWARE(name, pinname, speed)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pinname | Pin variable used for output. |
speed | Frequency 0 = lowest, 4 = maximum |
Use the output for heater and cooler controls.
Use the pulse dense modulation with software emulation to turn the signal. Works on every pin, but the frequency is low and depends on the pdm value.
IO_PDM_SOFTWARE(name, pinname)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pinname | Pin variable used for output. |
Use the output for heater and cooler controls.
Uses hardware PWM to control the output. This allows the highest frequency and has no additional load on the cpu, so it is the preferred solution. Works only on some pins.
For Arduino Due based boards you can use one pin on each channel:
The 32 bit timer counter also allow creation of PWM signals. Here both pins of a channel can be used in parallel with the limitation that the frequency must be identical. Some timers are also used internally for repeated interrupts. Here the frequency is predefined by the interrupt frequency.
For STM32F446 you can use all PWM that are on a timer not used by a interrupt. The first one defining a frequency define the frequency for other pins on same timer. They also differ on timer resolution. If you have a device requiring exact frequencies use a 24 bit timer. All pins on same time need to use same frequency! Per channel only one pin can be used for pwm.
Timer | Bits | Pins | Comment |
---|---|---|---|
TIM1 | 16 | Channel 1: PA8, PB13 Channel 2: PA9 Channel 3: PA10 Channel 4: PA11 | |
TIM2 | 32 | Channel 1: PA0, PA5 Channel 2: PB3 Channel 3: PB10 Channel 4: PB2 | |
TIM3 | 16 | Channel 1: PC6, PB3 Channel 2: PB5 Channel 3: PC8 Channel 4: PC9 | |
TIM4 | 16 | Channel 1: PB6 Channel 2: PB7 Channel 3: PD14, PB8 Channel 4: PD15 | |
TIM5 | 32 | Channel 2: PA1 | |
TIM6 | 16 | None | Motion 2 timer |
TIM7 | 16 | None | Motion 3 timer |
TIM8 | 16 | Channel 2: PB0, PC7 Channel 3: PB1 | |
TIM9 | 16 | None | Servo timer |
TIM10 | 16 | None | Software PWM |
TIM11 | 16 | Channel 1: PB9 | Tone generator |
TIM12 | 16 | Channel 1: PB14 Channel 2: PB15 | |
TIM13 | 16 | Channel 1: PA6 | |
TIM14 | 16 | Channel 1: PA7 |
For Adafruit Metra Grand Central you can use all PWM that are on a timer not used by a interrupt. The first one defining a frequency define the frequency for other pins on same timer. They also differ on timer resolution. If you have a device requiring exact frequencies use a 24 bit timer. All pins on same time need to use same frequency! Per channel only one pin can be used for pwm.
Timer | Bits | Pins | Comment |
---|---|---|---|
TCC0 | 24 | Channel 0: 25 Channel 1:24 Channel 2:2 Channel 3:3 Channel 4:4 Channel 5:5 | |
TCC1 | 24 | Channel 0:6, 8 Channel 1:7 Channel 2:62 Channel 3: 63 | |
TCC2 | 16 | Channel 0: 28 Channel 1:23 | |
TCC3 | 16 | Channel 0:18 Channel 1:19 | |
TCC4 | 16 | Channel 0:39 Channel 1:38 | |
TC0 | 8 | Channel 0:59 | Motion3 interrupt used |
TC1 | 8 | Channel 0:60 Channel 1:61 | Software PWM |
TC2 | 8 | Channel 0:26 Channel 1:27 | |
TC3 | 8 | Channel 0:35 Channel 1:36 | Tone generator |
TC4 | 8 | Channel 0:31 Channel 1:30 | Servo timer if servos configured |
TC5 | 8 | None | Motion2 timer |
TC6 | 8 | Channel 0:9, 14 Channel 1:69 | |
TC7 | 8 | Channel 0:10, 12 Channel 1:13, 87 |
IO_PWM_HARDWARE(name, pinid, frequency)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pinname | Pin variable used for output. |
frequency | Frequency of the PWM signal. Limit is cpu frequency/256. |
Use the output for heater and cooler controls.
Uses hardware DAC to control the output voltage. This is a real analog voltage and no PWM signal! It can be used like any PWM output.
AVR and STM32F1 boards do not support DAC.
Due pins are: DAC0 (67) & DAC1(68)
STM32F4 (RUMBA32) pins are: PA_4 & PA_5 (note: PA_5 is used as EXP2's SPI SCK. Users will have to choose.)
SAMD51 (AGC) pins are: DAC0 (A0) & DAC1 (A1)
IO_PWM_DAC(name, pinid)
Parameter | Function |
---|---|
name | The variable name used to set output voltage. |
pinname | Pin variable used for output. |
Use the output for e.g. laser power.
Converts a regular PWM output into a PWM output that enforces a minimum value or is off.
IO_PWM_MIN_SPEED(name, pwmname, minValue, offBelow)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pwmname | PWM function to control. |
minValue | Minimum value to start the pwm. |
offBelow | true = Values 1 - minValue -1 turn signal off, false = Values > 0 send max(minValue, wanted value) |
Use the output for heater and cooler controls.
Converts the regular scale 0..255 to 0..maxValue. Can be used to connect 12V heater to 24V rail if maxValue is 63.
IO_PWM_SCALEDOWN(name, pwmname, maxValue)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pwmname | PWM function to control. |
maxValue | Maximum value send to pwm output (0..255). |
Use the output for heater and cooler controls.
Sends sof a short time 100% power and then reduces power to set value.
IO_PWM_KICKSTART(name, pwmname, timems, treshold)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pwmname | PWM function to control. |
timems | Time in 100ms intervals to start with 100%. 1 = 100ms, 2 = 200ms and so on. |
treshold | Values below treshold cause a kickstart, higher values don't. |
Use the output for heater and cooler controls.
If you have a high current loads it can cause spikes when they get turned on/off directly. For this case it is possible to combine a pwm (best hardware pwm) with a ramped change between 2 pwm values. Changes below treshold get set directly. If exceeded it will take take a multiple of 100ms defined in rampUpTime and rampDownTime.
IO_PWM_RAMP(name, pwmname, rampUpTime, rampDownTime, threshold)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pwmname | PWM function to control. |
rampUpTime | Time in 100ms intervals to increase to new value. 1 = 100ms, 2 = 200ms and so on. |
rampDownTime | Time in 100ms intervals to decrease to new value. 1 = 100ms, 2 = 200ms and so on. |
treshold | Values below treshold cause a direct change. |
Use the output for heater and cooler controls.
Can be used to debug a pwm. Will send a message for each value change. Do not use in production setup!
IO_PWM_REPORT(name, pwmname)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pwmname | PWM function to control. |
Use the output for heater and cooler controls.
Sends PWM values to two independent PWM outputs.
IO_PWM_MIRROR(name, pwm1, pwm2)
Parameter | Function |
---|---|
name | The variable name used to set pwm speed. |
pwm1 | First PWM output. |
pwm2 | Second PWM output. |
Use the output for heater and cooler controls.
There are many ways to control a temperature and what works best depends on what you try to control and how fast it reacts to changes. Heaters always have a delay between increasing output level and measuring a temperature change. That makes it hard to get a completely flat temperature line. In fact, you will never get one. The simplest solution is a Bang-Bang controller. It enables heater below target temperature and disables it above target temperature. Here you see very clearly the temperature wave swinging around the optimal value. For a heated bed this is no real problem. It has so much delay and rises that slowly that the difference is not that much and it does not matter for quality as long as filament sticks to the bed.
For extruders you want a solution that reduces these waves. Here a PID controller with correct P, I, D value can do wonders to the waves. The only real deficit is that on temperature changes you get a big over swing that then gets reduced to a nearly invisible swing.
Another topic to take care of is safety. Heaters can get very hot and if they get uncontrolled hot, because the thermistor or heater got involuntarily removed the temperature would be reported as too cold and heater gets full power all the time. This can be enough to melt parts and set the printer on fire. To decrease the risk, we have several tests. One is that if a defect sensor is detected, we disable the heater. We do the same, if w edetect that we are heating and the temperature does not rise or if a reached temperature can not be hold any more. Therefor we suggest to enable this feature. It is not 100% perfect. Even a 230°C hot heater that falls out of the extruder can set a fire before we are able to detect it. Therefore always have a fire alarm close to printers and make sure someone is available in case of fire! It does not happen often and you have very good chances that nothing will happen, but I have seen printers that burned down, so it really can happen.
Heaters can not live on it's own. They only work if we tell the firmware to use them. To do so, we have to put them into one of three lists in Configuration.h like this:
#define NUM_HEATED_BEDS 1
#define HEATED_BED_LIST \
{ &HeatedBed1 }
#define NUM_HEATED_CHAMBERS 0
#define HEATED_CHAMBER_LIST \
{}
// Heaters enumerate all heaters, so we can loop over them
// or call commands on a specific heater number.
// Suggested order: extruder heaters, heated beds, heated chambers, additional heaters
#define NUM_HEATERS 3
#define HEATERS \
{ &HeaterExtruder1, &HeaterExtruder2, &HeatedBed1 }
The two lists HEATED_BED_LIST and HEATED_CHAMBER_LIST assign them to a special well defined purpose. This allow the firmware to set the temperatures using the proper g-code commands.
HEATERS is the total list, that can be used to iterate over all devices and call function on them. One example is the autotune g-code. It takes the index in this list to know, which heater you want to tune. Extruder heater have no list here as they are referenced indirectly by the extruder tool.
Controls the temperature using a PID controller. This is most widely used solution for controlling extruder temperatures.
HEAT_MANAGER_PID(name, type, index, input, output, maxTemp, maxPwm, sampleTime, decVariance, decPeriod, p, i, d, driveMin, driveMax, hotPluggable)
Parameter | Function |
---|---|
name | The variable name used to control the temperature. |
type | Heater symbol in temperature report. 'E' = extruder, 'B' = Bed, 'C' = Heated chamber. |
index | Index in it's type list. |
input | Temperature input function. |
output | PWM function to control. |
maxTemp | Maximum allowed temperature. |
maxPwm | Max. PWM value (1..255). Normally 255 but can reduced if full power would destroy the extruder. |
sampleTime | Sample time in ms. Typical value for extruders is 1000. Can b eused to optimize PID. |
decVariance | Value a temperature can swing around target temperature without triggering a decoupled error. All temperatures swing a bit and external influences like enabling a fan can also cause sudden drops. If you get a decoupled error mid print, this value is normally to low. |
decPeriod | Time in milli seconds, when a temperature rise at maxPwm should cause 1°C change. Set to 0 to disable decoupling test. |
p | Propertional factor of PID controller. |
i | Integral factor of PID controller. |
d | Damping factor of PID controller. |
driveMin | Minimum value the integrated I term must produce. |
driveMax | Maximum value the integrated I term must produce. |
hotPluggable | If true a defect will be interpreted as removed and not as error. |
Use in extruder, bed or chamber control.
Controls the temperature using a PID controller optimized for peltier elements. Peltier elements can cool or heat depending on the polarity. The flowPin output controls the polarity. If you can not change polarity, you need to provide a fake output instead.
Note: If using autotune M303 you need to add D-1 or D1 to tell it if this is a cooling or heating optimization. Can be omitted for fixed heater/cooler peltier elements.
HEAT_MANAGER_PELTIER_PID(name, tp, index, input, output, maxTemp, maxPwm, sampleTime, decVariance, decPeriod, p, i, d, driveMin, driveMax, hotPlugable, peltierType, flowPin, minTemp)
Parameter | Function |
---|---|
name | The variable name used to control the temperature. |
type | Heater symbol in temperature report. 'E' = extruder, 'B' = Bed, 'C' = Heated chamber. |
index | Index in it's type list. |
input | Temperature input function. |
output | PWM function to control. |
maxTemp | Maximum allowed temperature. |
maxPwm | Max. PWM value (1..255). Normally 255 but can reduced if full power would destroy the extruder. |
sampleTime | Sample time in ms. Typical value for extruders is 1000. Can b eused to optimize PID. |
decVariance | Value a temperature can swing around target temperature without triggering a decoupled error. All temperatures swing a bit and external influences like enabling a fan can also cause sudden drops. If you get a decoupled error mid print, this value is normally to low. |
decPeriod | Time in milli seconds, when a temperature rise at maxPwm should cause 1°C change. Set to 0 to disable decoupling test. |
p | Propertional factor of PID controller. |
i | Integral factor of PID controller. |
d | Damping factor of PID controller. |
driveMin | Minimum value the integrated I term must produce. |
driveMax | Maximum value the integrated I term must produce. |
hotPluggable | If true a defect will be interpreted as removed and not as error. |
peltierType | Defines which direction gets controlled. Possible values are:
|
flowPin | Output class for polarity. Will send low for cooling and high for heating. Us einverting output if inverted polarity is required. |
minTemp | Minimum temperature that is considered as disabled. Setting heater to any value <= minTemp disables the heater. |
Use in extruder, bed or chamber control.
This method uses a simple temperature prediction for unchanged power into the future and controls power accordingly. Prediction takes the temperature change in the last 0.4 seconds. Knowing ho wlong a change takes if oyu disable or enable temperature it computes the best time to disable/enable heaters to get no overshoot. This method is much easier to control then PID and also is not as prone of overshooting. The drawback is that it will always swing to some extend around the target temperature, but with good calibration the deviations are normally so small that you can ignore them.
The dynamic part means that you set for 2 different temperatures the time to stop or start heating. Timings vary over temperatures, so this interpolation allows a more precise control over a wide range of temperatures.
HEAT_MANAGER_DYN_DEAD_TIME(name, type, index, input, output, maxTemp, maxPwm, sampleTime, decVariance, decPeriod, p, i, d, driveMin, driveMax, hotPluggable)
Parameter | Function |
---|---|
name | The variable name used to control the temperature. |
type | Heater symbol in temperature report. 'E' = extruder, 'B' = Bed, 'C' = Heated chamber. |
index | Index in it's type list. |
input | Temperature input function. |
output | PWM function to control. |
maxTemp | Maximum allowed temperature. |
maxPwm | Max. PWM value (1..255). Normally 255 but can reduced if full power would destroy the extruder. |
sampleTime | Sample time in ms. Typical value for extruders is 1000. Can b eused to optimize PID. |
decVariance | Value a temperature can swing around target temperature without triggering a decoupled error. All temperatures swing a bit and external influences like enabling a fan can also cause sudden drops. If you get a decoupled error mid print, this value is normally to low. |
decPeriod | Time in milli seconds, when a temperature rise at maxPwm should cause 1°C change. Set to 0 to disable decoupling test. |
p | Propertional factor of PID controller. |
i | Integral factor of PID controller. |
d | Damping factor of PID controller. |
driveMin | Minimum value the integrated I term must produce. |
driveMax | Maximum value the integrated I term must produce. |
hotPluggable | If true a defect will be interpreted as removed and not as error. |
Use in extruder, bed or chamber control.
Enables heater when you are below a set temperature and disables it, when you are above a given temperature. If you want a fan that cools above a set temperature you can use a inverted PWM output.
HEAT_MANAGER_BANG_BANG(name, tp, index, input, output, maxTemp, maxPwm, decVariance, decPeriod, hotPluggable)
Parameter | Function |
---|---|
name | The variable name used to control the temperature. |
type | Heater symbol in temperature report. 'E' = extruder, 'B' = Bed, 'C' = Heated chamber. |
index | Index in it's type list. |
input | Temperature input function. |
output | PWM function to control. |
maxTemp | Maximum allowed temperature. |
maxPwm | Max. PWM value (1..255). Normally 255 but can reduced if full power would destroy the extruder. |
decVariance | Value a temperature can swing around target temperature without triggering a decoupled error. All temperatures swing a bit and external influences like enabling a fan can also cause sudden drops. If you get a decoupled error mid print, this value is normally to low. |
decPeriod | Time in milli seconds, when a temperature rise at maxPwm should cause 1°C change. Set to 0 to disable decoupling test. |
hotPluggable | If true a defect will be interpreted as removed and not as error. |
Use in extruder, bed or chamber control.
A cooler is a fan that gets controlled by a temperature input or a state. Depending on your needs, you can connect it with a heater, a temperature or just on motors being enabled.
Takes the maximum of current temperature and target temperature to control the fan speed.
COOLER_MANAGER_HEATER(name, heater, pwm, minTemp, maxTemp, minPWM, maxPWM)
Parameter | Function |
---|---|
name | The variable name used to control the cooler. |
heater | Heater variable to get the required data from. |
pwm | PWM function to control. |
minTemp | Minimum temperature to enable fan. |
maxTemp | Temperature where maximum pwm is set. |
minPwm | Min. PWM value (1..255). Fan starts with this speed when minTemp is reached. |
maxPwm | Max. PWM value (1..255). Normally 255 but can reduced if full power would destroy the fan. |
None
Takes the temperature directly from a sensor to control the fan speed. Note that a sensor can be used by several modules as input. No need to have multiple identical sensors.
COOLER_MANAGER_SENSOR(name, temp, pwm, minTemp, maxTemp, minPWM, maxPWM)
Parameter | Function |
---|---|
name | The variable name used to control the cooler. |
temp | Temperature sensor variable. |
pwm | PWM function to control. |
minTemp | Minimum temperature to enable fan. |
maxTemp | Temperature where maximum pwm is set. |
minPwm | Min. PWM value (1..255). Fan starts with this speed when minTemp is reached. |
maxPwm | Max. PWM value (1..255). Normally 255 but can reduced if full power would destroy the fan. |
None
Switches fan speed based on motor state. All motors enabled can disable fan or run it on lower speed. For the case a motor is enabled, it will run at set high speed. Use this if you need to actively cool your stepper drivers, but want a quiet fan when all are disabled.
COOLER_MANAGER_MOTORS(name, pwm, offPWM, onPWM, offDelaySeconds)
Parameter | Function |
---|---|
name | The variable name used to control the cooler. |
pwm | PWM function to control. |
offPwm | PWM value (1..255) in case all motors are turned off. |
onPwm | PWM value (1..255) in case one or more motors are on. |
offDelaySeconds | Time to keep fans in on mode after motors are turned of in seconds. |
None