Smart Fan and Power Expansion Board

From All for Raspberry Pi, Arduino, Lattepanda, Orange Pi, Pine64 | by Geekworm
Jump to: navigation, search
Raspberry Pi Smart Fan and Power Expansion Board sku:464657


Raspberry Pi Smart Fan and Power Expansion Board sku:464657
Raspberry Pi Smart Fan and Power Expansion Board sku:464657
Raspberry Pi Smart Fan and Power Expansion Board sku:464657
Raspberry Pi Smart Fan and Power Expansion Board sku:464657
Raspberry Pi Smart Fan and Power Expansion Board sku:464657
Raspberry Pi Smart Fan and Power Expansion Board sku:464657

Overview

Smart Fan and Power Expansion Board

Features

1. Width voltage input: 6V~14V' With power switch

2. Output: DC 5V 4A with two channel outputs:

OUT1 for  external device such as servo, motor, robots, mechanical arm, intelligent card etc. (output interface: HT3.96);
Max current is 2A, and can be programming control to on/off; please refer to SAMPLE CODE 1;
OUT2 (GPIO output for raspberry pi);Max current is up to 4A if the OUT1 be closed; 
CAN'T be programming control, it will be output to raspberry pi directly if the switch be turned on;

3. Built-in temperature sensor, with active cooling fan, you can control flexibly the ON/OFF of mini fan via I2C command and GPIO programming. please refer to SAMPLE CODE 2;

4. Support hardware pwm to control fan, please refer to SAMPLE CODE 3;

Temperature range and accuracy

  • -25 ℃ ~ + 100 ℃ when the ± 2 ℃
  • -55 ℃ ~ +125 ℃ when the ± 3 ℃

5. Cooling Fan can be replaced, please refer to FAN SPECIFICATIONS;

6. Standard HAT size;

Packing List

  • 1 x Board;
  • 1 x Mini fan (with install screws)

SAMPLE CODE 1

#demonstrates how to control the output of OUT1
import RPi.GPIO as GPIO
import time

GPIO_PIN = 27

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_PIN, GPIO.OUT)
GPIO.setwarnings(False)
while True:
	#turn on the power output, LED is on
	GPIO.output(GPIO_PIN,GPIO.HIGH)
	print "Turn on the power output"
	time.sleep(10)
	#turn off the power output, LED is off
	GPIO.output(GPIO_PIN,GPIO.LOW)
	print "Turn off the power output"
	time.sleep(10)

Download it: File:Out1-onoff.zip

or

wget http://raspberrypiwiki.com/download/battery-fan-board/out1-onoff.py

Run this sample code, if you can found the out1 led turns on, after 10 seconds, out1 led turns off, in turn.

SAMPLE CODE 2

#coding=utf-8

import RPi.GPIO as GPIO
import struct
import smbus
import sys
import time
import os

Sensor_ADDRESS		= 0x48

#Set global alert temperature;
ALERT_CON_TEMPERATURE   = 36

#Set global CPU temperature
ALERT_CPU_TEMPERATURE   = 70

TEMP_REGISTER 	    = 0
CONF_REGISTER 	    = 1
#THYST_REGISTER 	  = 2
#TOS_REGISTER 	    = 3

#CONF_SHUTDOWN       = 0
#CONF_OS_COMP_INT    = 1
#CONF_OS_POL 	    = 2
#CONF_OS_F_QUE 	    = 3

GPIO_PIN = 12
g_on = False

def regdata2float (regdata):
	return (regdata / 32.0) / 8.0

def toFah(temp):
	return (temp * (9.0/5.0)) + 32.0

def setAlertTemp():
	g_bus.write_byte_data(Sensor_ADDRESS,TEMP_REGISTER,ALERT_CON_TEMPERATURE)

def clearAlert():
	g_bus.write_byte_data(Sensor_ADDRESS,CONF_REGISTER,0x00)

#Initialize the sensor and others.
def init():
	GPIO.setmode(GPIO.BCM)
	GPIO.setup(GPIO_PIN, GPIO.OUT)
	GPIO.setwarnings(False)
	setAlertTemp()
	clearAlert()

def getTemp(self):
	#msg = "Reads the temp from the sensor";
	raw = g_bus.read_word_data(Sensor_ADDRESS, TEMP_REGISTER) & 0xFFFF
	raw = ((raw << 8) & 0xFF00) + (raw >> 8)
	ret = regdata2float(raw)
	print "Current condition temperature is ", ret, "℃", "[", ALERT_CON_TEMPERATURE,"℃]"
	return ret

def getCPUtemp():
	cTemp = os.popen('vcgencmd measure_temp').readline()
	ret = float(cTemp.replace("temp=","").replace("'C\n",""))
	print "Current CPU temperature is ", ret, "℃", "[", ALERT_CPU_TEMPERATURE,"℃]"
	return ret

def checkTemperature():
	return (getTemp(g_bus) > ALERT_CON_TEMPERATURE) or (getCPUtemp() > ALERT_CPU_TEMPERATURE)

def setFan(need_to_open):
	#turn on the fan
	global g_on
	if (g_on and need_to_open) :
		return

	if (g_on == False and need_to_open == False) :
		return

	if need_to_open :
		if g_on == False :
			print "starup fan!"
		GPIO.output(GPIO_PIN,GPIO.LOW)
		g_on = True
	else:
		if g_on :
			print "Stop fan!"
		GPIO.output(GPIO_PIN,GPIO.HIGH)
		g_on = False

g_bus = smbus.SMBus(1)
init()
while True:
	print "------------------"
	print time.strftime("[%Y-%m-%d %H:%M:%S] ", time.localtime())
	setFan(checkTemperature())
	time.sleep(3);

Download it: File:Smartfan.zip

or:

wget http://raspberrypiwiki.com/download/battery-fan-board/smartfan.py

SAMPLE CODE 3

File:Samplecode3.zip

FAN SPECIFICATIONS

Side length is 30mm;

Thickness is 7mm;

PS: the thickness is not more 8mm;

Matching Acrylic Case

Sku-465240-IMG-2077.jpg

Sku-465240-IMG-2087-1.jpg

Add your comment
All for Raspberry Pi, Arduino, Lattepanda, Orange Pi, Pine64 | by Geekworm welcomes all comments. If you do not want to be anonymous, register or log in. It is free.


Anonymous user #2

3 days ago
Score 0++
can add this to libreelec??

Admin

one day 10 hours 33 minutes ago
Score 0++

Hello sir, It is not tested on libreelec. We suggest that you can do a test, thank you very much! Best regards,

Geekworm

Anonymous user #1

one month ago
Score 0++
  1. !/usr/bin/python
  2. MyRPi.ca script - ocs11@hotmail.com
  1. 2018-10-01
  1. Python script that uses multiple sources to determine the CPU and enclosure temperature
  2. and adjust the fan speed automatically
  1. Load system libraries

import RPi.GPIO as GPIO # Required to access the GPIO pin for PWM control. import time # Required for the loop delay. [time.sleep] import datetime # Required for date and time strings import sys # Required for CTRL-C clean exit. [sys.exit] import os # Required for secondary CPU temperature extraction. [os.open] import smbus # Required to read the sensor temperature

  1. User Configuration Settings

FAN_PIN = 12 # BCM pin used to drive the fan control. WAIT_TIME = 30 # Time, in seconds, to wait between each loop cycle.

fanSpeedMin = 36 # Minimum fan speed. Must be greater than 0. Use the calibration utility to get this value. fanSpeedMax = 100 # Maximum fan speed. Set to limit noise otherwise leave at 100. Maximum 100. cpuTempMin = 45 # Temperature at which to start the fan. Minimum 1. cpuTempMax = 60 # Temperature at which fan should run at [fanSpeedMax] speed. Maximum 70 (for safety).

