Aquariumsteuerung mit Raspi und Python
Verfasst: Samstag 13. Februar 2021, 19:48
Hallo in die Runde,
ich bin ganz neu hier, auch was das Thema "Python" betrifft, bin ich Autodidakt. Man möge mir nachsehen. Ich habe mir eine kleine Aquariensteuerung gebaut - mittels Raspi und Relaisboard. Dazu habe ich mir ein Python-Script zusammengebastelt, was jetzt wohl das Problem zu sein scheint.
Ich habe es direkt auf dem Raspi in Thonny-Python aus diversen "Schnipseln" zusammengebaut. In Thonny lief es auch zeitweise, wenn ich es über die Kommandozeile gestartet habe, nur sehr kurz und hing sich dann auf.
Ich komm nicht mehr weiter, woran das liegen könnte. Wahrscheinlich schlagt ihr die Hände über dem Kopf zusammen, aber vielleicht hätte ja jemand mal die Zeit, über das Script zu schauen:
Das eingebundene Script lcddriver sieht weifolgt aus:
Vielen Dank schonmal für Hilfe, Tipps und Ratschläge
ich bin ganz neu hier, auch was das Thema "Python" betrifft, bin ich Autodidakt. Man möge mir nachsehen. Ich habe mir eine kleine Aquariensteuerung gebaut - mittels Raspi und Relaisboard. Dazu habe ich mir ein Python-Script zusammengebastelt, was jetzt wohl das Problem zu sein scheint.
Ich habe es direkt auf dem Raspi in Thonny-Python aus diversen "Schnipseln" zusammengebaut. In Thonny lief es auch zeitweise, wenn ich es über die Kommandozeile gestartet habe, nur sehr kurz und hing sich dann auf.
Ich komm nicht mehr weiter, woran das liegen könnte. Wahrscheinlich schlagt ihr die Hände über dem Kopf zusammen, aber vielleicht hätte ja jemand mal die Zeit, über das Script zu schauen:
Code: Alles auswählen
#!/usr/bin/env python3
"""
*************************** Variablen ******************************
#NanoCube
CO2Cube = Boolean, Schaltzustand CO2Cube
#Amazonas-Becken
UVLampe = Boolean, Schaltzustand UVLampe
CO2Pumpe = Boolean, Schaltzustand CO2Pumpe
CO2Ama = Boolean, Schaltzustand CO2Ama
Bodenheizer = Boolean, Schaltzustand Bodenheizer
Stabheizer = Boolean, Schaltzustand Stabheizer
Fuellpumpe = Boolean, Schaltzustand Fuellpumpe
Duengerpumpe = Boolean, Schaltzustand Duengerpumpe
alive = Boolean, Anzeige, dass Programm läuft
t1 = Einschaltzeit 1 UVLampe
t2 = Ausschaltzeit 1 UVLampe
t3 = Einschaltzeit 2 UVLampe
t4 = Ausschaltzeit 2 UVLampe
t5 = Einschaltzeit 3 CO2Pumpe
t6 = Ausschaltzeit 3 CO2Pumpe
t7 = Einschaltzeit 1 CO2Cube
t8 = Ausschaltzeit 1 CO2Cube
t9 = Einschaltzeit 2 CO2Ama
t10 = Ausschaltzeit 2 CO2Ama
Duengen = Zeitpunkt für Tagesduenger
Nachfuellen = Zeitpunkt für Nachfuellen
Ln = Fuellstand Normallevel
Ll = Fuellstand Lowlevel
Lh = Fuellstand Highlevel
s1 = Dauer Doesierung Tagesduenger in sec
s2 = Dauer Nachfuellen ins sec
Temp1 = Temperatur1 in °C
Temp2 = Temperatur2 in °C
BHL = Bodenheizer Low (ein)
BHH = Bodenheizer High (aus)
SHL = Stabheizer Low (ein)
SHH = Stabheizer High (aus)
TWH = Temperatur-Warnlevel High
TWL = Temperatur-Warnlever Low
************************ Ende Variablen ******************************
"""
# ******************** Importierte Module *****************************
import time
import RPi.GPIO as GPIO
import re
import lcddriver
from time import *
from time import sleep
# ******************* Definieren der GPIOs ***************************
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.OUT) # UVLampe
GPIO.setup(15, GPIO.OUT) # CO2Pumpe
GPIO.setup(18, GPIO.OUT) # CO2Cube
GPIO.setup(17, GPIO.OUT) # CO2Ama
#GPIO.setup(24, GPIO.OUT) # Bodenheizer
GPIO.setup(25, GPIO.OUT) # Stabheizer
GPIO.setup(8, GPIO.OUT) # Fuellpumpe
GPIO.setup(7, GPIO.OUT) # Duengerpumpe
GPIO.setup(5, GPIO.OUT) # Alive
GPIO.setup(4, GPIO.OUT) # Temperatur out of range
GPIO.setup(20, GPIO.OUT) # Fuellstand Trigger
GPIO.setup(21, GPIO.IN) # Fuellstand Echo
GPIO_TRIGGER = 20
GPIO_ECHO = 21
# ****************** Beginn Einstellparameter **************************
# Ein- und Ausschaltzeiten der Lampen
# UVLampe
t1 = "04:00"
t2 = "07:00"
t3 = "13:00"
t4 = "16:00"
# CO2Pumpe
t5 = "11:00"
t6 = "19:00"
# CO2Cube
t7 = "11:00"
t8 = "16:00"
# CO2Ama
t9 = "11:00"
t10 = "18:00"
# Duengerpumpe
s1 = 10
Duengen = "11:00"
# Fuellstand
Ln = 4.0 # Abstand Normal-Level
Ll = -1.0 # Level-Low
Lh = 0.5 # Level-High
s2 = 60 # Maximale Pumpdauer
# Temperatur-Schaltpunkte
# BHL = 22.0 # Bodenheizer Low (ein)
# BHH = 25.0 # Bodenheizer High (aus)
SHL = 23.5 # Stabheizer Low (ein)
SHH = 24.0 # Stabheizer High (aus)
TWH = 24.8 # Warnlevel Temperatur High
TWL = 22.0 # Warnlevel Temperatur Low
# ************************ Ende Einstellparameter *******************************
# ************************ Beginn Programm **************************************
# Initialisieren aller Ausgaenge auf AUS
GPIO.output(14, False)
GPIO.output(15, False)
GPIO.output(18, False)
GPIO.output(17, False)
# GPIO.output(24, False)
GPIO.output(25, False)
GPIO.output(8, False)
GPIO.output(7, False)
GPIO.output(5, False)
# Initialisieren der Variablen
UVLampe = False
CO2Pumpe = False
CO2Cube = False
CO2Ama = False
#Bodenheizer = False
Stabheizer = False
Fuellpumpe = False
Duengerpumpe = False
zeit = strftime("%H:%M", localtime())
alive = False
Fuellstand = False
Abstand = False
# Initialisieren des Displays
lcd = lcddriver.lcd()
lcd.lcd_clear()
# Uhrzeit wie viele Sekunden
TIME_DELAY = 1
# Temperaturanzeige in Sekunden
TEMPERATUR_DELAY = 1
# Entfernungsmessung
def distanz():
# setze Trigger auf HIGH
GPIO.output(GPIO_TRIGGER, True)
# setze Trigger nach 0.01ms aus LOW
sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
StartZeit = time()
StopZeit = time()
# speichere Startzeit
while GPIO.input(GPIO_ECHO) == 0:
StartZeit = time()
# speichere Ankunftszeit
while GPIO.input(GPIO_ECHO) == 1:
StopZeit = time()
# Zeit Differenz zwischen Start und Ankunft
TimeElapsed = StopZeit - StartZeit
# mit der Schallgeschwindigkeit (34300 cm/s) multiplizieren
# und durch 2 teilen, da hin und zurueck
distanz = Ln - ((TimeElapsed * 34300) / 2)
return distanz
# Auslesen der Temperatursensoren
# Temperatur 1 ermitteln und Wert value zurückgeben
def GetTemp1():
a1 = open('/sys/bus/w1/devices/' + '28-031650f6d9ff' + '/w1_slave') # Ermittelten Sensor lesen
Temp1 = a1.readline()
if re.match(r"([0-9a-f]{2} ){9}: crc=[0-9a-f]{2} YES", Temp1): # Erste Zeile auf "YES" am Ende uberprufen
Temp1 = a1.readline()
m1 = re.match(r"([0-9a-f]{2} ){9}t=([+-]?[0-9]+)", Temp1) # Wert aus zweiter Zeile prufen
if m1:
value1 = str(float(m1.group(2)) / 1000.0) # Wert nach t= auslesen und umwandeln
a1.close()
return value1 # Ruckgabewert "value" definieren
# Temperatur 2 ermitteln und Wert value zurckgeben
def GetTemp2():
a2 = open('/sys/bus/w1/devices/' + '28-0416545902ff' + '/w1_slave') # Ermittelten Sensor lesen
Temp2 = a2.readline()
if re.match(r"([0-9a-f]{2} ){9}: crc=[0-9a-f]{2} YES", Temp2): # Erste Zeile auf "YES" am Ende uberprufen
Temp2 = a2.readline()
m2 = re.match(r"([0-9a-f]{2} ){9}t=([+-]?[0-9]+)", Temp2) # Wert aus zweiter Zeile prufen
if m2:
value2 = str(float(m2.group(2)) / 1000.0) # Wert nach t= auslesen und umwandeln
a2.close()
return value2 # Ruckgabewert "value" definieren
while True: # Schleife endlos laufen lassen
try: # Moeglichkeit Fehler abzufangen
Abstand = round(float(distanz()),1)
Temp1 = round(float(GetTemp1()),1) # Die Temperatur in eine Zahl wandeln....
Temp2 = round(float(GetTemp2()),1) # Die Temperatur in eine Zahl wandeln....
Fuellstand = str(Abstand)
Temp_1 = str(Temp1)
Temp_2 = str(Temp2)
cputemp = str(round(float(open("/sys/class/thermal/thermal_zone0/temp", "r").read())/1000, 1))
lcd.lcd_display_string("Amazonasb.: "+Temp_1+chr(223)+"C", 1)
lcd.lcd_display_string("NanoCube : "+Temp_2+chr(223)+"C", 2)
lcd.lcd_display_string("CPU-Temp. : "+cputemp+chr(223)+"C", 3)
lcd.lcd_display_string("Fuellstand: "+Fuellstand, 4)
except KeyboardInterrupt: # Ausnahme STR+C festlegen
GPIO.cleanup()
# Auswerten der Zeit und Schalten der Ausgaenge
# UVLampe
if (zeit >= t1 and zeit<= t2) or (zeit >= t3 and zeit<= t4) :
GPIO.output(14, True)
UVLampe = False
else :
GPIO.output(14, False)
UVLampe = True
# CO2Pumpe
if (zeit >= t5 and zeit<= t6) :
GPIO.output(15, True)
CO2Pumpe = False
else :
GPIO.output(15, False)
CO2Pumpe = True
# CO2
if (zeit >= t7 and zeit <= t8) :
GPIO.output(18, True)
CO2Cube = False
else :
GPIO.output(18, False)
CO2Cube = True
#sleep(2)
if (zeit >= t9 and zeit <= t10) :
GPIO.output(17, True)
CO2Ama = False
else :
GPIO.output(17, False)
CO2Ama = True
# Temperatur
# if (Temp1 < BHL) :
# GPIO.output(24, True)
# Bodenheizer = False
# if (Temp1 > BHH) :
# GPIO.output(24, False)
# Bodenheizer = True
if (Temp1 < SHL) :
GPIO.output(25, True)
Stabheizer = False
if (Temp1 > SHH) :
GPIO.output(25, False)
Stabheizer = True
# if (temp >= TWL) and (temp <= TWH) :
# GPIO.output(24, False)
# GPIO.output(25, False)
# else:
# GPIO.output(24, True)
# GPIO.output(25, True)
# Fuellpumpe
if (Abstand < Ll) :
GPIO.output(8, True)
Fuellpumpe = False
if (Abstand > Lh) :
GPIO.output(8, False)
Fuellpumpe = True
# Output von x Zeilen zum Klaeren des Bildschirms
zaehler= 10
while zaehler>0:
print("*")
zaehler-=1
# Ausgabe der Zeit
zeit =strftime("%H:%M:%S", localtime())
print (zeit)
# Ausgabe aller Schaltzustaende
if UVLampe == False:
print("UV-Lampe an")
else:
print("UV-Lampe aus")
if CO2Pumpe == False:
print("CO2-Pumpe an")
else:
print("CO2-Pumpe aus")
if CO2Cube == False:
print("CO2-Cube an")
else:
print("CO2-Cube aus")
if CO2Ama == False:
print("CO2-Ama an")
else:
print("CO2-Ama aus")
# Temperatur ausgeben
print(str("Temperatur 1 =") + ' %2.1f °C' % Temp1)
print(str("Temperatur 2 =") + ' %2.1f °C' % Temp2)
# Fuellstand ausgeben
print(str("Füllstand =") + ' %2.1f cm' % Abstand)
if Fuellpumpe == False:
print("Fuellpumpe an")
else:
print("Fuellpumpe aus")
# if Bodenheizer == False:
# print("Bodenheizer an")
# else:
# print("Bodenheizer aus")
if Stabheizer == False:
print("Stabheizer an")
else:
print("Stabheizer aus")
if alive == True:
GPIO.output (5, True)
alive = False
print ("x")
else:
GPIO.output (5, False)
alive = True
print ("+")
sleep (0.1)
Code: Alles auswählen
import sys
sys.path.append("./lib")
import i2c_lib
from time import *
# LCD Address
ADDRESS = 0x27
# commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80
# flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00
# flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00
# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00
# flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00
# flags for backlight control
LCD_BACKLIGHT = 0x08
LCD_NOBACKLIGHT = 0x00
En = 0b00000100 # Enable bit
Rw = 0b00000010 # Read/Write bit
Rs = 0b00000001 # Register select bit
class lcd:
#initializes objects and lcd
def __init__(self):
self.lcd_device = i2c_lib.i2c_device(ADDRESS)
self.lcd_write(0x03)
self.lcd_write(0x03)
self.lcd_write(0x03)
self.lcd_write(0x02)
self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE)
self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON)
self.lcd_write(LCD_CLEARDISPLAY)
self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT)
sleep(0.2)
#clocks EN to latch command
def lcd_strobe(self, data):
self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT)
sleep(.0005)
self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT))
sleep(.0001)
def lcd_write_four_bits(self, data):
self.lcd_device.write_cmd(data | LCD_BACKLIGHT)
self.lcd_strobe(data)
#write a command to lcd
def lcd_write(self, cmd, mode=0):
self.lcd_write_four_bits(mode | (cmd & 0xF0))
self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0))
#turn on/off the lcd backlight
def lcd_backlight(self, state):
if state in ("on","On","ON"):
self.lcd_device.write_cmd(LCD_BACKLIGHT)
elif state in ("off","Off","OFF"):
self.lcd_device.write_cmd(LCD_NOBACKLIGHT)
else:
print("Unknown State!")
#put string function
def lcd_display_string(self, string, line):
if line == 1:
self.lcd_write(0x80)
if line == 2:
self.lcd_write(0xC0)
if line == 3:
self.lcd_write(0x94)
if line == 4:
self.lcd_write(0xD4)
for char in string:
self.lcd_write(ord(char), Rs)
#clear lcd and set to home
def lcd_clear(self):
self.lcd_write(LCD_CLEARDISPLAY)
self.lcd_write(LCD_RETURNHOME)