Nachtrag: Einige Sachen werden importiert und dann nicht benutzt. Und insbesondere beim Sternchenimport von *allem* was im `Tkinter`-Modul definiert ist, das sind um die 190 Namen, wird nur ein ganz winziger Bruchteil verwendet. Dabei steht die sinnvollere Alternative das Modul unter dem Namen `tk` zu importieren zwar im Quelltext, wird dann aber im weiteren gar nicht verwendet.
``math.pi`` einfach so als Anweisung in den Quelltext zu schreiben ist sinnlos.
Kommentare sollten einen Mehrwert zum Code bieten. Ein Kommentar „Import der Module” vor dem Code mit den ``import``-Anweisungen bringt dem Leser nichts. Als Faustregel sollten Kommentare nicht sagen was der Code tut, denn das sollte man am Code selber ablesen können, sondern *warum* der Code das tut was er tut. Sofern das nicht auch aus dem Code selber schon klar wird.
Das in meinem letzten Beitrag erwähnte Problem wenn man Variablen alle am Anfang auf einem Haufen definiert und dabei dann den Überblick verlieren kann was davon überhaupt gebraucht wird, bestätigt das `x`, das definiert, aber nirgends verwendet wird. Um das festzustellen muss man den ganzen Quelltext absuchen. `diff` wird auch nicht verwendet. Was zwar dokumentiert ist, aber warum etwas definieren von dem man weiss das man es gar nicht verwendet?
Um sicherzustellen das `GPIO.cleanup()` auf jeden Fall aufgerufen wird, auch wenn beispielsweise zwischendurch eine Ausnahme auftritt die das Programm beendet, sollte das in einem ``finally``-Zweig von einem ``try``-Block passieren.
Das auslesen eines Temperaturfühlers wird in dem Quelltext zweimal mit fast identischem Code gemacht. Code- oder Datenwiederholungen sind schlecht. Für Codewiederholungen gibt es Schleifen und/oder Funktionen.
Wenn man Dateien zusammen mit der ``with``-Anweisung öffnet werden sie beim verlassen des ``with``-Blocks, egal aus welchen Gründen, sicher geschlossen.
`e` ist irgendwie überflüssig weil nur ein anderer Name für `y`‽ Die Rückführgrösse ist immer 0 hat also keinen Effekt bei den Berechnungen die damit angestellt werden.
*Ganz* wichtig:
http://if-schleife.de/
Werte und Zeichenketten mittels ``+`` und `str()` zusammenzusetzen ist eher BASIC als Python. In Python verwendet man dafür Zeichenkettenformierung mittels der `format()`-Methode auf Zeichenketten.
Ein ``sys.exit(0)`` am Programmende ist überflüssig, das passiert auch ohne den Aufruf.
Ich komme da ungefähr bei so etwas heraus (ungetestet):
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function
#
# Die Sensoren müssen mit "modprobe w1-gpio" und "modprobe w1-therm" aktiviert
# werden!
#
import Tkinter as tk
from RPi import GPIO
FAN_PIN = 18
INPUT_PIN = 23
TEMPERATURE_SENSOR_PATH_A = '/sys/bus/w1/devices/10-000802de25c6/w1_slave'
TEMPERATURE_SENSOR_PATH_B = '/sys/bus/w1/devices/10-000802de8236/w1_slave'
def read_temperature(sensor_path):
with open(sensor_path) as lines:
next(lines) # Skip first line.
temperature_line = next(lines)
return float(temperature_line.split(' ')[9][2:]) / 1000
class FanUI(tk.Frame):
FAN_MIN_PWM_VALUE = 20
def __init__(self, master, fan_pin, interval):
tk.Frame.__init__(self, master)
self.fan_pin = fan_pin
self.interval = interval
self.temperature_a = None
self.temperature_b = None
self.pwm_value = None
self.temperature_a_label = tk.Label(self)
self.temperature_a_label.pack()
self.temperature_b_label = tk.Label(self)
self.temperature_b_label.pack()
self.fan_speed_label = tk.Label(self)
self.fan_speed_label.pack()
self.pwm = GPIO.PWM(self.fan_pin, self.FAN_MIN_PWM_VALUE)
self.pwm.start(self.FAN_MIN_PWM_VALUE)
self.regulate_fan()
def update_values(self):
for temperature, label in [
(self.temperature_a, self.temperature_a_label),
(self.temperature_b, self.temperature_b_label),
]:
label['text'] = 'temp_a= {0}°C'.format(temperature)
self.fan_speed_label['text'] = 'y = {0}% der maximalen Drehzahl'.format(
self.pwm_value
)
def regulate_fan(self):
self.temperature_a = read_temperature(TEMPERATURE_SENSOR_PATH_A)
self.temperature_b = read_temperature(TEMPERATURE_SENSOR_PATH_B)
pwm_value = 13.33 * abs(self.temperature_b - self.temperature_a) - 6.66
#
# Auf Wertebereich für PWM begrenzen da sonst Fehler auftreten
# (Regelglied).
#
self.pwm_value = max(min(pwm_value, self.FAN_MIN_PWM_VALUE), 100)
self.pwm.ChangeFrequency(pwm_value)
self.pwm.ChangeDutyCycle(pwm_value)
self.update_values()
self.after(self.interval, self.regulate_fan)
def main():
GPIO.setmode(GPIO.BCM)
try:
GPIO.setup(FAN_PIN, GPIO.OUT)
GPIO.setup(INPUT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
root = tk.Tk()
root.title('Auswertung Lüftersteuerung')
fan_ui = FanUI(root, FAN_PIN, 5000)
fan_ui.pack()
root.mainloop()
finally:
GPIO.cleanup()
Die `read_temperature()`-Funktion orientiert sich an Deinem Quelltext und ist ziemlich sicher nicht wirklich robust.
Und GUI und Programmlogik sind hier noch vermischt, was nicht sein sollte.