diagCon = 0 # Set to [1] to enable diagnostic output to the console. [0] to diable. diagLog = 1 # Set to [1] to enable diagnostic output to a log file. [0] to diable. fanStatusLog = "/tmp/fanStatus" # Diagnostic Log file path and filename.

  1. I2C Temperature LM75 sensor onboard Fan/power hat
  2. i2cdetect -y 1
  3. 0 1 2 3 4 5 6 7 8 9 a b c d e f
  4. 00: -- -- -- -- -- -- -- -- -- -- -- -- --
  5. 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  6. 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  7. 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  8. 40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- -- <- 0x48 LM75 Temperature Sensor
  9. 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  10. 60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- <- 0x68 DS3231 RTC Module
  11. 70: -- -- -- -- -- -- -- --

checkLM75 = 1 # Enable (1) or disable (0) the LM75 sensor check sensorAddress = 0x48 # I2C Address of the temperature sensor tempRegister = 0 # In progress I2Cbus = smbus.SMBus(1) # 0 or 1 depending on the RPi. 0=/dev/i2c-0 1=/dev/i2c-1

  1. End of typical user configuration. Changing the code below may result in unexpected behaviour.
  1. Initialize runtime variables

PWM_FREQ = 50 # [Hz] Do not change. See documentation. cpuTemp = 0 # CPU Temperatue cpuTempOld = 0 # CPU Temperature on the last cycle fanSpeed = 0 # Fan Speed fanSpeedOld = 0 # Fan Speed on the last cycle fanRunning = 1 # Boolean to store if the fan is running or not

def regdata2float (regdata): return (regdata / 32.0) / 8.0

def getCPUtemp1(): if (diagCon): print "Trying to acquire CPU Temperature (Primary)." if (diagLog): fileLog.write ( "Trying to acquire CPU Temperature (Primary).\n" ) cpuTempFile = open("/sys/class/thermal/thermal_zone0/temp","r") # Open system file Read-Only cpuTemp1 = int(float(cpuTempFile.read())/1000) # Retrieve the system temperature value cpuTempFile.close() # Close the system file return cpuTemp1

def getCPUtemp2(): if (diagCon): print "Trying to acquire CPU Temperature (Secondary)." if (diagLog): fileLog.write ( "Trying to acquire CPU Temperature (Secondary).\n" ) cpuTemp2 = os.popen('vcgencmd measure_temp').readline() return float(cpuTemp2.replace("temp=","").replace("'C\n",""))

def getSensorTemp(self):

  1. Read the temperature from the I2C LM75 sensor

if (diagCon): print "Trying to acquire LM75 Sensor Temperature." if (diagLog): fileLog.write ( "Trying to acquire LM75 Sensor Temperature.\n" ) raw = I2Cbus.read_word_data(sensorAddress, tempRegister) & 0xFFFF raw = ((raw << 8) & 0xFF00) + (raw >> 8) ret = regdata2float(raw) if (diagCon): print "LM75 Sensor Temperature is ", ret, "C" if (diagLog): fileLog.write ( "LM75 Sensor Temperature is " + str(ret) + " C\n" ) return ret

  1. Verify the configuration values

if ((cpuTempMin >= cpuTempMax) or (cpuTempMin < 1) or (cpuTempMax > 70)): print "Invalid cpuTempMin or cpuTempMax value has been configured. Please read the documentation. Aborting." exit(0) if ((fanSpeedMin >= fanSpeedMax) or (fanSpeedMin < 0) or (fanSpeedMax > 100)): print "Invalid fanSpeedMin or fanSpeedMax value has been configured. Please read the documentation. Aborting." exit(0)

  1. Initialize the GPIO subsystem

GPIO.setmode(GPIO.BCM) GPIO.setup(FAN_PIN, GPIO.OUT, initial=GPIO.LOW) GPIO.setwarnings(False) fan = GPIO.PWM(FAN_PIN,PWM_FREQ) fan.start(0);

  1. Main runtime loop

