<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.geekworm.com/index.php?action=history&amp;feed=atom&amp;title=CommentStreams%3A98b4f6ee1f2db4c26065155d713b9f0e</id>
	<title>CommentStreams:98b4f6ee1f2db4c26065155d713b9f0e - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.geekworm.com/index.php?action=history&amp;feed=atom&amp;title=CommentStreams%3A98b4f6ee1f2db4c26065155d713b9f0e"/>
	<link rel="alternate" type="text/html" href="https://wiki.geekworm.com/index.php?title=CommentStreams:98b4f6ee1f2db4c26065155d713b9f0e&amp;action=history"/>
	<updated>2026-07-30T01:32:00Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://wiki.geekworm.com/index.php?title=CommentStreams:98b4f6ee1f2db4c26065155d713b9f0e&amp;diff=30260&amp;oldid=prev</id>
		<title>209.58.142.155: Migrated comment #26</title>
		<link rel="alternate" type="text/html" href="https://wiki.geekworm.com/index.php?title=CommentStreams:98b4f6ee1f2db4c26065155d713b9f0e&amp;diff=30260&amp;oldid=prev"/>
		<updated>2018-10-26T11:02:00Z</updated>

		<summary type="html">&lt;p&gt;Migrated comment #26&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;#!/usr/bin/python&lt;br /&gt;
# MyRPi.ca script - ocs11@hotmail.com&lt;br /&gt;
&lt;br /&gt;
# 2018-10-01&lt;br /&gt;
&lt;br /&gt;
# Python script that uses multiple sources to determine the CPU and enclosure temperature&lt;br /&gt;
# and adjust the fan speed automatically&lt;br /&gt;
&lt;br /&gt;
# Load system libraries&lt;br /&gt;
import RPi.GPIO as GPIO # Required to access the GPIO pin for PWM control.&lt;br /&gt;
import time             # Required for the loop delay. [time.sleep]&lt;br /&gt;
import datetime         # Required for date and time strings&lt;br /&gt;
import sys              # Required for CTRL-C clean exit. [sys.exit]&lt;br /&gt;
import os               # Required for secondary CPU temperature extraction. [os.open]&lt;br /&gt;
import smbus            # Required to read the sensor temperature&lt;br /&gt;
&lt;br /&gt;
# User Configuration Settings&lt;br /&gt;
FAN_PIN     = 12        # BCM pin used to drive the fan control.&lt;br /&gt;
WAIT_TIME   = 30        # Time, in seconds, to wait between each loop cycle. &lt;br /&gt;
&lt;br /&gt;
fanSpeedMin = 36        # Minimum fan speed. Must be greater than 0. Use the calibration utility to get this value.&lt;br /&gt;
fanSpeedMax = 100       # Maximum fan speed. Set to limit noise otherwise leave at 100. Maximum 100.&lt;br /&gt;
cpuTempMin  = 45        # Temperature at which to start the fan. Minimum 1.&lt;br /&gt;
cpuTempMax  = 60        # Temperature at which fan should run at [fanSpeedMax] speed. Maximum 70 (for safety).&lt;br /&gt;
&lt;br /&gt;
diagCon     = 0         # Set to [1] to enable diagnostic output to the console. [0] to diable.&lt;br /&gt;
diagLog     = 1         # Set to [1] to enable diagnostic output to a log file. [0] to diable.&lt;br /&gt;
fanStatusLog = &amp;quot;/tmp/fanStatus&amp;quot; # Diagnostic Log file path and filename.&lt;br /&gt;
&lt;br /&gt;
# I2C Temperature LM75 sensor onboard Fan/power hat&lt;br /&gt;
# i2cdetect -y 1&lt;br /&gt;
#     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f&lt;br /&gt;
#00:          -- -- -- -- -- -- -- -- -- -- -- -- --&lt;br /&gt;
#10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --&lt;br /&gt;
#20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --&lt;br /&gt;
#30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --&lt;br /&gt;
#40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --     &amp;lt;- 0x48 LM75 Temperature Sensor&lt;br /&gt;
#50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --&lt;br /&gt;
#60: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --     &amp;lt;- 0x68 DS3231 RTC Module&lt;br /&gt;
#70: -- -- -- -- -- -- -- --&lt;br /&gt;
checkLM75     = 1               # Enable (1) or disable (0) the LM75 sensor check&lt;br /&gt;
sensorAddress = 0x48            # I2C Address of the temperature sensor&lt;br /&gt;
tempRegister  = 0               # In progress&lt;br /&gt;
I2Cbus        = smbus.SMBus(1)  # 0 or 1 depending on the RPi. 0=/dev/i2c-0 1=/dev/i2c-1&lt;br /&gt;
 &lt;br /&gt;
