How to: Controlling the MCU fan via MCU temperature (Klipper)

The problem

I recently built myself a Voron v0.2 3Dprinter and while I have been loving my v0.2 I found it was getting frequent MCU (Processor) temperature warning notifications for my Raspberry Pi 3B+ in Mainsail.

I found these warnings more then a little bit concerning. I recalled that while I was building the kit, the default configuration had me install a fan referred to as the MCU fan. However when I started digging into the default Klipper configuration for the Voron v0 I found the following...

Source: Github

[controller_fan MCU_fan]
pin: gpio20
max_power: 1.0
kick_start_time: 0.5
heater: extruder

Some reason the Voron Team decided the default configuration should turn the MCU fan on when the extruder heater is active. This means if your not actively 3Dprinting the MCU fan is not on. I also noticed there wasn't any sort of speed control applied to the fan, it was simply set to 1.0 which is max speed (on). I am also not sure if there is a bug in Klipper firmware at the time of writing this, or if it had something else to do with 'contoller_fan' in Klipper. But for me, this usually resulted in my MCU fan not always being on when it should have been or left running after a print completed and allowed my Raspberry Pi to get very very hot.

After some research I understood that the extruder was probably the "safe" option to be used as a MCU fan control. It would be the most universal when paired to different hardware people might use while self-sourcing. It is also possible that some 3rd-party(clone) Raspberry type devices might not report the MCU temperature the same way the Pi3 does. So binding the fan control to an MCU sensor that might not always exist and could pose other problems and headaches for the Voron Team.

However, after some more digging I concluded 'temprature_fan' would probably be a better option for my hardware configuration and needs. I did not want my Raspberry Pi overheating and cooking itself, but neither did I want the fan running full speed (max noise) every time it was activated to reduce noise generated by the 3Dprinter.

Configuration I settled on using:

[temperature_fan MCU_fan]
sensor_type: temperature_host #This is what the Pi3's Temperature sensor is known as.
pin: PB5                      #Set this to your fan pin
max_temp: 80.0                #Set below 85C, Pi3+ MCU can be damaged at 85C
target_temp: 49.0             #Set this to your preferred running temperature
min_temp: 0
shutdown_speed: 0.0
kick_start_time: 0.5
off_below: 0.19
max_speed: 1.0
min_speed: 0.0
control: pid
pid_Kp: 2.0
pid_Ki: 5.0
pid_Kd: 0.5
pid_deriv_time: 2.0

Official documentation on 'temperature_fan' see: Klipper Documentation

Explanation of Configuration:

'temperature_fan' allows a lot more control over your fan while also allowing you to trigger it from a temperature sensor rather than a heater. 

'max_temp' - This is basically the "Emergency Stop" temperature. If the MCU reaches this temperature the firmware will stop your printer. Sort of the same way as hitting Emergency Stop would, to prevent damage to the MCU. You can set this to whatever temperature you like.
(Warning: you wont be able to resume your print if this triggers!)
Some research told me that beyond 85C and you risk physical damage to the Pi3 MCU.

'target_temp' - This is the MCU temperature that you ideally don't want exceeded. Based on this value the firmware will gradually speed up the fan speed as the temperature is reached. Once the temperature is reached or exceeded the fan speed is set to 100%. Likewise as the temperature drops below the target it will eventually turn the fan back of.