Automated Cooling Fan for Pi

17,826

209

38

Description
A simple design to control a mini 5v fan with python, without the need of a breadboard, transistors etc. All you need are a few cables and a 1 channel relay. I had a 2 channel relay which i recommend, since its almost the same price plus you get an extra controller. A script executing every hour will check the pi's temperature and turn on/off a fan until the desired temperature is reached.

Introduction
Since summer is upon us my secondary pi is running a bit too hot for my taste so i wanted to cool it down a bit every now and then. Of course i could have a fan blowing at it 24/7 but a) that would require a breadboard, and some resistors etc because i cant just plug it in on the GPIO pins directly b) writing some code that interacts with the 'outside' world is more fun :) and c) its really cheap...all you need are some cables and relay.

Enjoy, and feel free to comment !

Step 1: Materials Needed

- crontab / python installed on your pi
- A raspberry pi with a case
- 5v mini fan (link)
- 2 channel relay (link)
- Couple of female to female cables (link). I only had 1, so i used an old DVD audio cable for the PC and that extra f2f cable for the relay controller pin.

Note:
The hole on top of my raspberry case was a bit smaller than usual, so i had to use a drill to make it a bit wider. Maybe you should get a case with a 5v fan already attached to it, if you are not sure about the size of it on your case.

Step 2: The Circuit - Assembly

As you can see from the image above i am using pins 2,6,12, which are all the same for any type of raspberry pi you might have, so you don't have to worry about the fact that i am using a Pi Model B rev2.

Plug in the cables the same way i am doing it.
- The 5v(pin2) goes to VCC
- The GND(pin6) to the GND
- The GPIO18(pin2) goes to the IN1
Make sure the jumper on your relay is set to : JD-VCC VCC.

Now to the relay...My setup is a bit weird, i know. I didnt want to use an external power source to start the fan, so i kinda of attached it to the pi as well. You will have to make a small cut to both the 5v and GND cable coming from the pi to attach the fan cables the same way i am doing it. You can use a soldering iron and some tape like i did.
I dont think there is a reason to worry about bricking your pi, because only the ground cable is directly connected to the pi. If you see carefully at the image, the relay switch is connected to the power cable, meaning when the fan is off, the direct connection with the pi is 'open' as well. So any electrical current the fan might produce when it goes off, will have no way of returning back to the pi.

The reason why i am using those gates on the relay, is because the relay has a tiny led on top of it. I wanted to see the red light when the fan in ON, so i know when the pi is cooling down.
If you want, you could use the other gates so that the reverse thing happens.
But you would probably need to reverse the GPIO commands in the python script (in functions fanON fan OFF shown in the next step) to make it work...You'll see what i mean when we get to it.

Step 3: The Script

Now don't freak out about scripting... Last week i didn't know python and yet i managed to write this script by reading and testing various examples out there. I know other programming languages though so dont worry, i am not gonna blow up your pi.
If i used (which i probably did) some functions that someone else wrote, i apologize for no credits given, but i've tweaked this script so much, its basically new.

Instructions

1) Download the attachement, or just copy/paste it from pastebin here and name it fan.py

2) Place the fan.py script in /home/pi/ folder

3) Execute: sudo chmod +x /home/pi/fan.py and sudo chown pi:pi /home/pi/fan.py

4) Assuming you have crontab installed on your pi execute: crontab -e

5) At the bottom copy / paste: 5 * * * * sudo python /home/pi/fan.py and save the file. (Ctrl+X and Y)

This crontab will execute the script every 1h5m.
The script will work as a standalone script as well...meaning besides the automated crontab action you can manually turn on/off the fan yourself. You do this using parameters like so:

  • sudo python /home/pi/fan.py on or
  • sudo python /home/pi/fan.py off

I also wrote a failsafe function in case you press Ctrl+C while the script is running. If you do, the fan will shut down before the script exits.


So, how this works ?

Every hour the script executes and checks the pi's temperature.
If the temperature is above an X value the fan will turn on and stay on until it cools down to a Y value. When it does, the script will exit. If for some reason it never reaches that low temperature and an hour passes, the next time the script executes it will 'see' that the fan is still on and the second script will quit...so use realistic temperature values if you want the fan to actually turn on/off.
If not, just set some ridiculous values (like Y = 0 degrees Celsius) so that the fan will always stay on.)
If your pi is operating between those 2 values (X,Y), it means that its operating under 'accepted' temperatures so the script will just exit when it checks the temperature every hour.