# End of typical user configuration. Changing the code below may result in unexpected behaviour.&lt;br /&gt;
&lt;br /&gt;
# Initialize runtime variables&lt;br /&gt;
PWM_FREQ    = 50        # [Hz] Do not change. See documentation.&lt;br /&gt;
cpuTemp     = 0         # CPU Temperatue&lt;br /&gt;
cpuTempOld  = 0         # CPU Temperature on the last cycle&lt;br /&gt;
fanSpeed    = 0         # Fan Speed &lt;br /&gt;
fanSpeedOld = 0         # Fan Speed on the last cycle&lt;br /&gt;
fanRunning  = 1         # Boolean to store if the fan is running or not&lt;br /&gt;
&lt;br /&gt;
def regdata2float (regdata):&lt;br /&gt;
   return (regdata / 32.0) / 8.0&lt;br /&gt;
&lt;br /&gt;
def getCPUtemp1():&lt;br /&gt;
   if (diagCon): print &amp;quot;Trying to acquire CPU Temperature (Primary).&amp;quot;&lt;br /&gt;
   if (diagLog): fileLog.write ( &amp;quot;Trying to acquire CPU Temperature (Primary).\n&amp;quot; )&lt;br /&gt;
   cpuTempFile = open(&amp;quot;/sys/class/thermal/thermal_zone0/temp&amp;quot;,&amp;quot;r&amp;quot;) # Open system file Read-Only&lt;br /&gt;
   cpuTemp1 = int(float(cpuTempFile.read())/1000) # Retrieve the system temperature value&lt;br /&gt;
   cpuTempFile.close() # Close the system file&lt;br /&gt;
   return cpuTemp1&lt;br /&gt;
