5

I have a Raspberry pi Model B revision 2 and I've set up a mini 5v fan on a relay switch which i want to control with python now. I will be running a crontab every hour to check the temperature of the pi and if the temperature is above 50C i will be running the fan for like 10 min. This is my current setup:

enter image description here

The relay is connected like this diagram here:

enter image description here

I've setup the relay this way, because it has a light on top of it (a red light) which i want it to be on when the fan is working...and off when its not.

Here is my script:

#!/usr/bin/python3
import time
import os
import sys
import RPi.GPIO as GPIO

# Identify which pin controls the relay
FAN_PIN = 3
# Temperature check. Start fan after 50C, Shut down under 50C
FAN_START = 50

def GPIOsetup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(FAN_PIN, GPIO.OUT)
    GPIO.setwarnings(False)

def getCPUtemperature():
    res = os.popen('vcgencmd measure_temp').readline()
    return(res.replace("temp=","").replace("'C\n",""))

def fanON():
    GPIO.output(FAN_PIN, 0)
    print "fan on"
    return()

def fanOFF():
    GPIO.output(FAN_PIN, 1)
    print "fan off"
    return()

def getTEMP():
    CPU_temp = float(getCPUtemperature())
    if CPU_temp>FAN_START:
        fanON()
    else:
        fanOFF()
    return()

def main():
    GPIOsetup()
    getTEMP()

try:
    main()
finally:
    print ("Finish")
    #GPIO.cleanup()

Now the problem is that i am getting some warnings which i just cant get rid off:

root@raspberrypi:/home/pi# python fan.py
fan.py:14: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  GPIO.setup(FAN_PIN, GPIO.OUT)
fan.py:14: RuntimeWarning: A physical pull up resistor is fitted on this channel!
  GPIO.setup(FAN_PIN, GPIO.OUT)
fan off
Finish

The line in question as you can see is this:

GPIO.setup(FAN_PIN, GPIO.OUT)

Why am I getting this error ? i have GPIO.setwarnings(False) in my code. And also should i be using that pin for controlling the relay ? Is there optional pin i should be using ? Thanks.

  • 1
    Can't say for sure because I've never put this to the test, but possibly because that GPIO is part of the I2C interface. Unless you've run out of them, you might as well use GPIO's which aren't by default dedicated to some higher level purpose -- I think in your diagram these would be the yellow ones. If this does turn out to be the problem and you really want to use that pin, you should be able to give set the purpose appropriately using one of the pi specific libraries (e.g. pigpio). – goldilocks Jun 1 '15 at 16:57
  • hmm i see. I did see a picture on the web of a guy using pin12. I guess thats why. Thanks i'll give it a try – Sandbird Jun 1 '15 at 17:20
  • 3
    Are you sure that you want to connect the relay directly to the GPIO pin as the schematics suggest? (I don't know whether the relay module hast some transistor on board). Also: the schematics is misleading in the way that the relay is constantly switched on - it's tied to 5V and GND - while the GPIO pin is connected to nothing. – Ghanima Jun 1 '15 at 19:09
  • yeah i should have picked up a better relay image.. here is how it looks like : driscocity.com/wp-content/uploads/2014/05/connectrelay1.jpg ..It has 4 pins, +,-,ch1,ch2 where ch are the controllers for the gates. There is no other way to hook it up to the pi, so yeah i am pretty sure this is how i have to set it up.Funny thing...i just found this diagram by accident :) – Sandbird Jun 1 '15 at 20:49
  • Thanks for posting this (and the answer). Here's another resource for anyone searching for this: it uses a transistor and a 5V fan – brasofilo Nov 11 at 16:41
4

Final code:

#! /usr/bin/env python3
import os
import RPi.GPIO as GPIO
import time
import datetime
import sys

# 5 * * * * sudo python /home/pi/fan.py
# A crontab will run every hour and check the temp. If the temp is > 49 the script will start the fan
# until the temperature goes down to 28. When it does, the script will end, shutting down the fan as well.
# If the script executes again while a previous script is running, the latter will exit
# ... meaning the pi is in hell, and will never get bellow FAN_END value :P

# 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

# Get what action. If you manually turning on/off the fan
action = sys.argv.pop()


def GPIOsetup():
    GPIO.setwarnings(False) 
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(FAN_PIN, GPIO.OUT)

def fanON():
    GPIOsetup()
    GPIO.output(FAN_PIN, 0) #fan on
    return()
def fanOFF():
    GPIOsetup()
    GPIO.output(FAN_PIN, 1) #fan off
    return()

def get_temp_from_system():
    res = os.popen('vcgencmd measure_temp').readline()
    return(res.replace("temp=","").replace("'C\n",""))

def check_fan(pin):
    GPIOsetup()
    return GPIO.input(pin)

def run(pin):
    current_date = datetime.datetime.now()
    temp = get_temp_from_system()
    if float(temp) >= FAN_START:
        print(temp+' @ '+str(current_date))
        if check_fan(pin) == 1:
            print('Fan is Off...Starting Fan')
            fanON()
        else:
            time.sleep(5) # Remove, if you want real-time checking
            print('Fan is ON')
    elif float(temp) <= FAN_END:
        print(temp+' @ '+str(current_date))
        if check_fan(pin) == 0:
            print('Fan is on...Shuting it Down')
            fanOFF()
            GPIO.cleanup()
            return 1 # exit script. The pi has cooled down
        else:
            time.sleep(5) # Remove, if you want real-time checking
            print('Fan is OFF')
    else:
            pass # while the script is passing through here, there will be no output on screen


if action == "on" :
   print "Turning fan on"
   fanON()
elif action == "off" :
   print "Turning fan off"
   fanOFF()

# first check if script is already running
if check_fan(FAN_PIN) == 0:
    print('Fan is on, script must be running from another instance...')
else:
    temp = get_temp_from_system()
    if float(temp) < FAN_START:
        print('Pi is operating under normal temperatures.')
    else:
        try:
            while(True):
                tmp = run(FAN_PIN)
                if tmp == 1: # value returned from line 60
                    break
        except KeyboardInterrupt:
            fanOFF()
            GPIO.cleanup()
        finally:
            fanOFF()
            GPIO.cleanup()
2

In addition to moving off the I2C pin, you'll want to un-comment (remove #) the last line so your GPIO will cleanup. This will reset the GPIO and remove your warnings and errors the next time your script runs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.