try: while (1): # Repeat until CTRL-C is pressed.

  1. Reset variables at beginning of loop

cpuTemp = 0 now = datetime.datetime.now() timeNow = now.strftime("%Y-%m-%d %H:%M:%S") if (diagCon): print timeNow if (diagLog): fileLog = open(fanStatusLog,"w") fileLog.write ( timeNow + "\n" )

  1. Try method 1 to acquire CPU Temperature

cpuTemp = getCPUtemp1()

  1. If method 1 failed, try method 2 to get CPU temperature

if ((cpuTemp <= 0) or (cpuTemp > 120)): cpuTemp = getCPUtemp2()

  1. Check to make sure we have a reasonable CPU temperature to work with

if ((cpuTemp <= 0) or (cpuTemp > 120)): print "Unable to read the CPU Temperature [cpuTemp]. Incompatible system architecture or Linux version. Aborting." exit(0) if (diagCon): print "CPU Temperature: ", cpuTemp if (diagLog): fileLog.write ( "CPU Temperature: " + repr(cpuTemp) + "\n" )

  1. Calculate the appropriate fan speed based on the current CPU temperature

if (cpuTemp > cpuTempMin): cpuTempPerc = (((cpuTemp - cpuTempMin) * 100) / (cpuTempMax - cpuTempMin)) fanSpeed = (((fanSpeedMax - fanSpeedMin) * cpuTempPerc ) / 100 ) + fanSpeedMin if (diagCon): print "Calculated cpuTempPerc:", cpuTempPerc, "% fanSpeed:", fanSpeed if (diagLog): fileLog.write ( "Calculated cpuTempPerc: " + str(cpuTempPerc) + "% fanSpeed: " + str(fanSpeed) + "\n" )

  1. Enforce maximum fan speed

if ((fanSpeed > fanSpeedMax) or (cpuTemp >= cpuTempMax)): if (diagCon): print "Setting fanSpeed [", fanSpeed, "] -> fanSpeedMax [", fanSpeedMax, "] based on fanSpeedMax or cpuTempMax" if (diagLog): fileLog.write ( "Setting fanSpeed [" + str(fanSpeed) + "] -> fanSpeedMax [" + str(fanSpeedMax) + "] based on fanSpeedMax or cpuTempMax\n" ) fanSpeed = fanSpeedMax

  1. If fanSpeed is at or below the minimum, stop the fan

if (((fanSpeed < fanSpeedMin) or (cpuTemp <= cpuTempMin)) and (fanRunning != 0)): if (diagCon): print "Changing Duty Cycle [", fanSpeedOld, "] -> [Off] Cooling not required." if (diagLog): fileLog.write ( "Changing Duty Cycle [" + str(fanSpeedOld) + "] -> [Off] Cooling not required\n" ) fanSpeed = fanSpeedMin fanSpeedOld = fanSpeedMin fanRunning = 0 fan.ChangeDutyCycle(100)

  1. If the calculated speed is different from the last cycle, set the fan speed

if ((fanSpeed != fanSpeedOld)): if (diagCon): print "Changing Duty Cycle [", fanSpeedOld, "] -> [", fanSpeed, "]" if (diagLog): fileLog.write ( "Changing Duty Cycle [" + str(fanSpeedOld) + "] -> [" + str(fanSpeed) + "]\n" ) fanRunning = 1 fan.ChangeDutyCycle(100-fanSpeed)

fanSpeedOld = fanSpeed if (checkLM75): getSensorTemp(I2Cbus)

  1. Wait until the next loop cycle

if (diagCon): print if (diagLog): fileLog.close() time.sleep(WAIT_TIME)

  1. If a keyboard interrupt occurs (ctrl + c), set the GPIO to 0 and exit the program.

except(KeyboardInterrupt): print "Fan speed control script interrupted by the user. CTRL-C was pressed." GPIO.cleanup() if not fileLog.closed: fileLog.close() sys.exit()

  1. End of Script