4

I'm new to the world of Raspberry Pi, I'm setting one up as a little PC for a kid. I have a RPi 4 running Raspberry Pi OS, and I've build a case around this heatsink. I have created a simple circuit to control the fans from a GPIO using a MOSFET.

Schematic for fan control, motor represents fans

I am using a python script as a service to control the fans when booted. This seems to be working fine, I'll include it for reference in case it's important:


import os
from time import sleep
import signal
import sys
import RPi.GPIO as GPIO
import logging

gpioPin = 2 # The GPIO connected to fan circuit
onTemp = 40 # The temperature in Celsius after which the fan is turned on
offTemp = 35 # The temperature in Celsius after which the fan is turned off
status = False # Cooling status, true when the fan is in a cooling cycle, false when it's not

logging.basicConfig(filename='heatsink-fan.log', encoding='utf-8', format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.DEBUG)

def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(gpioPin, GPIO.OUT, initial=0)
    GPIO.setwarnings(False)
    return()

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

def fanON():
    setPin(True)
    logging.debug('Fan turned on')
    return()

def fanOFF():
    setPin(False)
    logging.debug('Fan turned off')
    return()

def getTEMP():
    CPU_temp = float(getCPUtemperature())
    if status is False:
        if CPU_temp > onTemp: fanON()
    else:
        if CPU_temp <= offTemp: fanOFF()
    return()

def setPin(mode):
    global status
    GPIO.output(gpioPin, mode)
    status = mode
    return()

try:
    logging.info('Fan script started.')
    setup() 
    while True:
        getTEMP()
        sleep(10) # Read the temperature every 10 seconds
except KeyboardInterrupt: # trap a CTRL+C keyboard interrupt
    GPIO.cleanup() # resets all GPIO ports

The real purpose of the circuit was to turn the fans off when the Pi is shutdown/halted so they aren't running 24/7. The power supply will always be connected. However, for some reason the GPIOs are being driven high even when shutdown.

I have tried using dtoverlay=gpio-poweroff in config.txt which I now understand is not the correct thing to do.

I have tried creating a systemd service (following this) to run at shutdown, which briefly set the GPIOs low but then when it fully shut down they went high again.

Why does the Pi drive pins high when halted? Is there a way to overcome this or do I have to make a new circuit to be driven by active low?

David
  • 673
  • 4
  • 19
shane-pi
  • 43
  • 4
  • 1
    Your actual Question has been solved, BUT there is no need for a program. You can use the gpio-fan overlay (which has been available in the kernel since late 2018). See https://raspberrypi.stackexchange.com/a/105820/8697 – Milliways Oct 12 '20 at 06:18

1 Answers1

2

GPIO 2 and GPIO 3 have hard-wired external pulls of 1k8 to 3V3.

Those pins will read high while the Pi is powered (unless they are driven low by software or an external circuit).

joan
  • 67,803
  • 5
  • 67
  • 102
  • I know about GPIO 3 (which I'm using with a power button), I did not realize GPIO 2 had that too! So if I swap to another GPIO it should work? I'll give that a shot thanks! – shane-pi Oct 11 '20 at 19:18
  • 1
    Thank you! This solved my problem, I simply swapped it to GPIO 17 and updated my script and now it's working. That 1K8 resistor perfectly explains why I saw a 2.7V signal into my MOSFET. – shane-pi Oct 11 '20 at 19:36