Explaining some values

At the top of the script there are some global variables. There are the variables you have to change.

# Identify which pin controls the relay
FAN_PIN = 18 # the yellow box ex: GPIO18
# Temperature check. Start fan if temp > 49C
FAN_START = 49
# Temperature check. Shut down under 28C
FAN_END = 28

Its pretty obvious what to do here. If you used GPIO18 like i did, then leave 18 here, otherwise change that value to the gpio you used.
FAN_START and FAN_END are the high/low temperatures you want use. You can even put float numbers there if you want, like 49.2


Note:

Remember the way i set up my relay ? If you see functions fanON and fanOFF you'll notice that i am setting the gpio output to False to turn the fan on and True to turn it off. If you chose another gate configuration on the relay, you'll probably need to reverse those values.

Step 4: Final Notes

I apologize for the detailed instructions. I wanted to cover all types of users.
There is probably a better way to do all this but i did the best i could with the materials in hand and with my noobness in circuitry and python.

A small bonus code

If you want a fast way to check the temperature of your pi, create a file called temp in /usr/local/bin folder and then copy paste this script inside:

http://pastebin.com/rUYqGjV5

execute: chmod +x /usr/local/bin/temp to make it executable.

Then just type temp from whichever folder you are to see your pi's temperature.

Share

    Recommendations

    • Fandom Contest

      Fandom Contest
    • Colors of the Rainbow Contest

      Colors of the Rainbow Contest
    • Backyard Contest

      Backyard Contest

    38 Discussions

    0
    None
    kwisher

    20 days ago on Step 3

    Hello, thanks for your Instructable. I found 2 errors in your script noted below:
    print("Turning fan on") << your forgot parenthesis Line 73
    print("Turning fan off") << same on Line 76

    19 replies
    0
    None
    Sandbirdkwisher

    Reply 20 days ago

    Hi, thanks for the that :)
    Fixed it in both files.

    0
    None
    kwisherSandbird

    Reply 20 days ago

    I'm not having any luck with your script. I can't even manually turn the fan on from cli. Running on a Pi-3 using GPIO-6, code has been changed to reflect the correct pin. Not sure where to start troubloeshooting.

    0
    None
    Sandbirdkwisher

    Reply 20 days ago

    wait....gpio6 ?
    gpio6 is all the way down here on the pi3: https://imgur.com/HuLdbuT
    Are you sure you placed the cable there ?

    Gpi18 is at the same location on both pi2, and 3, why did you change it to 6?

    0
    None
    kwisherSandbird

    Reply 20 days ago

    Like I said earlier, I'm using physical pin 22 which is BCM 25. I can turn the fan on/off using gpio commands and sudo python3 fan.py on/off. Problem is the script is not running with cron even though i added it to root's cron.

    0
    None
    Sandbirdkwisher

    Reply 19 days ago

    The only things i can think of are :
    1) Since you are using python3 you obviously used that instead of plain python in the crontab right?
    2) The paths are maybe wrong in the cronjob ? Try using absolute paths for both python3 bin file and the .py script location.
    3) Enable some logging by doing the following.
    5 * * * * sudo python3 /home/pi/fan.py > /home/{user..etc}/output_file.txt
    Ofc change the path in this example to a valid directory. The output_file.txt should have a log inside of weither the cron executed of failed and for what reason.

    0
    None
    kwisherSandbird

    Reply 19 days ago

    Line from root cron:
    */15 * * * * /usr/bin/python3 /home/kevin/fan.py > /home/kevin/fanLog.txt

    Output from log file:
    Fan is on, script must be running from another instance...

    But script is not running according to htop.

    0
    None
    kwisherSandbird

    Reply 18 days ago

    New script will power on fan once high limit is reached but will not power off fan once lower limit is reached. Now I can manually power fan off which wasn't working with the previous version.

    0
    None
    Sandbirdkwisher

    Reply 18 days ago

    sorry shouldnt have deleted that....does the log say anything when the cronjob fires again ?

    0
    None
    kwisherSandbird

    Reply 18 days ago

    Log output:
    Fan is on, script must be running from another instance...

    Since there are no date/time in log out put, I'm goingby file date/time.

    0
    None
    Sandbirdkwisher

    Reply 18 days ago

    Can you temporarily disable the cronjob and just start the script manually? First make sure to do the '...fan.py off' command and then :
    sudo python3 /home/kevin/fan.py
    Just let it run for a few minutes and check the output on the screen.
    Maybe its never reaching the low end temp. and thats why it stays in the loop forever.

    0
    None
    kwisherSandbird

    Reply 18 days ago

    Manual test worked!!! Not sure why cron is causing issues. Maybe a systemd service or timer would work better?

    0
    None
    Sandbirdkwisher

    Reply 18 days ago

    hmm no idea. I am not that good when it comes to systemd services. To tell you the truth i've moved from the relay idea to a much easier setup using a 2N3904 NPN Bipolar Transistor like this one: https://www.aliexpress.com/item/32968684789.html?spm=2114.search0104.3.1.49c01f9ebJEhQg&ws_ab_test=searchweb0_0%2Csearchweb201602_6_10065_10068_319_10059_10884_317_10887_10696_321_322_10084_453_10083_454_10103_10618_10304_10307_10820_10821_537_10302_536%2Csearchweb201603_52%2CppcSwitch_0&algo_expid=54239650-9ade-41c3-9970-688de37ba14a-0&algo_pvid=54239650-9ade-41c3-9970-688de37ba14a&transAbTest=ae803_4

    Using the mini fan and the transistor with this setup (where speaker=fan): https://imgur.com/a/d1BHkY5 and then using this script here:
    https://pastebin.com/fM4kU3dY with a cronjob that runs every minute like so:
    * * * * * /home/fan/fan.sh
    It will quickly check the temp every minute and turn the fan on/off if the value is above/below 45oC. No python, just bash. The only thing you need to edit in the script is the temp value you want and the lines that have: class/gpio/gpio2/value where gpio2 is the pin number you are using. I used the same pin as the example image, thats why it says 2. This setup is more robust and easier to test. But you do need a tiny piece of breadboard, the transistor, a resistor (i used a 260.00 ohms one (red-blue-black-black-brown))and some soldering.

    0
    None
    kwisherSandbird

    Reply 12 days ago

    When manually running your bash script I get the following error:
    FYI, using physical pin 37, gpio 25, bcm26

    kevin@pi-04:~ $ sudo ./fan3.sh
    cat: /sys/class/gpio/gpio26/value: No such file or directory
    sh: echo: I/O error
    ./fan3.sh: 12: ./fan3.sh: cannot create /sys/class/gpio/gpio26/direction: Directory nonexistent
    ./fan3.sh: 16: [: -eq: unexpected operator
    ./fan3.sh: 20: [: -eq: unexpected operator

    0
    None
    Sandbirdkwisher

    Reply 12 days ago

    Its querying gpio26 though not 25. You either using the wrong pin, or put the wrong pin in script

    0
    None
    kwisherSandbird

    Reply 12 days ago

    Error after changing to gpio25:

    kevin@pi-04:~ $ sudo ./fan3.sh
    [sudo] password for kevin:
    cat: /sys/class/gpio/gpio25/value: No such file or directory
    sh: echo: I/O error
    ./fan3.sh: 12: ./fan3.sh: cannot create /sys/class/gpio/gpio25/direction: Directory nonexistent
    ./fan3.sh: 16: [: -eq: unexpected operator

    0
    None
    kwisherSandbird

    Reply 18 days ago

    kevin@pi-04:~ $ sudo python3 /home/kevin/fan2.py
    [sudo] password for kevin:
    45.1 @ 2019-05-30 07:25:47.387085
    Fan is Off...Starting Fan
    45.1 @ 2019-05-30 07:25:47.401777
    Fan is ON
    44.0 @ 2019-05-30 07:25:52.434532
    Fan is ON
    44.0 @ 2019-05-30 07:25:57.530827
    Fan is ON
    44.0 @ 2019-05-30 07:26:03.026025
    Fan is ON
    44.0 @ 2019-05-30 07:26:12.612085
    Fan is ON
    39.7 @ 2019-05-30 07:28:15.305166
    Fan is on...Shuting it Down

    0
    None
    Sandbirdkwisher

    Reply 18 days ago

    Yeah that's what it should happen. The script is in a loop. Every 5 secs it checks the temp and acts accordingly. If a 2nd cronjob fires up, and the fan is on it will exit since there must be another script running. If it's off that means the other script has exited already so it takes hold of the action.

    0
    None
    kwisherSandbird

    Reply 18 days ago

    I've adjusted the high & low limits to suit my garage environment and have manually used the temp bash script to check on the temps so that I would know when the fan should be powered on or off. I will disable cron as you asked for some testing and reply back.