Temperatursteuerung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
schneiderre
User
Beiträge: 11
Registriert: Montag 1. Mai 2017, 20:40

Hallo Leute,
ich versuche jetzt schon zwei Wochen lang meine Temperatursteuerung für´s Terrarium fertig zu bekommen. Scheitere allerdings an der Steuerung der Heizmatte :( . Da diese zu schnell abkühlt schaltet das Relais jede Minute und das ist auf Dauer bestimmt nicht ganz so gut. Ich möchte, dass die Heizmatte bei Temp_Min (z.B. 25°C) einschaltet und bei Temp_Max (z.B. 30°C) wieder ausschaltet. Das ist nicht das Problem. Sie schaltet allerding sobald Temp_Max unterschritten ist wieder ein und nicht erst wenn Temp_Min erreicht ist :K . Die Werte kommen aus einer DB. Da ich mit Schleifen auf Kriegsfuß stehe komme ich nicht wirklich weiter und am WE sollte eigentlich der Einzug sein. Ich hoffe mir kann jemand auf die Sprünge helfen. Vielen Dank.
Hier noch ein wenig Code wie ich bis jetzt vorgegangen bin. Es sind drei verschiedene Versionen welche ich unabhängig voneinander getestet habe. Jeweils ohne Erfolg.

[codebox=python file=Unbenannt.txt]#!/usr/bin/python
# -*- encoding: utf-8 -*-

# Komponenten importieren
from sys import exit
import RPi.GPIO as GPIO
from time import *
import mysql
import mysql.connector as db
import time
import os

try:
# Verbindung zur Datenbank herstellen
connection = db.connect (host = "localhost", user = "*****", passwd = "*****", db = "*****")

# Fehlerausgabe wenn keine Verbindung möglich
except:
print "Keine Verbindung zum Server"
exit(0)

# Cursorfunktion in Variable schreiben
cursor = connection.cursor()

# Abfrage der Datenbank (Tabelle)
cursor.execute("SELECT * from tbl_temperatur")
result = cursor.fetchall()
cursor.close()

# Variablen aus result definieren
temp_heizmatte = data[16] #z.B. 27°C
temp_heizmatte_min = data[17] #z.B. 25°C
temp_heizmatte_max = data[18] #z.B. 30°C

# Legt GPIO-Format fest
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

# Formatiert Uhrzeit
uhrzeit = time.strftime("%H:%M")

# GPIO Heizmatte
GPIO.setup(29,GPIO.OUT)

print '- - - - Test1 Heizmatte - - - -'
print '..............................'
if temp_heizmatte <= temp_heizmatte_min and temp_heizmatte <= temp_heizmatte_max:
GPIO.output(29,GPIO.LOW)
print '1 - Heizmatte an'
print 'Temp. Heizmatte Min: ' + temp_heizmatte_min
print 'Temp. Heizmatte: ' + temp_heizmatte
print 'Temp. Heizmatte Max: ' + temp_heizmatte_max
elif temp_heizmatte >= temp_heizmatte_max:
GPIO.output(29,GPIO.HIGH)
print '2 - Heizmatte aus'
print 'Temp. Heizmatte Min: ' + temp_heizmatte_min
print 'Temp. Heizmatte: ' + temp_heizmatte
print 'Temp. Heizmatte Max: ' + temp_heizmatte_max
else:
GPIO.output(29,GPIO.HIGH)
print '3 - Heizmatte aus'
print 'Temp. Heizmatte Min: ' + temp_heizmatte_min
print 'Temp. Heizmatte: ' + temp_heizmatte
print 'Temp. Heizmatte Max: ' + temp_heizmatte_max
print '..............................'

#----------------------------------------------------------------------------------------------------------

print '- - - - Test2 Heizmatte - - - -'
print '..............................'
while temp_heizmatte <= temp_heizmatte_max:
GPIO.output(29,GPIO.LOW)
print '1 - Heizmatte an'
print 'Temp. kleiner Temp. Max.'
print 'Temp. Heizmatte Min: ' + temp_heizmatte_min
print 'Temp. Heizmatte: ' + temp_heizmatte
print 'Temp. Heizmatte Max: ' + temp_heizmatte_max
print '..............................'
time.sleep(60)
else:
GPIO.output(29,GPIO.HIGH)
print '2 - Heizmatte aus'
print 'Temp. groesser Temp. Max.'
print 'Temp. Heizmatte Min: ' + temp_heizmatte_min
print 'Temp. Heizmatte: ' + temp_heizmatte
print 'Temp. Heizmatte Max: ' + temp_heizmatte_max
print '..............................'

#----------------------------------------------------------------------------------------------------------

print '- - - - Test3 Heizmatte - - - -'
print '..............................'
while True:
temp_heizmatte <= temp_heizmatte_max
GPIO.output(29,GPIO.LOW)
print '1 - Heizmatte an'
print 'Temp. Heizmatte Min: ' + temp_heizmatte_min
print 'Temp. Heizmatte: ' + temp_heizmatte
print 'Temp. Heizmatte Max: ' + temp_heizmatte_max
print '..............................'
time.sleep(60)
while temp_heizmatte >= temp_heizmatte_max:
GPIO.output(29,GPIO.HIGH)
print '3 - Heizmatte aus'
print 'Temp. Heizmatte Min: ' + temp_heizmatte_min
print 'Temp. Heizmatte: ' + temp_heizmatte
print 'Temp. Heizmatte Max: ' + temp_heizmatte_max
print '..............................'

#----------------------------------------------------------------------------------------------------------

# Datenbank schließen
connection.close()[/code]
Zuletzt geändert von Anonymous am Dienstag 25. Juli 2017, 16:19, insgesamt 2-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1020
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ich habe mal erlebt, dass ein Techniker eine PWM Steuerung mit einem mechanischem Relais verwirklicht hat. Da dort ziemlich viel Strom drüber ging, ist ein Hallenschiff komplett abgebrannt. Die Versicherung hat sich gefreut.

Du benötigst eine Hysterese. Relais bei 20°C einschalten und bei 30°C wieder ausschalten und erst bei 20° wieder einschalten. Dazu musst du den letzten Status deines Relais in einer Variable speichern und abhängig vom letzten Status und der Sensordaten ein- bzw. ausschalten.

Code: Alles auswählen

class Hysterese:
    def __init__(self, on_temp, off_temp):
        self.state = False
        self.on_temp = on_temp
        self.off_temp = off_temp
    def update(self, temp):
        if temp <= self.on_temp:
            self.state = True
            return self.state
        elif temp >= self.off_temp:
            self.state = False
            return self.state
        elif self.on_temp < temp < self.off_temp:
            return self.state
Der Code sollte eigentlich selbsterklärend sein, sofern du so ungefähr weißt was Klassen sind.
Im letzten Teil, wenn die Temperatur genau zwischen den beiden festgelegten Punkten liegt, wird einfach der letzte Status ausgegeben, ohne ihn zuvor zu setzen. Das verhindert das ein- und ausschalten bei der Temperatur, bei der wieder ausgeschaltet werden soll.

Den Code solltest du vorher in der repl testen, bevor du ihn einsetzt.

Code: Alles auswählen

hyst = Hysterese(20, 30)
[(temp, hyst.update(temp)) for temp in range(10, 35)]
[(temp, hyst.update(temp)) for temp in range(35, 10, -1)]
Zuletzt geändert von Anonymous am Dienstag 25. Juli 2017, 16:20, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
schneiderre
User
Beiträge: 11
Registriert: Montag 1. Mai 2017, 20:40

Hallo DeaD_EyE,
herzlichen Dank für deine schnelle Antwort.
Mit Klassen kenne ich mich nicht wirklich aus, aber so habe ich auf jeden Fall einen Anhaltspunkt und weiß wonach ich suchen muss. Ich werde deinen Code gleich mal testen und dir eine Rückmeldung geben-
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

So richtig die Anmerkung von DeaD_EyE ist, moechte ich noch was generelles zu bedenken geben: ich wuerde das *NICHT* mit dem PI machen. Im Terrarium leben Tiere, und blos weil der PI mal abstuerzt (und das wird er), und ggf. Probleme hat mit dem wieder hochfahren (das kann gut sein), sollten die nicht leiden, oder gar schlimmeres.

Ich wuerde darum *nachdruecklich* zu entweder einer kommerziellen Loesung raten, oder wenigstens einem Arduino, der eine solche kleine Aufgabe auch problemlos erledigt, aber dabei hoch robust ist.
schneiderre
User
Beiträge: 11
Registriert: Montag 1. Mai 2017, 20:40

So, ich habe es jetzt mit meinen Variablen aus der DB angepasst und getestet.
Die Heizmatte geht an und schaltet bei Temp_Max aus und bleibt dann auch aus. Die Temp sinkt. Allerdings schaltet die beim Unterschreiten von Temp_Min nicht wieder ein.

[codebox=python file=Unbenannt.txt]
class Hysterese:
def __init__(self, temp_heizmatte_min, temp_heizmatte_max):
self.state = False
self.temp_heizmatte_min = temp_heizmatte_min
self.temp_heizmatte_max = temp_heizmatte_max
def update(self, temp_heizmatte):
if temp_heizmatte <= self.temp_heizmatte_min:
self.state = True
GPIO.output(29,GPIO.LOW)
print '1 - Heizmatte an'
return self.state
elif temp_heizmatte >= self.temp_heizmatte_max:
self.state = False
GPIO.output(29,GPIO.HIGH)
print '2 - Heizmatte aus'
return self.state
elif self.temp_heizmatte_min < temp_heizmatte < self.temp_heizmatte_max:
GPIO.output(29,GPIO.HIGH)
print '3 - Heizmatte aus'
return self.state

hyst = Hysterese(25, 30)
[(temp_heizmatte, hyst.update(temp_heizmatte)) for temp in range(25, 30)]
[(temp_heizmatte, hyst.update(temp_heizmatte)) for temp in range(30, 25, -1)]
[/code]

@ __deets__
Vielen Dank für deine Anmerkung. Ich habe den PI jetzt seit zwei Monaten mit zahlreichen Skripten laufen. Er hat ne USV. Sollte er mal ausgehen fährt er selbstständig wieder hoch. Ich werden aber trotzdem über den Einsatz eines Arduino nachdenken.
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

schneiderre hat geschrieben: @ __deets__
Vielen Dank für deine Anmerkung. Ich habe den PI jetzt seit zwei Monaten mit zahlreichen Skripten laufen. Er hat ne USV. Sollte er mal ausgehen fährt er selbstständig wieder hoch. Ich werden aber trotzdem über den Einsatz eines Arduino nachdenken.
Die Sache ist m.M.n. eher ethischer Natur. Für Soft- und Hardware Systeme, deren korrekte Funktionsweise Auswirkungen auf Menschenleben hat, gibt es recht hohe Anforderungen. Da nimmt man zum Beispiel dezidierte, eingebettete Systeme mit maßgeschneiderter Software, die direkt oder über ein zertifziertes Realtime OS mit der Hardware spricht. Im Kontrast dazu ist der Raspberry PI, wenn man es herunterbricht, im Kern ein ~35 € Lerncomputer, der nicht auf Zuverlässigkeit ausgerichtet ist und auf dem normalerweise ein "volles" Betriebssystem läuft. Damit dein Skript überhaupt starten kann, müssen diverse andere Software-Komponenten ebenfalls arbeiten; es läuft also einiges an Overhead, der für die eigentliche Steueraufgabe gar nicht notwendig wäre, aber im Zweifelsfall dafür Sorgen kann, dass dein Skript nicht (korrekt) läuft. Abgesehen vom Stromausfall gibt es ja auch diverse andere Fälle, in denen das System zwar läuft, aber nicht korrekt arbeitet. Die Frage wäre daher, wie schädlich es für die Tiere ist, wenn der Worst-Case eintritt und dieses System ausfällt.
schneiderre
User
Beiträge: 11
Registriert: Montag 1. Mai 2017, 20:40

Hallo nezzcarth,
auf dem PI laufen im Minutentakt zahlreiche Skripte zum auslesen der Temperaturen und Luftfeuchte und zur Steuerung der anderen Komponenten. Der PI läuft wie gesagt seit zwei Monaten stabil ohne jegliche Störungen. Sollte es trotzdem mal zu einem Ausfall kommen ist es nicht wirklich ein Problem, da meinen Schlangen nichts passiert falls mal das Licht oder die Heizmatte aus sind. Und für den absoluten Notfall habe ich noch einen zweiten PI auf welchen ich das Packup aufspielen könnte und alles wäre wieder OK. Von daher bin bei dem Thema sehr entspannt.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1020
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Da muss ich den anderen Recht geben. Da es sich um fühlende Lebewesen handelt, wäre es unverantwortlich die Kontrolle einem oder mehren Raspberry PI zu überlassen, die dafür bekannt sind, dass sie nicht stabil laufen. Auch wenn du andere Erfahrungen bis jetzt gesammelt hast, wir haben die Erfahrung, dass es so ist.

In der Klasse solltest du übrigens den GPIO nicht direkt ansteuern. Mach das außerhalb der Klasse. Die Variablen in der Klasse hättest du gar nicht anpassen müssen. Da sehe ich auch schon die Probleme. Ein Programm, dass Laienhaft zusammen gestrickt wird und der Programmierer noch nicht einmal Tests implementiert hat, möchte das sein Programm über Leben und Tod entscheidet. Dein Programm wäre in der Zertifizierung noch nicht einmal näher betrachtet worden.

Mein Beispiel, dass ein Hallenschiff abgebrannt ist, kam nicht so von ungefähr. Das ist wirklich passiert und es waren Fachkräfte involviert.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
BlackJack

@schneiderre: Das der zwei Monate stabil läuft, hat ja erst einmal nichts zu sagen. Ein grosses Problem bei einem so komplexen, kompletten, normalen Betriebssystem ist halt auch das da ganz viel schief laufen kann. Auch etliche Sachen die beispielsweise verhindern, dass der nach einem Neustart wieder hoch kommt. Alleine eine SD-Karte ist so ein Punkt der bei zu viel Wärme oder Stromausfall wirklich sehr gerne mal Probleme bereitet. Von kaputten Dateisystemen bis hin zu Karten die einen physischen Schaden haben.
schneiderre
User
Beiträge: 11
Registriert: Montag 1. Mai 2017, 20:40

Ok, dann werde ich mein Vorhaben beerdigen und doch wieder auf Zeitschaltuhren mit Temperaturfühler zurückgreifen. Trotzdem vielen Dank für eure Mühe.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

schneiderre hat geschrieben:Ok, dann werde ich mein Vorhaben beerdigen und doch wieder auf Zeitschaltuhren mit Temperaturfühler zurückgreifen.
Die versagen auch bei Stromausfall. Können tropische Schlangen in frostsicheren Räumen einen Schaden nehmen oder fahren die nur herunter?
schneiderre
User
Beiträge: 11
Registriert: Montag 1. Mai 2017, 20:40

@Melewo
Daher habe ich am PI auch eine USV welcher ihn bei Batterieladung unter 10% kontrolliert herunter fährt. Wenn die Steuerung für mehrere Stunden nicht funktionieren sollte sterben sie nicht gleich, sie werden nur träge und sonst nichts. Selbst ein zwei Tage wären kein Problem. Ich war letztens Arbeiten und die Wärmelampe ist kaputt gegangen (Was ja immer passieren kann, egal wie man es realisiert ob PI, Zeitschaltuhr oder prof. Steuerung) und war mehrere Stunden aus und alles war gut.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

Meine ich, die haben doch da auch ein Temperaturgefälle zwischen Tag und Nacht und werden sich bei Abkühlung verkriechen oder wie auch immer.
Du könntest Dir sicherlich mittelfristig wie __deets__ schrieb so einen Arduino ansehen, wobei ich jetzt zwar nicht wüsste, wie die mit Python angesprochen werden, nur so kompliziert soll das nicht sein, las ich. Und bis Du Dich da hineingefunden hast, machst Du es erst einmal so, wie es für Dich und die Schlagen am geeignetsten ist.
schneiderre
User
Beiträge: 11
Registriert: Montag 1. Mai 2017, 20:40

Melewo hat geschrieben:Meine ich, die haben doch da auch ein Temperaturgefälle zwischen Tag und Nacht und werden sich bei Abkühlung verkriechen oder wie auch immer.
Du könntest Dir sicherlich mittelfristig wie __deets__ schrieb so einen Arduino ansehen, wobei ich jetzt zwar nicht wüsste, wie die mit Python angesprochen werden, nur so kompliziert soll das nicht sein, las ich. Und bis Du Dich da hineingefunden hast, machst Du es erst einmal so, wie es für Dich und die Schlagen am geeignetsten ist.
Genau so sieht es aus. Klingt auf jeden Fall nach nem Plan :D . So lange würde ich es mit dem PI realisieren, da ich dort Monate an Zeit reingesteckt habe. Leider hänge ich immer noch an der Schaltung der Heizmatte.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

Was aber nicht an den Statements liegen dürfte, die sind eigentlich richtig, eher am Rest Deines Codes.

Code: Alles auswählen

class Hysterese:
    def __init__(self, temp_heizmatte_min, temp_heizmatte_max):
        self.state = False
        self.temp_heizmatte_min = temp_heizmatte_min
        self.temp_heizmatte_max = temp_heizmatte_max
        
    def update(self, temp_heizmatte):
        #          24               25
        if temp_heizmatte <= self.temp_heizmatte_min:
            self.state = True
            return self.state
        #          31               30
        elif temp_heizmatte >= self.temp_heizmatte_max:
            self.state = False
            return self.state
        #          25                   von 26 bis 29            30
        elif self.temp_heizmatte_min < temp_heizmatte < self.temp_heizmatte_max:
            self.state = False
            return self.state
 
hyst = Hysterese(25, 30)
print(hyst.update(25))  # True bis 25 und False ab 26
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

@ schneiderre
Ich spiele auch ab und zu (wenn auch unter völlig anderen Rahmenbedingungen) mit einer Heizmatte rum. Dabei ist mir mal unbemerkt ein Relais kaputt gegangen und "plötzlich" war meine Heizplatte über 120°C warm, Tendenz steigend...
Damit will ich auch nur sagen, dass noch schlimmere Sachen passieren können, als dass sie nur nicht mehr heizt...
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Melewo: Ergänzend: Der Code ist nicht nur keine Hysterese sondern auch überkompliziert und funktioniert analog zu:

Code: Alles auswählen

def update(self, temp_heizmatte):
    return temp_heizmatte <= self.temp_heizmatte_min
Kompakt und richtig wäre:

Code: Alles auswählen

def update(self, temp_heizmatte):
    if temp_heizmatte <= self.temp_heizmatte_min:
        self.state = True
    elif temp_heizmatte >= self.temp_heizmatte_max:
        self.state = False
    return self.state
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

@kbr: Ist beides nicht richtig. Es geht ja darum, dass die weniger oft anspringt und weniger oft schaltet. Und somit bei 3 bei 26 bis 29 Grad weiterläuft, falls gerade am Laufen und aus bleibt, falls nicht gerade am Laufen. Nur soweit habe ich heute Morgen noch nicht gedacht. Der aktuelle Stand, ob am Laufen oder nicht, müsste somit mit verglichen werden.
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Melewo hat geschrieben:@kbr: Ist beides nicht richtig. Es geht ja darum, dass die weniger oft anspringt und weniger oft schaltet. Und somit bei 3 bei 26 bis 29 Grad weiterläuft, falls gerade am Laufen und aus bleibt, falls nicht gerade am Laufen. Nur soweit habe ich heute Morgen noch nicht gedacht.
Ich behaupte jetzt einfach mal, dass das Programm von kbr genau das macht :wink:
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

Zizibee hat geschrieben:Ich behaupte jetzt einfach mal, dass das Programm von kbr genau das macht :wink:
Ich denke eher das von DeaD_EyE. Zumindest findet bei kbr keine Prüfung statt, ob die Heizung gerade läuft oder nicht und der aktuelle Stand müsste ja zwischengespeichert werden.
Zuletzt geändert von Melewo am Mittwoch 26. Juli 2017, 10:35, insgesamt 1-mal geändert.
Antworten