Ich habe den Code damals leider aus Versehen gelöscht.
Ich abe mir damals das Grundprogramm runtergeldaen und dieses hätte ich versucht anzupassen und eine Menüführung zu integrieren, und da bin ich halt gescheitert.
Mein Problem war wenn ich in der Schleife sage Wenn Taste "Menü" gedrückt wird dann gehe zu Subroutine Menü und zeige im display Menü.
dann springe ich wieder zurück in die Schleife. Aber die Schleife überschreibt ja dann das Display wieder wenn es wieder die Werte am Display ausgibt.
Es ist bestimmt nur ein Logikfehler von mir.
Hier ist das Grundprogramm auf diesem ich es aufbauen wollte.
Code:
define Takt 8 ' Takt in Sekunden bis zum nächsten Prozent
'***** GLOBALE VARIABLE *****
define command byte
define value byte
define LastHour byte
define LastMinute byte
define TempMin byte
define TempMax byte
define pHMin byte
define pHMax byte
define hMin_1 byte
define hMax_1 byte
define hMin_2 byte
define hMax_2 byte
define LeitMin byte
define LeitMax byte
define MinutePumpe byte
define LastSecond byte 'global
define Lichtproz byte 'global
define Lokal byte 'lokal
define TaktHilf byte 'global - Lichttakt
define TempAuswert byte 'global
define pHAuswert byte 'global
define LeitAuswert byte 'global
define EVG DA[1]
define TempMess AD[1]
define LeitMess AD[2]
define pHMess AD[3]
define Wasserstand_oben AD[7]
define Wasserstand_unten AD[8]
define Licht port[1]
define Licht2 port[2]
define Pumpe port[3]
define CO2 port[4]
define UV port[5]
define Heizung port[6]
define Putzen port[7]
define Kati port[8]
'***** ASCII-ZEICHENVARIABLE FÜR LCD-DISPLAY *****
define C_ &H43
define D_ &H44
define F_ &H46
define H_ &H48
define L_ &H4C
define M_ &H4D
define S_ &H53
define V_ &H56
define kA &H61 'a#
define PROZ &H25 '%#
define kI &H69 'i#
define kM &H6D 'm#
define kO &H6F 'o#
define kP &H70 'p#
define kR &H72 'r#
define kU &H75 'u#
define LEERZ &H20 '
define MINUS &H2D '-
define NULL &H30 '0
define GLEICH &H3D '=
define DOPPELPUNKT &H3A ':
define PUNKT &H2E '.
define GRAD &HDF '°
'LCD-Variable
define lcd_buf byte
define lcd_param byte
'LCD-Ports
define lcd_port byteport[2]
define lcd_e port[15] '"Enable" control line
'***** PROGRAMMPARAMETER INITIALISIEREN UND ZU MESS-SCHLEIFE SPRINGEN ****************************
'Alle Min. / Max. - Werte aus EEProm auslesen. Beim erstmaligen Aufruf sind alle Werte = 0
'Das Endbyte wird nicht mitgelesen
open# for read
input# TempMin
input# TempMax
input# pHMin
input# pHMax
input# LeitMin
input# LeitMax
input# hMin_1
input# hMax_1
input# hMin_2
input# hMax_2
close#
'Prüfen, ob gültige Konfigurationsdaten vorliegen. Wenn nicht, dann Platzhalter dafür
'anlegen, die alle einen Standartwert bekommen.
'if TempMin + TempMax <> 0 then goto default
TempMin = 45 'Standartwerte => 24,5 Grad
TempMax = 48 ' => 24,8 Grad
pHMin = 148 ' => 6,76
pHMax = 150 ' => 6,80
hMin_1 = 8
hMax_1 = 13
hMin_2 = 15
hMax_2 = 22
LeitMin = 15
LeitMax = 21
hour = 20 'Startuhrzeit
minute = 10
year = 2004 : month = 7 : day = 19
'Default Schaltstellungen:
#default
gosub SaveConfigData
#reset
licht = on : licht2 = off : heizung = off : co2 = off
pumpe = on : uv = off : putzen = off : lastminute=0
TempAuswert = 30 : pHAuswert = 170 : LeitAuswert = 150
Lichtproz = 95 : TaktHilf = Takt
'LCD initialisieren
gosub LCD_INIT
'Zur Mess-Schleife springen
goto MAINLOOP
'***** LCD-ROUTINEN *******************************************************
'Display zurücksetzen
#LCD_INIT
'Organisation: MSB.....LSB
'zuerst im 8-Bit-Modus:
lcd_param = &B00111000 : gosub LCD_WRITECMD 'Function Set: 8-Bit-Modus benutzen, mehrzeilig
lcd_port = &B00000010 'Function Set: zu 4-Bit-Modus umschalten, einzeilig
pulse lcd_e
'ab hier 4-Bit-Modus:
lcd_param = &B00101000 : gosub LCD_WRITECMD '4-Bit-Modus, mehrzeilig
lcd_param = &B00001000 : gosub LCD_WRITECMD 'Display off
lcd_param = &B00001100 : gosub LCD_WRITECMD 'Display on
lcd_param = &B00000110 : gosub LCD_WRITECMD 'Entry Mode: Cursor unsichtbar inkrementierend, kein Display Shift
gosub LCD_CLS
return
'Display löschen, Cursor Home
#LCD_CLS
lcd_param = &B00000010 : gosub LCD_WRITECMD 'Return Home
lcd_param = &B00000001 : gosub LCD_WRITECMD 'Clear Display
return
'Zeilenwechsel mit Set CGRAM Adress: (DB7 = 1)
#LCD_GOTOLINE
'im 4-Bit Modus mit DB4...DB7, Bit 7 ist immer 1 (N=1) bei Display mit mehr als 1 Zeile
if lcd_param = 1 then lcd_param = &B10000000 'Zeile 1 = &H00
if lcd_param = 2 then lcd_param = &B11000000 'Zeile 2 = &H40
if lcd_param = 3 then lcd_param = &B10010000 'Zeile 3 = &H10
if lcd_param = 4 then lcd_param = &B11010000 'Zeile 4 = &H50
goto LCD_WRITECMD
'Kommando senden
#LCD_WRITECMD
lcd_buf = &B00000000 'Buffer zurücksetzen
goto LCD_WRITE
'Zeichen senden an Adresse
#LCD_WRITECHAR
lcd_buf = &B00100000 'CG RAM-Adresse vor Schreiben mit &B000000 vorbelegen (DB0...DB6)
goto LCD_WRITE
'Kommando oder Zeichen im 4-Bit-Modus an LCD senden
#LCD_WRITE
lcd_port = lcd_buf or (lcd_param shr 4) ' Hi-Nibble
pulse lcd_e
lcd_port = lcd_buf or (lcd_param and &B00001111) ' Lo-Nibble
pulse lcd_e
return
'***** MESS-SCHLEIFE MIT AUSGABE AN PORTS UND DISPLAY *****
'***** MESSWERTE ERFASSEN *****
#MAINLOOP
'Sekundentakt synchronisieren
wait second <> LastSecond
LastSecond = second
'während Putzen kann man kalibrieren dafür Takt 1 Sekunde
'if (Putzschalter = off) then takthilf=1
if (Putzen = on) then takthilf=1
'langer "Sonnenuntergang"
if (takthilf <> 0) then goto endtakt
if (hour <= 18) then takthilf=takt else takthilf=takt*2
#endtakt
taktHilf = taktHilf - 1
'Zeile 1
lcd_param = 1 : gosub LCD_GOTOLINE
'Temperatur ------------------------------------------
if (takthilf <> 0) then goto endAuswertung
TempAuswert = TempMess
'(TempMess/2)+(TempAuswert/2) 'evt.Umrechnung und Korrektur
'Umrechnung für LCD-Anzeige
'Auf LCD anzeigen
lcd_param = NULL + 2
if (TempAuswert >= 100) then lcd_param = NULL + 3 : gosub LCD_WRITECHAR
lcd_param = NULL + (TempAuswert mod 100) / 10: gosub LCD_WRITECHAR
lcd_param = PUNKT : gosub LCD_WRITECHAR
lcd_param = NULL + TempAuswert mod 10 : gosub LCD_WRITECHAR
lcd_param = GRAD : gosub LCD_WRITECHAR
lcd_param = C_ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
'pH auf LCD anzeigen / Genauigkeit 0,02--------------------
'pHAuswert = phMess
phAuswert = (phMess/2)+(pHAuswert/2) 'evt.Umrechnung und Korrektur
lokal = pHAuswert
if (lokal < 10) then lokal = lokal + 50
lokal = lokal - 10
lokal = lokal mod 100
if (lokal > 49) then lokal = lokal - 50
lokal = lokal * 2
if(pHAuswert<10) then lcd_param = NULL + 3
if(pHAuswert>= 10) and (pHAuswert< 60) then lcd_param = NULL + 4
if(pHAuswert>= 60) and (pHAuswert<110) then lcd_param = NULL + 5
if(pHAuswert>=110) and (pHAuswert<160) then lcd_param = NULL + 6
if(pHAuswert>=160) and (pHAuswert<210) then lcd_param = NULL + 7
if(pHAuswert>=210) and (pHAuswert<=255) then lcd_param = NULL + 8
gosub LCD_WRITECHAR
lcd_param = PUNKT : gosub LCD_WRITECHAR
lcd_param = NULL + (Lokal mod 100) / 10 : gosub LCD_WRITECHAR
lcd_param = NULL + Lokal mod 10 : gosub LCD_WRITECHAR
lcd_param = kP : gosub LCD_WRITECHAR
lcd_param = H_ : gosub LCD_WRITECHAR
#endAuswertung
'Zeile 2
lcd_param = 2 : gosub LCD_GOTOLINE
'Licht in %
'Auf LCD anzeigen
lcd_param = L_ : gosub LCD_WRITECHAR
lcd_param = DOPPELPUNKT : gosub LCD_WRITECHAR
lcd_param = NULL + (Lichtproz mod 1000) / 100 : gosub LCD_WRITECHAR
lcd_param = NULL + (Lichtproz mod 100) / 10 : gosub LCD_WRITECHAR
lcd_param = NULL + Lichtproz mod 10 : gosub LCD_WRITECHAR
lcd_param = PROZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
'Leitwert-Regler
if LeitMess < 5 then LeitAuswert = 0 else LeitAuswert = LeitMess
LeitAuswert = (LeitMess/2) + (LeitAuswert/2)
'Umrechnung für LCD-Anzeige
'Auf LCD anzeigen
lcd_param = NULL + (LeitAuswert mod 1000) / 100 : gosub LCD_WRITECHAR
lcd_param = NULL + (LeitAuswert mod 100) / 10 : gosub LCD_WRITECHAR
lcd_param = NULL + LeitAuswert mod 10 : gosub LCD_WRITECHAR
lcd_param = kU : gosub LCD_WRITECHAR
lcd_param = S_ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
'Zeile 4
lcd_param = 4 : gosub LCD_GOTOLINE
'Uhrzeit
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = LEERZ : gosub LCD_WRITECHAR
lcd_param = NULL + hour / 10 : gosub LCD_WRITECHAR
lcd_param = NULL + hour mod 10 : gosub LCD_WRITECHAR
lcd_param = DOPPELPUNKT : gosub LCD_WRITECHAR
lcd_param = NULL + minute / 10 : gosub LCD_WRITECHAR
lcd_param = NULL + minute mod 10 : gosub LCD_WRITECHAR
lcd_param = DOPPELPUNKT : gosub LCD_WRITECHAR
lcd_param = NULL + second / 10 : gosub LCD_WRITECHAR
lcd_param = NULL + second mod 10 : gosub LCD_WRITECHAR
'Zeitsteuerung der Beleuchtung
Lokal=0
if ( hour >= hMin_1 ) and ( hour < hMax_1 ) then Lokal = 1
if ( hour >= hMin_2 ) and ( hour < hMax_2 ) then Lokal = 1
'UV Licht schalten
UV = off
'if (hour <> LastHour) and (hour = 14) then UV = on
'if (hour <> LastHour) and (hour = 18) then UV = off
'Steuerung des Datenloggers für Licht an
if (hour <> LastHour) and (licht = on) then gosub WriteToLogger
if (hour <> LastHour) and (licht = on) then LastHour = Hour
'Relais schalten:
'if (Putzschalter = off) then goto StatusPutzen 'Putzen über Schalter
if (Putzen = on) then goto StatusPutzen 'Putzen über PC
if (lichtproz <= 10) then evg =255
if (lichtproz = 100) then evg =0
if (lichtproz > 10) and (lichtproz < 100) then evg =25+ lichtproz /2 *5
if (Lokal = 1) and (Lichtproz <>100) then gosub Lichtan
if (Lokal = 0) and (LichtProz <> 0) then gosub Lichtaus
if (lichtproz = 0) then licht=off else licht=on
if (lichtproz = 100) then licht2=on else licht2=off
if (hour <> LastHour) then gosub WriteToLogger
LastHour = Hour
'Pumpe schalten und x - Minuten aus lassen -------------------
if ( MinutePumpe = 254 ) then MinutePumpe = 100 ' Zähler begrenzen
if ( minute <> Lastminute ) then MinutePumpe = MinutePumpe + 1
if ( Wasserstand_unten < 250 ) then goto EndePumpe ' Wasserstand zu tief
if ( MinutePumpe = 1) then pumpe = off 'erst beim zweiten Durchlauf schalten, falls 1. Störimpuls
wait 10
if ( MinutePumpe = 1) then CO2 = off
MinutePumpe = 0 ' Zähler Rücksetzen
#EndePumpe
if ( Wasserstand_oben < 250 ) then pumpe = on ' Wasserstand zu hoch
if ( MinutePumpe = 5 ) then Pumpe = on
'nur ein Mal in der Minute Relais schalten ----------------
if (minute = LastMinute) then goto endRelaisschalten
lastminute = minute
if (TempAuswert <= TempMin) then Heizung = on
if (TempAuswert >= TempMax) then Heizung = off
if (LichtProz>=1) and (Lichtproz<=99) then goto phSprung
if (pHAuswert >= pHMax) and ( Pumpe = on) then CO2 = on
if (pHAuswert <= pHMin) or ( Pumpe = off) then CO2 = off
#phSprung
goto endRelaisschalten 'überspringe Putzschaltung
#StatusPutzen
'Putz - Relais schalten
licht = on : licht2 = off : evg = 0 : UV = off
Heizung = off : CO2 = off : Pumpe = off
#endRelaisschalten
'RxD auf auf Übertragungssignal testen
if RXD then gosub TEST_RxD
goto MAINLOOP
'***** Reaktion auf RxD-Signal *****
#TEST_RxD
get command
if command = 65 then goto test_RxD 'Dummy
if command = 84 then put 87 'wird vom PC geprüft
if command = 1 then gosub ReadLogger
if Command = 3 then gosub ReadCurrentValues 'aktuelle Meßwerte und Zeit
if Command = 4 then gosub ReadConfigData
if Command = 5 then gosub GetAndSaveConfigData
if Command = 7 then gosub AnzeigeRelaisStatus
if command = 6 then goto reset
if command = 8 then goto Aus
if command = 9 then goto TestRelais
if command = 11 then Putzen = on
if command = 12 then Putzen = off
return
' Unterprogramme ------------------------------------------
#ReadConfigData 'Konfigurationn aus EEPROM lesen und an PC senden (4)
open# for read
#NextRead
input# Value
if Value = 254 then goto Ready 'Endbyte für Konfigurationsdaten
put Value 'an serielle Schnittstelle übertragen, Endbyte "Z" wird nicht gesendet
goto NextRead
#Ready
close#
return
#ReadCurrentValues 'Aktuelle Messwerte an PC senden (2). 254 und 255 sind Datensatz-Endbytes
put TempAuswert
put pHAuswert
put LeitAuswert
put Lichtproz
put year
put month
put day
put hour
put minute
return
#WriteToLogger
open# for append 'Loggerdaten an Konfigurationsdaten (Endbyte=254) bzw. an zuletzt geloggte Daten (Endbyte=255) anhängen
'if not filefree then goto OverFlow
if TempAuswert > 253 then TempAuswert = 253 'Werte müssen < 254 sein, weil 254 und 255 Endbytes sind
print# TempAuswert
if pHAuswert > 253 then pHAuswert = 253
print# pHAuswert
if LeitAuswert > 253 then LeitAuswert = 253
print# LeitAuswert
print# year
print# month
print# day
print# hour
if (Licht = on) then print# 1 else print# 0
if (Licht2 = on) then print# 1 else print# 0
if (CO2 = on) then print# 1 else print# 0
if (Heizung = on) then print# 1 else print# 0
print# 255 'Endbyte für jeden Logger-Datenstz = 255
'#OverFlow
close#
return
#ReadLogger
gosub ReadCurrentValues
gosub AnzeigeRelaisStatus
open# for read
#Loop 'jetzt alle Konfigurationsdaten (Endbyte=254) und Loggerdaten (Datensatz-Endbyte=255) lesen
pause(1)
input# Value
pause(1)
put Value 'an serielle Schnittstelle einschließlich der Datensatz-Endbytes (254 bzw. 255) ausgeben
if not eof then goto Loop
close#
put 255
gosub SaveConfigData
return
#GetAndSaveConfigData 'Daten von PC empfangen und ins EEPROM schreiben (8)
get TempMin
get TempMax
get pHMin
get pHMax
get LeitMin
get LeitMax
get hMin_1
get hMax_1
get hMin_2
get hMax_2
get year
get month
get day
get hour
get minute
get Lichtproz
gosub SaveConfigData 'Daten ins EEPROM schreiben
put 255
put 255
return
#SaveConfigData
open# for write 'Konfigurationswerte ins EEPROM schreiben. Sie dürfen nicht > 253 sein, weil 254 und 255 Endbytes sind.
if TempMin > 253 Then TempMin = 253
print# TempMin
if TempMax > 253 Then TempMax = 253
print# TempMax
if pHMin > 253 Then pHMin = 253
print# pHMin
if pHMax > 253 Then pHMax = 253
print# pHMax
if LeitMin > 253 Then LeitMin = 253
print# LeitMin
if LeitMax > 253 Then LeitMax = 253
print# LeitMax
print# hMin_1
print# hMax_1
print# hMin_2
print# hMax_2
print# 254 'Endbyte für Konfigurationsdaten = 254
close#
return
#AnzeigeRelaisStatus
if (Heizung =on) then put 191 else put 192
if (UV =on) then put 193 else put 194
if (Licht =on) then put 195 else put 196
if (Licht2 =on) then put 197 else put 198
if (CO2 =on) then put 199 else put 200
if (Pumpe =on) then put 201 else put 202
if (Putzen =on) then put 203 else put 204
put LichtProz
return
#Lichtan
if (lichtproz = 0) then lichtproz = 1 'damit Logger Anschalten richtig anzeigt
if (taktHilf <> 0) then goto ExitLicht1
lichtproz = lichtproz + 1
if lichtproz <> 99 then goto ExitLicht1
gosub LCD_INIT
#ExitLicht1
return
#Lichtaus
if (taktHilf <> 0) then goto ExitLicht2
lichtproz = lichtproz - 1
if lichtproz <> 1 then goto ExitLicht2
if hour < 18 then minute = minute - 7 'Zeitkorrektur der C-Control (Minuten am Tag)
gosub LCD_INIT
#ExitLicht2
return
#TestRelais '(5)
#TestWeiter
get Value
if (value = 15) then Heizung = on
if (value = 25) then Heizung = off
if (value = 35) then UV = on
if (value = 45) then UV = off
if (value = 55) then Licht = on
if (value = 65) then Licht = off
if (value = 75) then Licht2 = on
if (value = 85) then Licht2 = off
if (value = 95) then Pumpe = on
if (value = 105) then Pumpe = off
if (value = 115) then CO2 = on
if (value = 125) then CO2 = off
if (value = 155) then Kati = on
if (value = 165) then Kati = off
if (value = 20) then goto TestEnde
goto TestWeiter
#TestEnde
gosub LCD_INIT
return
#Alarm
beep 475,5,1
beep 425,5,1
beep 0,0,0
return
'***** PROGRAMM BEENDEN *****
#Aus
END 'Programmende
(Das Programm gehört Markus Bigiel)
Lesezeichen