Skip to content

Instantly share code, notes, and snippets.

@xxmatyuk
Last active January 1, 2021 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xxmatyuk/5f37b719b8ba76bb6e5ce06e431b015d to your computer and use it in GitHub Desktop.
Save xxmatyuk/5f37b719b8ba76bb6e5ce06e431b015d to your computer and use it in GitHub Desktop.
The first draft of a small Flask app running on Raspberry Pi to read DH-22 sensors temperature and to operate Noctua fans (A6 and A12) via GPIO PWM.
import board
import atexit
import json
import adafruit_dht
import RPi.GPIO as GPIO
from flask import Flask
# Fans
FANS_PIN = 21
PWM_DEFAULT_FREQ = 100
PWM_DEFAULT_DUTY = 75
DEFAULT_RPM_A6 = 3000
DEFAULT_RPM_A12 = 2000
# Sensors
DHT_PIN_16 = 16
DHT_PIN_20 = 20
DHT_DEVICES = {
DHT_PIN_20: adafruit_dht.DHT22(board.D20),
DHT_PIN_16: adafruit_dht.DHT22(board.D16)
}
# Flask stuff
app = Flask(__name__)
# Global vars
fans = None
current_pwm_duty = None
current_pwm_frequency = None
def _init_pwm():
"""Inits PWM fans controls"""
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(FANS_PIN, GPIO.OUT, initial=GPIO.LOW)
global fans
fans = GPIO.PWM(FANS_PIN, PWM_DEFAULT_FREQ)
def _stop_fans():
"""Stops fans without loosing controls"""
global fans, current_pwm_duty
if fans:
fans.stop()
current_pwm_duty = 0
def _stop_pwm_fans_control():
"""Stops fans and does cleanup"""
global fans
_stop_fans()
GPIO.cleanup()
fans = None
def _set_fans_pwm_duty_cycle(percent):
"""Sets fans' duty cycle"""
global fans, current_pwm_duty
if fans:
fans.ChangeDutyCycle(percent)
current_pwm_duty = percent
def _set_fans_pwm_frequency(freq):
"""Sets fans' frequency"""
global fans, current_pwm_frequency
if fans:
fans.ChangeFrequency(freq)
current_pwm_frequency = freq
def _get_current_rpm():
"""Returns RPM values based on PWM status and its values of duty and frequency"""
global fans, current_pwm_duty
if not fans:
return DEFAULT_RPM_A6, DEFAULT_RPM_A12
elif fans and current_pwm_duty == 0:
return 0, 0
elif fans and current_pwm_duty == 100:
return DEFAULT_RPM_A6, DEFAULT_RPM_A12
else:
return (current_pwm_duty*DEFAULT_RPM_A6)/100, (current_pwm_duty*DEFAULT_RPM_A12)/100
def _get_sensor_temperature(pin):
"""Gets tempreature mesure of a given sensor"""
try:
d = DHT_DEVICES.get(pin, None)
if d:
return d.temperature
except Exception:
return -100
def _get_average_temperature():
"""Gets average temperature from two available sensors"""
t1 = _get_sensor_temperature(DHT_PIN_16)
t2 = _get_sensor_temperature(DHT_PIN_20)
if t1 and t2:
return (t1 + t2)/2
@app.route("/get-sensor-temperature/<int:pin>")
def get_sensor_temp(pin):
return str(_get_sensor_temperature(pin))
@app.route("/get-average-temperature")
def get_avg_temp():
return str(_get_average_temperature())
@app.route("/pwm/start")
def pwm_start():
msg = "No action taken"
try:
global fans, current_pwm_duty, current_pwm_frequency
_init_pwm()
fans.start(PWM_DEFAULT_DUTY)
current_pwm_duty = PWM_DEFAULT_DUTY
current_pwm_frequency = PWM_DEFAULT_FREQ
return "Started."
except RuntimeError:
return msg
return msg
@app.route("/pwm/set-duty/<int:percent>")
def pwm_set_duty(percent):
global fans
if fans:
_set_fans_pwm_duty_cycle(percent)
return "Duty is set to: %s" % percent
return "No action taken."
@app.route("/pwm/set-frequency/<int:freq>")
def pwm_set_frequency(freq):
global fans
if fans:
_set_fans_pwm_frequency(freq)
return "Frequency is set to: %s" % freq
return "No action taken."
@app.route("/pwm/stop")
def pwm_stop():
global fans
if fans:
_stop_fans()
return "Stopped."
return "No action taken."
@app.route("/pwm/cleanup")
def pwm_cleanup():
global fans
if fans:
_stop_pwm_fans_control()
return "Contols stopped."
return "No action taken."
@app.route("/stats")
def stats():
global fans, current_pwm_duty, current_pwm_frequency
rpm_a6, rpm_a12 = _get_current_rpm()
stats = {
"pwm_enabled": True if fans else False,
"t1_temperature": _get_sensor_temperature(DHT_PIN_16),
"t2_temperature":_get_sensor_temperature(DHT_PIN_20),
"pwm_duty_cycle": current_pwm_duty if fans else 0,
"pwm_frequency": current_pwm_frequency if fans else 0,
"rpm_a6": rpm_a6,
"rpm_a12": rpm_a12,
}
return json.dumps(stats, indent=4)
atexit.register(_stop_pwm_fans_control)
if __name__ == "__main__":
app.run(host='0.0.0.0')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment