Fan Shim Button to turn Pi on and off FYI post

I have a Fan Shim on my Pi 4B. I chose to not install the Daemon and just let the fan run continuously. My temps are consistently right around 40c.
Anyway, I use the Fan Shim button to boot my Pi up, and do a proper shutdown. The boot up is easy, by default momentarily grounding GPIO 3 will boot your pi up. Assuming you left it powered after shutting it down. The Fan Shim Button grounds GPIO 3 when, and while pressed. Its listed as Wake in the Pinout

To get that same button to do a proper shut down you add the following to config.txt
dtoverlay=gpio-shutdown
If the Pi is running pressing the button will do a shutdown just like it does from the shutdown menu.

That is until you enable i2c? Once I did that the shut down via the button stopped working. Disable i2c and reboot and it works again. i2c uses GPIO 3 is I guess why this happens? Boot up was fine just no shutdown from the button. Then I noticed the Button also uses GPIO 17 so I changed my code to thei
dtoverlay=gpio-shutdown,gpio_pin=17,active_low=1,gpio_pull=up
Shut now works even if i2c is enabled. =)

Name:   gpio-shutdown
Info:   Initiates a shutdown when GPIO pin changes. The given GPIO pin
        is configured as an input key that generates KEY_POWER events.
        This event is handled by systemd-logind by initiating a
        shutdown. Systemd versions older than 225 need an udev rule
        enable listening to the input device:

                ACTION!="REMOVE", SUBSYSTEM=="input", KERNEL=="event*", \
                        SUBSYSTEMS=="platform", DRIVERS=="gpio-keys", \
                        ATTRS{keys}=="116", TAG+="power-switch"

        This overlay only handles shutdown. After shutdown, the system
        can be powered up again by driving GPIO3 low. The default
        configuration uses GPIO3 with a pullup, so if you connect a
        button between GPIO3 and GND (pin 5 and 6 on the 40-pin header),
        you get a shutdown and power-up button.
Load:   dtoverlay=gpio-shutdown,<param>=<val>

Params: gpio_pin                GPIO pin to trigger on (default 3)

        active_low              When this is 1 (active low), a falling
                                edge generates a key down event and a
                                rising edge generates a key up event.
                                When this is 0 (active high), this is
                                reversed. The default is 1 (active low).

        gpio_pull               Desired pull-up/down state (off, down, up)
                                Default is "up".

                                Note that the default pin (GPIO3) has an
                                external pullup.

        debounce                Specify the debounce interval in milliseconds
                                (default 100)

One wrinkle I’d like to work out is that the fan keeps running after the Pi shuts down. This happens even if you have installed the Fan Shim software and the Daemon. Any solution I have found breaks the GPIO startup function. You would have to ground the Global_En pin or Reset pin to boot up. Bummer.
Like doing this for example. Putting a low / ground on the fan control pin will turn the fan off.

 Name:   gpio-poweroff
Info:   Drives a GPIO high or low on poweroff (including halt). Enabling this
        overlay will prevent the ability to boot by driving GPIO3 low.
Load:   dtoverlay=gpio-poweroff,<param>=<val>
Params: gpiopin                 GPIO for signalling (default 26)

        active_low              Set if the power control device requires a
                                high->low transition to trigger a power-down.
                                Note that this will require the support of a
                                custom dt-blob.bin to prevent a power-down
                                during the boot process, and that a reboot
                                will also cause the pin to go low.
        input                   Set if the gpio pin should be configured as
                                an input.
        export                  Set to export the configured pin to sysfs

I found a really easy solution that works for me. I just wired a 10k resistor from the Fan Shim, Fan Control pin, GPIO 18 physical pin 12 to ground. A pull down resistor that will make the default state of the fan off. You will have to command it on, with either the dtoverlay=gpio-fan config.tx entry, or via the Pimoroni software Daemon. I tested both and it worked as I wanted. The Fan turned on and off when it should with the Daemon, and turned on as it should with the dtovery entry. Pressing the button on the Fan Shim to do a shutdown had the fan stop right away. And stay off even with the power supply plugged into the Pi. Pressing the button again on boot up the fan was off if the temp was below the on threshold. :D

