2 Relais mit einem Themperatursensor steuern

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Grafkrolock
User
Beiträge: 6
Registriert: Donnerstag 2. August 2018, 18:45

Donnerstag 2. August 2018, 19:33

Hallo
Ich bin leider blutiger anfäger was pythen angeht und deshalb brauch ich mal bitte euer hilfe !
Idee ist es einen art Reifeschrank zu bauen !
Ziel soll es sein abwekselnt 2 Relais abhängig vom wert des Themperatursensores zu schalten !

Fällt der Wert unter z.b. 20 C° soll Relais 1 ( Heitzung ) Angeschalted werden
und Relais 2 (Kühlung ) abgeschaltet werden

Steigt der Wert über z.b.22C° soll Relais 2 (Kühlung ) Angeschalted werden
und Relais 1 ( Heitzung ) abgeschaltet werden

und jetzt weil das ja noch nicht schwer genung ist ;-( soll nach einer bestimmten Zeit ca.15 Stunden

soll Relais 2 (Kühlung ) Angeschalted werden
und Relais 1 ( Heitzung ) abgeschaltet werden

mitlerweile habe ich den Themperatursensor mit dem Raspbeery und python schon soweit bekommen das es ausgelesen wird !
nur momentan stehe ich auf dem schlauch wie ich weiter machen muss !
das ansteuern der Relais bekomme ich auch hin aber mit der Programmirung komme ich einfach nicht weiter !

Ich bitte um eure hilfe !


import glob
import time

pfad = "/sys/bus/w1/devices/"
sensor_ordner = glob.glob(pfad + "28-00000a2f8251*")[0]
sensor_daten_pfad = sensor_ordner + "/w1_slave"

def temperatur_lesen():
datei = open(sensor_daten_pfad, "r")
zeilen = datei.readlines()
datei.close()
return zeilen

def grad_lesen():
zeilen = temperatur_lesen()
while zeilen[0].strip()[-3:] != 'YES':
time.sleep(0.2)
zeilen = temperatur_lesen()
equals_pos = zeilen[1].find('t=')
if equals_pos != -1:
temp_string = zeilen[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
return temp_c
while True:
print(grad_lesen())
time.sleep(1)
Sirius3
User
Beiträge: 8081
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 2. August 2018, 20:14

Das Ermitteln des Pfads ist noch reichlich kompliziert. Um doppelten Code zu vermeiden, benutzt man am besten while-True-Schleifen mit break. Dann braucht man auch keine extra Funktion, um den Sensor zu lesen. Statt find mit Index nimmt man split.

Code: Alles auswählen

import glob
import time

sensor_daten_pfad = "/sys/bus/w1/devices/28-00000a2f8251*/w1_slave"
sensor_daten_pfad = next(glob.iglob(sensor_daten_pfad))

def temperatur_lesen():
    while True:
        with open(sensor_daten_pfad) as lines:
            if "YES" in next(lines):
                temperature = next(lines).split('t=')[-1]
                return float(temperature) / 1000.0
        time.sleep(0.2)

while True:
    print(temperatur_lesen())
    time.sleep(1)
Wo hast Du konkret ein Problem? Beim Temperatur prüfen, oder beim Relayschalten?
Grafkrolock
User
Beiträge: 6
Registriert: Donnerstag 2. August 2018, 18:45

Freitag 3. August 2018, 10:30

Hallo !

Danke für die verbesserung !

Die Relasi kann ich schalten :oops:

hirmit

# GPIO 21 ist fürs Heizen
# GPIO 20 ist fürs Kühlung
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.OUT)
GPIO.output(21, GPIO.LOW)

time.sleep(2)

GPIO.output(21, GPIO.HIGH)
GPIO.cleanup(21)

time.sleep(5)

GPIO.setup(20, GPIO.OUT)
GPIO.output(20, GPIO.LOW)

time.sleep(2)

GPIO.output(20, GPIO.HIGH)
GPIO.cleanup(20)

Mein Problem ist jetzt wie ich das verbinden muss !
es müste doch mit einer IF Schleife funktzioniren ???
aber das bekomme ich einfach nicht hin !
ein weiteres Problem ist das sich ja die steuerung nach einer bestimmten zeit ca 20 Stunden nur noch kühlen soll !
quasi
wie baue ich das ein ??


GPIO.cleanup(21)
GPIO.setup(20, GPIO.OUT)
GPIO.output(20, GPIO.LOW)
Sirius3
User
Beiträge: 8081
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 3. August 2018, 13:10

die WHILE-Schleife zum Bestimmen der Temperatur hast Du schon, eine if-Abfrage der Temperatur solltest Du doch auch hinbekommen.
Bleibt noch die Zeitschaltung, die Du mit dem time oder datetime Modul machen kannst.
Grafkrolock
User
Beiträge: 6
Registriert: Donnerstag 2. August 2018, 18:45

Freitag 3. August 2018, 17:28

Ja sollte ich hin bekommen tue ich aber aus irgendeinem Grund nicht :cry:

ich hab jetzt erstmal versucht eine if schleife einzubauen aber irgedwo muss ein denkfehler drin sein ;-(

Code: Alles auswählen

import glob
import time
import RPi.GPIO as GPIO 
GPIO.setmode(GPIO.BCM)

sensor_daten_pfad = "/sys/bus/w1/devices/28-00000a2f8251*/w1_slave"
sensor_daten_pfad = next(glob.iglob(sensor_daten_pfad))

def temperatur_lesen():
    while True:
        with open(sensor_daten_pfad) as lines:
            if "YES" in next(lines):
                temperature = next(lines).split('t=')[-1]
                return float(temperature) / 1000.0
                time.sleep(0.2)
                
temperatur_lesen()=int(temperatur_lesen())

if temperatur_lesen() < 33 :
        print("Heizung an")
        print("Kühlung aus")
        GPIO.cleanup(20)
        GPIO.setup(21, GPIO.OUT) 
        GPIO.output(21, GPIO.LOW) 
        time.sleep(20) 
        GPIO.output(21, GPIO.HIGH) 
        GPIO.cleanup(21)
        time.sleep(2)
        
else temperatur_lesen() > 33 :
        print("Heizung aus")
        print("Kühlung an")
        GPIO.cleanup(21)
        GPIO.setup(20, GPIO.OUT) 
        GPIO.output(20, GPIO.LOW) 
        time.sleep(20) 
        GPIO.output(20, GPIO.HIGH) 
        GPIO.cleanup(20)
        time.sleep(2)
        
       
while True:
    print(temperatur_lesen())
    time.sleep(1)
die if anweisung löst überhaupt nicht aus
auch else löst nicht aus obwohl die ja eine beding erfüllt sein muss
sorry das ich mich so dumm anstelle ;-(
Benutzeravatar
ThomasL
User
Beiträge: 244
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Freitag 3. August 2018, 17:45

Versuchs mal so

Code: Alles auswählen

temperatur = int(temperatur_lesen())

if temperatur < 33 :
        print("Heizung an")
        print("Kühlung aus")
        GPIO.cleanup(20)
        GPIO.setup(21, GPIO.OUT) 
        GPIO.output(21, GPIO.LOW) 
        time.sleep(20) 
        GPIO.output(21, GPIO.HIGH) 
        GPIO.cleanup(21)
        time.sleep(2)
        
elif temperatur > 33 :
        print("Heizung aus")
        print("Kühlung an")
        GPIO.cleanup(21)
        GPIO.setup(20, GPIO.OUT) 
        GPIO.output(20, GPIO.LOW) 
        time.sleep(20) 
        GPIO.output(20, GPIO.HIGH) 
        GPIO.cleanup(20)
        time.sleep(2)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
Sirius3
User
Beiträge: 8081
Registriert: Sonntag 21. Oktober 2012, 17:20

Freitag 3. August 2018, 18:31

@Grafkrolock: das tut nicht, weil einige SyntaxFehler drin sind. Die solltest Du zuerst beheben. Dann gibt es keine if-Schleifen. Die if-Anweisungen werden also nur einmal zum Start ausgeführt. Die Einrückung von dem von mir kopierten Code ist falsch.
Grafkrolock
User
Beiträge: 6
Registriert: Donnerstag 2. August 2018, 18:45

Freitag 3. August 2018, 20:33

Ok ich werd morgen mal einen neuen Versuch Wagen eine Frage habe ich aber vor Weg! Muss ich themperatur als int gleichsetzen ?
Weil es ist ja bereits eine Zahl oder nimmt das python sonst nicht an ?
Benutzeravatar
ThomasL
User
Beiträge: 244
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Samstag 4. August 2018, 06:54

Nein, musst du nicht.
Python kann auch eine Fließkommazahl mit einer ganzen Zahl vergleichen. z.B. if 3.0 < 10: wird in Wahr aufgelöst.
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
Grafkrolock
User
Beiträge: 6
Registriert: Donnerstag 2. August 2018, 18:45

Montag 6. August 2018, 12:04

so hallo noch mal ich hab es irgendwie hin bekommen :P
und wollte mal nach eure meinung fragen ob man das so lassen kann oder besser nicht ?
laufen tut es aber wie gesagt?
Ist das sinnvoll gerade was die zeutschaltuhr angeht ?

mit anderen worten ich bin für verbesserungsvorschälge offen :-)

Code: Alles auswählen

import glob
import time
import RPi.GPIO as GPI
import datetime

GPIO.setmode(GPIO.BCM)

sensor_daten_pfad = "/sys/bus/w1/devices/28-00000a2f8251*/w1_slave"
sensor_daten_pfad = next(glob.iglob(sensor_daten_pfad))

timeout_start=time.time()
timeout = 300

GPIO.setup(22, GPIO.OUT)
GPIO.setup(21, GPIO.OUT)
GPIO.cleanup(22)
GPIO.cleanup(21)

def temperatur_lesen():
        while True  :
            with open(sensor_daten_pfad) as lines:
                if "YES" in next(lines):
                    temperature = next(lines).split('t=')[-1]
                    return float(temperature) / 1000.0
                    time.sleep(0.2)

while True :
    while time.time() < timeout_start + timeout :
        print(temperatur_lesen())
        time.sleep(1)
        temperatur = int(temperatur_lesen())
        if temperatur <= 32 :
            print("Heizung an")
            print("Kühlung aus")
            GPIO.setup(21, GPIO.OUT) 
            GPIO.output(21, GPIO.LOW) 
            time.sleep(1) 
            GPIO.output(21, GPIO.HIGH) 
            GPIO.cleanup(21)
            time.sleep(1)
        if temperatur >= 33 :
            print("Heizung aus")
            print("Kühlung an")
            GPIO.setup(22, GPIO.OUT) 
            GPIO.output(22, GPIO.LOW) 
            time.sleep(1) 
            GPIO.output(22, GPIO.HIGH) 
            GPIO.cleanup(22)
            time.sleep(1)
    while time.time() > timeout_start + timeout :
        if temperatur >= 7 :
            print(temperatur_lesen())
            print("Heizung aus")
            print("Kühlung an")
            GPIO.setup(22, GPIO.OUT) 
            GPIO.output(22, GPIO.LOW)
Sirius3
User
Beiträge: 8081
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 6. August 2018, 12:25

Das `time.sleep` in `temperatur_lesen` ist immer noch falsch eingerückt. `timeout_start` wird viel zu weit von seiner Benutzung definiert. Funktionsdefinitionen und ausführbaren Code sollte man nicht mischen. Außer Konstanten und Definitionen sollte nichts auf oberster Ebene stehen und Konstanten sollten komplett groß geschrieben werden, dass man sie als solche erkennt, (z.b. TIMEOUT). Module werden dagegen komplett klein geschrieben, statt GPI z.b. gpio. GPIO ist nirgends definiert und führt bei Dir zu einem NameError.
temperatur_lesen sollte nur einmal in der Schleife aufgerufen werden. Ist es Absicht, dass Heizung bzw. Kühlung im Sekundentakt an und ausgeht?
In der zweiten Schleife wird `temperatur` nie geändert, die if-Abfrage ist also unsinnig. der Busy-Loop ist auch nur zum Heizung gut. Die zweite Schleife innere wird nie verlassen, so dass die äußere while-True-Schleife unsinnig ist.

Ständig setup und cleanup aufzurufen ist ungwöhlich. Normalerweise ruft man einmal am Anfang setup und einmal am Schluß cleanup auf.

Code: Alles auswählen

import glob
import time
import RPi.GPIO as gpio

SENSOR_DATEN_PFAD = next(glob.iglob("/sys/bus/w1/devices/28-00000a2f8251*/w1_slave"))
TIMEOUT = 300
PIN_HEATING = 21
PIN_COOLING = 22

def temperatur_lesen():
    while True:
        with open(sensor_daten_pfad) as lines:
            if "YES" in next(lines):
                temperature = next(lines).split('t=')[-1]
                return float(temperature) / 1000.0
        time.sleep(0.2)

def main():
    gpio.setmode(gpio.BCM)
    gpio.setup([PIN_HEATING, PIN_COOLING], gpio.OUT)
    try:
        timeout_start = time.time()
        while time.time() - timeout_start < TIMEOUT:
            temperatur = temperatur_lesen()
            print(temperatur)
            if int(temperatur) <= 32:
                print("Heizung an")
                print("Kühlung aus")
                pin = PIN_HEATING
            else:
                print("Heizung aus")
                print("Kühlung an")
                pin = PIN_COOLING
            gpio.output(pin, gpio.LOW)
            time.sleep(1)
            gpio.output(pin, gpio.HIGH)
            time.sleep(2)
        print("Heizung aus")
        print("Kühlung an")
        gpio.output(PIN_COOLING, gpio.LOW)
        while True:
            print(temperatur_lesen())
            time.sleep(1)
    finally:
        gpio.cleanup()

if __name__ == '__main':
    main()
Grafkrolock
User
Beiträge: 6
Registriert: Donnerstag 2. August 2018, 18:45

Montag 6. August 2018, 19:58

Danke an alle für die hilfe !!!

:shock: den Code muss ich jetzt erst mal sacken lassen :shock:

Es ist Absicht das die relativ nur 1 Sekunden schalten sollen !
Jetzt nur zu Test Zwecken!

Aber wie ich sehe !

Um es mit den Worten von Yoda zu sagen !

Noch viel zu lernen ich habe ! Kann mir jemand gute Lektüre zu Python empfehlen
?
Antworten