&lt;br /&gt;
def getCPUtemp2():&lt;br /&gt;
   if (diagCon): print &amp;quot;Trying to acquire CPU Temperature (Secondary).&amp;quot;&lt;br /&gt;
   if (diagLog): fileLog.write ( &amp;quot;Trying to acquire CPU Temperature (Secondary).\n&amp;quot; )&lt;br /&gt;
   cpuTemp2 = os.popen(&amp;#039;vcgencmd measure_temp&amp;#039;).readline()&lt;br /&gt;
   return float(cpuTemp2.replace(&amp;quot;temp=&amp;quot;,&amp;quot;&amp;quot;).replace(&amp;quot;&amp;#039;C\n&amp;quot;,&amp;quot;&amp;quot;))&lt;br /&gt;
&lt;br /&gt;
def getSensorTemp(self):&lt;br /&gt;
   # Read the temperature from the I2C LM75 sensor&lt;br /&gt;
   if (diagCon): print &amp;quot;Trying to acquire LM75 Sensor Temperature.&amp;quot;&lt;br /&gt;
   if (diagLog): fileLog.write ( &amp;quot;Trying to acquire LM75 Sensor Temperature.\n&amp;quot; )&lt;br /&gt;
   raw = I2Cbus.read_word_data(sensorAddress, tempRegister) &amp;amp; 0xFFFF&lt;br /&gt;
   raw = ((raw &amp;lt;&amp;lt; 8) &amp;amp; 0xFF00) + (raw &amp;gt;&amp;gt; 8)&lt;br /&gt;
   ret = regdata2float(raw)&lt;br /&gt;
   if (diagCon): print &amp;quot;LM75 Sensor Temperature is &amp;quot;, ret, &amp;quot;C&amp;quot;&lt;br /&gt;
   if (diagLog): fileLog.write ( &amp;quot;LM75 Sensor Temperature is &amp;quot; + str(ret) + &amp;quot; C\n&amp;quot; )&lt;br /&gt;
   return ret&lt;br /&gt;
&lt;br /&gt;
# Verify the configuration values&lt;br /&gt;
if ((cpuTempMin &amp;gt;= cpuTempMax) or (cpuTempMin &amp;lt; 1) or (cpuTempMax &amp;gt; 70)):&lt;br /&gt;
    print &amp;quot;Invalid cpuTempMin or cpuTempMax value has been configured. Please read the documentation. Aborting.&amp;quot;&lt;br /&gt;
    exit(0)&lt;br /&gt;
if ((fanSpeedMin &amp;gt;= fanSpeedMax) or (fanSpeedMin &amp;lt; 0) or (fanSpeedMax &amp;gt; 100)):&lt;br /&gt;
    print &amp;quot;Invalid fanSpeedMin or fanSpeedMax value has been configured. Please read the documentation. Aborting.&amp;quot;&lt;br /&gt;
    exit(0)&lt;br /&gt;
&lt;br /&gt;
# Initialize the GPIO subsystem&lt;br /&gt;
GPIO.setmode(GPIO.BCM)&lt;br /&gt;
GPIO.setup(FAN_PIN, GPIO.OUT, initial=GPIO.LOW)&lt;br /&gt;
GPIO.setwarnings(False)&lt;br /&gt;
fan = GPIO.PWM(FAN_PIN,PWM_FREQ)&lt;br /&gt;
fan.start(0);&lt;br /&gt;
&lt;br /&gt;
# Main runtime loop&lt;br /&gt;
try:&lt;br /&gt;
    while (1): # Repeat until CTRL-C is pressed.&lt;br /&gt;
&lt;br /&gt;
        # Reset variables at beginning of loop&lt;br /&gt;
        cpuTemp = 0&lt;br /&gt;
        now = datetime.datetime.now()&lt;br /&gt;
        timeNow = now.strftime(&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;)&lt;br /&gt;
        if (diagCon): print  timeNow&lt;br /&gt;
        if (diagLog): &lt;br /&gt;
           fileLog = open(fanStatusLog,&amp;quot;w&amp;quot;)&lt;br /&gt;
           fileLog.write ( timeNow + &amp;quot;\n&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
        # Try method 1 to acquire CPU Temperature&lt;br /&gt;
        cpuTemp = getCPUtemp1()&lt;br /&gt;
 &lt;br /&gt;
        # If method 1 failed, try method 2 to get CPU temperature&lt;br /&gt;
        if ((cpuTemp &amp;lt;= 0) or (cpuTemp &amp;gt; 120)):&lt;br /&gt;
            cpuTemp = getCPUtemp2()&lt;br /&gt;
&lt;br /&gt;
        # Check to make sure we have a reasonable CPU temperature to work with&lt;br /&gt;
        if ((cpuTemp &amp;lt;= 0) or (cpuTemp &amp;gt; 120)):&lt;br /&gt;
            print &amp;quot;Unable to read the CPU Temperature [cpuTemp]. Incompatible system architecture or Linux version. Aborting.&amp;quot;&lt;br /&gt;
            exit(0)&lt;br /&gt;
        if (diagCon): print &amp;quot;CPU Temperature: &amp;quot;, cpuTemp&lt;br /&gt;
        if (diagLog): fileLog.write ( &amp;quot;CPU Temperature: &amp;quot; + repr(cpuTemp) + &amp;quot;\n&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
        # Calculate the appropriate fan speed based on the current CPU temperature&lt;br /&gt;
        if (cpuTemp &amp;gt; cpuTempMin):&lt;br /&gt;
           cpuTempPerc = (((cpuTemp - cpuTempMin) * 100) / (cpuTempMax - cpuTempMin))&lt;br /&gt;
           fanSpeed = (((fanSpeedMax - fanSpeedMin) * cpuTempPerc ) / 100 ) + fanSpeedMin&lt;br /&gt;
           if (diagCon): print &amp;quot;Calculated cpuTempPerc:&amp;quot;, cpuTempPerc, &amp;quot;% fanSpeed:&amp;quot;, fanSpeed&lt;br /&gt;
           if (diagLog): fileLog.write ( &amp;quot;Calculated cpuTempPerc: &amp;quot; + str(cpuTempPerc) + &amp;quot;% fanSpeed: &amp;quot; + str(fanSpeed) + &amp;quot;\n&amp;quot; )&lt;br /&gt;
&lt;br /&gt;
        # Enforce maximum fan speed&lt;br /&gt;
        if ((fanSpeed &amp;gt; fanSpeedMax) or (cpuTemp &amp;gt;= cpuTempMax)):&lt;br /&gt;
           if (diagCon): print &amp;quot;Setting fanSpeed [&amp;quot;, fanSpeed, &amp;quot;] -&amp;gt; fanSpeedMax [&amp;quot;, fanSpeedMax, &amp;quot;] based on fanSpeedMax or cpuTempMax&amp;quot;&lt;br /&gt;
           if (diagLog): fileLog.write ( &amp;quot;Setting fanSpeed [&amp;quot; + str(fanSpeed) + &amp;quot;] -&amp;gt; fanSpeedMax [&amp;quot; + str(fanSpeedMax) + &amp;quot;] based on fanSpeedMax or cpuTempMax\n&amp;quot; )&lt;br /&gt;
           fanSpeed = fanSpeedMax &lt;br /&gt;
&lt;br /&gt;
        # If fanSpeed is at or below the minimum, stop the fan&lt;br /&gt;
        if (((fanSpeed &amp;lt; fanSpeedMin) or (cpuTemp &amp;lt;= cpuTempMin)) and (fanRunning != 0)):&lt;br /&gt;
           if (diagCon): print &amp;quot;Changing Duty Cycle [&amp;quot;, fanSpeedOld, &amp;quot;] -&amp;gt; [Off] Cooling not required.&amp;quot;&lt;br /&gt;
           if (diagLog): fileLog.write ( &amp;quot;Changing Duty Cycle [&amp;quot; + str(fanSpeedOld) + &amp;quot;] -&amp;gt; [Off] Cooling not required\n&amp;quot; )&lt;br /&gt;
           fanSpeed = fanSpeedMin&lt;br /&gt;
           fanSpeedOld = fanSpeedMin&lt;br /&gt;
           fanRunning = 0&lt;br /&gt;
           fan.ChangeDutyCycle(100)&lt;br /&gt;
&lt;br /&gt;
        # If the calculated speed is different from the last cycle, set the fan speed&lt;br /&gt;
        if ((fanSpeed != fanSpeedOld)):&lt;br /&gt;
           if (diagCon): print &amp;quot;Changing Duty Cycle [&amp;quot;, fanSpeedOld, &amp;quot;] -&amp;gt; [&amp;quot;, fanSpeed, &amp;quot;]&amp;quot;&lt;br /&gt;
           if (diagLog): fileLog.write ( &amp;quot;Changing Duty Cycle [&amp;quot; + str(fanSpeedOld) + &amp;quot;] -&amp;gt; [&amp;quot; + str(fanSpeed) + &amp;quot;]\n&amp;quot; )&lt;br /&gt;
           fanRunning = 1&lt;br /&gt;
           fan.ChangeDutyCycle(100-fanSpeed)&lt;br /&gt;
&lt;br /&gt;
        fanSpeedOld = fanSpeed                &lt;br /&gt;
        if (checkLM75): getSensorTemp(I2Cbus)&lt;br /&gt;
&lt;br /&gt;
        # Wait until the next loop cycle&lt;br /&gt;
        if (diagCon): print&lt;br /&gt;
        if (diagLog): fileLog.close()&lt;br /&gt;
        time.sleep(WAIT_TIME)&lt;br /&gt;
&lt;br /&gt;
# If a keyboard interrupt occurs (ctrl + c), set the GPIO to 0 and exit the program.&lt;br /&gt;
except(KeyboardInterrupt):&lt;br /&gt;
    print &amp;quot;Fan speed control script interrupted by the user. CTRL-C was pressed.&amp;quot;&lt;br /&gt;
    GPIO.cleanup()&lt;br /&gt;
    if not fileLog.closed: fileLog.close()&lt;br /&gt;
    sys.exit()&lt;br /&gt;
&lt;br /&gt;
# End of Script&amp;lt;!-- migrated from Comments; original IP: 209.58.142.155 --&amp;gt;&lt;/div&gt;</summary>
		<author><name>209.58.142.155</name></author>
	</entry>
</feed>