I’m glad to learn I’m not the only one being “annoyed” by the fact the fan keeps spinning after shutdown. What I did: if we check the shim board we see that the RPI physical pin 12 (aka BCM GPIO 18) that controls the fan is pulled up on the shim board via a (about) 8.2k resistor to the RPI pin 1 (3.3V).
It’s enough to simply sever that copper trace between that resistor and the 3.3V pin. If someone really wants to go by the book with this one (which I did), with a hobby knife remove some of the lacquer to expose a small patch of GND copper next to that 8.2k resistor pad that was just severed from 3.3V line and solder it to the newly exposed GND patch. But again, this is not really necessary as the gate current of the mosfet transistor that drives the fan is enough to drain the pin 12 (GPIO 18) to ground in just 5-6s seconds after RPI shutdown (width the ground connection described above the fan shuts off right away on shutdown).
As for the RPI shutdown from fan shim button I did it via software. I modified pretty much the entire python code actually - now it works as someone would expect it to work. Among others, LED colors transit more fluently, in manual mode the LED is pulsating in intensity (brightness) to notify the user about the “manual” mode, button double click switches between auto/manual and the long (3sec) hold on the button shuts down the RPI. The CPU usage did not increase (it’s still around 1%) while the responsiveness has improved a bit and the overall behavior is more consistent now.

1 Like

Is that resistor the black square labeled 822? I would like to make that modification. My pull up works but some times I hear a very faint tick tick sound which I think is the fan trying to start? I’ve since removed my mode and gone back to stock.
I’d also like a look at your code modifications, if you don’t mind sharing. =)
The last time I tried it the manual mode was broken and didn’t work correctly. I do believe there is a github issue posted on it?

Let me take a picture of the board and post it…there are three resistors next to each other…the resistor that needs to be severed from the 3.3V line is the closest to the shim’s RPI “connector”.

OK, it sounds like its the one I think it is. They go from top to bottom 822, and then two 18A or IBA.


P.S. It looks like the new users like me are limited to 3 messages per post so this would be my last message for now.
P.P.S. Please see below the Python code for a RPI shutdown. CPU usage next to none. Just save this code into a whatever_name.py file and execute it. Then hold the fan shim button for 3 seconds and you will get a clean shutdown (make sure to save first whatever other work you have open…just saying ;-) ).

Off topic: I still find the Pimoroni policy of putting a 3 messages limit per post for new users pure BS so how about my own policy: one pimoroni product on my desk is one too many.
This being said, really nice chatting with you, alphanumeric!

import RPi.GPIO as GPIO
import os

button_pin = 17
hold_time = 3000 # in ms

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(button_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

while True:
    GPIO.wait_for_edge(button_pin, GPIO.FALLING)
    if GPIO.wait_for_edge(button_pin, GPIO.RISING, timeout=hold_time) is None:
        os.system("sudo shutdown -h now")

Thank you, that’s the one I thought it was. I’ll dig my multi meter out tomorrow and have a go at modifying it. I’ve had a few Rum & Cokes so not going to try it now. ;)
Oh, and by the way, welcome to the forums. Looking forward to more informative posts by you. =) Insert thumbs up smiley here, lol.

I just now did that mod and cut the trace going from the resistor to the 3.3V GPIO pin. Its easy to see the track even with the mask on the board, with a magnifying glass.
Then I just did a config.txt edit adding the fan dtoverlay.
dtoverlay=gpio-fan,gpiopin=18,temp=45000
I went with on at 45c and off at 35c for now. I may adjust latter if need be.
It now turns off on shutdown. =)
Plus it looks a lot better than my cludgy mod. You have to look really close to know its been modified.

