Control of 5V PWM fans, manually, with script and automatically by kernel

The topic of cooling has been addressed here in the forum on various occasions. Some consider fan-assisted cooling to be necessary, others swear by passive cooling and still others find the topic overrated and consider cooling of the VF2 to be unnecessary. Differing opinions on this subject are normal and perfectly fine. Here I would like to address only the first group and go through the possibilities of temperature-regulated PWM control together with you.

Those who are concerned about cooling may also find the following topic interesting: What's the thermal safety of VisionFive 2?

Not to raise expectations too high, with my preferred PWM fan controller EMC2301, it is difficult to realise a temperature control with a 5.15 kernel.

Why then do I get the idea of using the EMC2301 chip?
For me, the advantages of the EMC2301 are:

  • I have tested the simple use on my Raspberry Pi Compute Module 4 IO Board.
  • With the Fan Click, there is an inexpensive board with the EMC2301 that invites experimentation.
  • I could control the Fan Click on my BeaglePlay just as easily as the EMC2301 on my CM4IO.
  • I have already had some experience with the EMC2101, but unlike the EMC2301, it is not expected to be supported by the Linux kernel any time soon.

For my experiments I had just ordered several Adafruit EMC2101 I2C PC Fan Controllers and recently also three Fan Click Boards.

Here are two photos of my BeaglePlay, which has a socket for the mikroBUS, with a Fan Click installed.


And here you can see a Fan Click connected to my VF2-8. Because of the lack of microBUS, I made the connection via the 40 pin GPIO. You can also see the connected fan, a Noctua NF-A4x10 5V PWM.


The necessary connections on the GPIO to control the EMC2301 are:

  • 5V which are passed on from the Click Board to the fan as power supply.
  • 3.3V as power supply for the Click Board itself.
  • GND
  • I2C0 SDA for transmitting commands to and exchanging data with the EMC2301.
  • I2C0 SCL for transmitting commands to and exchanging data with the EMC2301.
  • GPIO55 Alert/Int (not yet in use).

General Call and Alert Response

Here you can see the connections of the Fan Click MIKROE-2004, these are also printed on the board itself.

Fan click user manual

The comparable circuit on the CM4 IO board is simpler and inspires to copy it.
From the Raspberry Pi CM4 IO data sheet, Chapter 4. Circuit diagram, Figure 8. RTC, wakeup and fan.

At the moment, as already mentioned above, the EMC2301 is not yet supported by hwmon in the 5.15 kernel, which is why, out of laziness, I set the speed of the fan down in the console after a cold start on my Raspberry Pi CM4, which runs continuously but does not get very hot.

RISC-V Kernel 6.2.6 support of Microchip EMC2305 and compatible EMC2301/2/3

For my experiments I installed lm-sensors fancontrol i2c-tools.

sudo apt install lm-sensors fancontrol i2c-tools
Linux cm4io 5.15.61-v8+ #1579 SMP PREEMPT Fri Aug 26 11:16:44 BST 2022 aarch64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Mar 23 18:36:31 2023


pi@cm4io:~ $ i2cget -y 10 0x2f 0x30
0xff
pi@cm4io:~ $ i2cset -y 10 0x2f 0x30 0x68
pi@cm4io:~ $ i2cget -y 10 0x2f 0x30
0x68
pi@cm4io:~ $ 

This is also how it works on the VF2.

Linux vfive2-8 5.15.0-starfive #1 SMP Mon Feb 27 14:03:14 EST 2023 riscv64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Apr  1 00:58:34 2036 from 192.168.178.24
user@vfive2-8:~$ sudo i2cget -y 0 0x2f 0x30
[sudo] password for user: 
0xff
user@vfive2-8:~$ sudo i2cset -y 0 0x2f 0x30 0x68
user@vfive2-8:~$ sudo i2cget -y 0 0x2f 0x30
0x68
user@vfive2-8:~$ 

The EMC2301 is connected to I2C bus 10 on the CM4 IO and to I2C bus 0 on the VF2. Of course, all systems have the address of the EMC2301 in common, which is 0x2f. What I read above from register 0x30 and also wrote there was the “duty cycle”. The “duty cycle”, which can be between 0 and 255, is used to set the speed of the fan motor. I got the information from the EMC2301/2/3/5 Data Sheet

Intel’s 4_Wire_PWM_Spec are also interesting.

@geerlingguy wrote an interesting article at the end of last year, Controlling PWM fans with the Raspberry Pi CM4 IO Board’s EMC2301, and I would like to thank him for his great work. His temperature-controlled fan script is a good inspiration for a script of your own that runs on the VF2 until this eventually happens in the kernel.

I will order 10 EMC2301 in the next few days to solder one of them onto an MSOP-8 to DIP adapter and assemble a breadboard with it.

I might “develop” a breakout board for the EMC2301 and have some boards produced at Oshpark. I have already ordered three copies of a breakout board there that someone else had developed and uploaded to Oshpark. Oh, I just saw that I have already ordered copies of two different boards from Oshpark.

I am grateful for suggestions, criticism, ideas and questions.

8 Likes

Never heard of the part before, never even knew such a thing existed, thanks.
Pretty neat, so over i2c you can set the fan speed (or query it), monitor the CPU temperature in the usual ways and slowly ramp up/down the fan speed to minimise fan noise while maximising cooling with some form of automatic fan control.

Or you could even implement a PID (Proportional, Integral and Derivative) controller algorithm to gently change the speed to minimise wear on the fans bearings - maximising the useful lifetime of the fan (anything with moving parts that can wear down over time, is typically the first component of a physical system to fail).

3 Likes