To post code you do three ` your code and then three more of those.
It’s the symbol under the ~ on a US keyboard.
your code here

A big thank you to both of you. This was extremely helpful. I now have the fan shim operating as a proper startup/shutdown button (with bodge wires going to an external momentary switch on the case) while retaining the thermally-controlled fan.

If you add the following line to your config.txt file, the Pi will do a proper shutdown when the Fan Shim button is pressed.
dtoverlay=gpio-shutdown
It defaults to GPIO 3, the same pin that does the boot up.
It will fail to work however if you enable i2c. Bootup will still work but gpio-shutdown won’t.
To get around that I used this
dtoverlay=gpio-shutdown,gpio_pin=17,active_low=1,gpio_pull=up
It sets it to GPIO 17 instead of GPIO 3. The button on the fam shim grounds GPIO 3 and GPIO 17 when pressed. =)

Hello,
I’m an absolute novice and I have a question about the Pimoroni FanShim and hope that somebody could help me.
I use the RPI-RF-MOD radio module on the GPIO port of my RPI 4.
Now I also have installed the FAN-SHIM.
Unfortunately I had to find out that that the radio module stopped working properly.
In the documentations I read, that they use some same GPIO pins (3, 14 and 15).
My question now, is it possibility to change the GPIO pins in the software for the FAN-SHIM to other, free GPIO PINS (in terms of hardware I would implement this via an intermediate board) and if so, how and in which file I can do this?

I don’t know which file you would edit to change the pin numbers used by the Pimoroni service? Changing the pin used by a dtoverlys is easy though. You just change the “pin=”.

Hello alphanumeric,
I think I read something that the LED PINs 14 and 15 are controlled by some plasma library, so I thought I would have to change this in a file …
If I understand you correctly, I can change everything in the config.txt file, like this ?!
dtoverlay = ???, gpio_pin = 24
dtoverlay = ???, gpio_pin = 25
dtoverlay = ???, gpio_pin = 22
Can you tell me what I must insert instead of “???” for the PINs 14 (=> 24), 15 (=> 25) and 3 (=> 22) ?

The Fan control Pin is GPIO 18 and the dtoverlay for that is
dtoverlay=gpio-fan,gpiopin=18,temp=45000
gpiopin= is the pin you want to use
and the 4500 stands for 45c, you can change that to what ever you want.

The Fan Shim button is wired to GPIO 3 and GPIO 17.
Pressing the button grounds those pins.
The dtoverlay for shutdown is
dtoverlay=gpio-shutdown,gpio_pin=17,active_low=1,gpio_pull=up
pin= is the pin you want to use.

You can drive the LED with plasma, but it won’t change color based on temperature.
It will just show a changing repeating color pattern etc.
I don’t use the LED, not even with the Pimoroni software. I use --noled to turn it off.
I have never bothered to try and use it to show temperature by other means.
I have turned it on with Plasma but that was an accident. I was trying to run Plasma on my Blinkt and the Fan Shim LED lit up instead.

Hello alphanumeric,
Thank you for your feedback.
After a long search, read and test, I have now managed to run the original script with the changed PINs (the LED color also changes depending on the temperature).

Well done. Yeah its an APA102 and there is code out there for those LED’s. My Blinkt uses those LED’s.

Will this script replace any other script provided by Pimoroni here?

When I execute the script install-service.sh a service will be deployed; the service status when running is this:

$ sudo systemctl status pimoroni-fanshim.service
â—Ź pimoroni-fanshim.service - Fan Shim Service
     Loaded: loaded (/etc/systemd/system/pimoroni-fanshim.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2022-03-05 15:21:40 CET; 11min ago
   Main PID: 463 (python3)
      Tasks: 2 (limit: 4532)
        CPU: 3.643s
     CGroup: /system.slice/pimoroni-fanshim.service
             └─463 /usr/bin/python3 /opt/fanshim-python/examples/automatic.py --on-threshold 55 --off-threshold 45 --low-temp 45 --high-temp 55 --delay 2 --brightness 25 --nobutton

Mär 05 15:21:40 eddie systemd[1]: Started Fan Shim Service.

I guess your script must be additionally started.

But when I run it I get this error:

# python3 /opt/fanshim-python/examples/poweroff.py 
Traceback (most recent call last):
  File "/opt/fanshim-python/examples/poweroff.py", line 12, in <module>
    GPIO.wait_for_edge(button_pin, GPIO.FALLING)
RuntimeError: Error waiting for edge