' WC-FREI/BESETZT-Anzeige mit 8*8x8-Modulen MAX7218-Matrix
' ================================================================
' Zeigt nach dem Start einmalig kurz die eigene IP-Adresse
' Dann wird endlos mittig oder als Lauftext angezeigt ...
' - der deutsche Text "WC *FREI*" bzw "WC BESETZT"
' - der englische Text "WC VACANT" bzw "WC occupied"
' - das Tagesdatum DD/MM/YYYY
' - einige WENIGE lokale Wetter-Daten von OPENWEATHER.org
' - ein kleiner Werbetext
' - die laufende Uhrzeit HH:MM:SS
'
' Der WC-Text wird regelmäßig angezeigt, jedoch SOFORT, wenn sich der Tuerstatus ändert.
' Version 4.0 nun mit einem LDR-Lichtsensor als analoger Sensor
' optisch gekoppelt an eine vorhandenen externe frei/besetzt Anzeige-Leuchte
' Wird ein 1MOhm LDR an Pin 33 von einer externen FREI/BESETZT-LEUCHTE beleuchtet,
' wird sofort der entsprechende Türstatus zweisprachig angezeigt.
' Die frei/besetzt Erkennung erfolgt durch Auswertung einer Spannung am Analog/Digital-Wandler.
' Pin 33 wird über einem externen 470K-Widerstand an 3V3 angeschlossen.
' Der LDR liegt zwischen PIN33 und GND.
' Bei unbeleuchtetem LDR ist die Spannung an Pin 33 rund 2.5Volt.
' Bei beleuchtetem LDR sinkt die Spannung auf unterhalb von rund 1Volt.
' Der Erkennungs-Schwellwert wird mit der Variablen LDR_SCHWELLE (in mV) eingestellt.
' Der Schwellwert muss einmalig für die lokalen Umstände eingestellt werden.
' Anstelle des LDR kann auch ein Schalter angeschlossen werden, der bei BEESETZT geschlossen ist.
WLOG "START"
' Definition einiger Variablen, die schon beim Start bestimmte Werte haben sollten
VERSION$ = "4.0" 'TextVariable mit der aktuellen Programmversion
LDR_PIN = 33 'analoger Eingang für einen externen LDR-Sensor
LDR_SCHWELLE = 1000 'Schwellwert der LDR-Beleuchtung bei dessen Unterschreitung "WC besetzt" erkannt wird
TEXT_BESETZT$ = " WC BESETZT!" 'Vorbelegung für Besetzt-Text
TEXT_FREI$ = " WC FREI!" 'Vorbelegung für Frei-Text
TEXT_BESETZT_EN$ = " WC OCCUPIED! "'Vorbelegung für englischen Besetzt-Text
TEXT_FREI_EN$ = " WC VACANT! " 'Vorbelegung für englischen Frei-Text
WERBETEXT$ = " Willkommen im Caf" + CHR$(130) + " Geschmacksache :-) "
'ANZEIGE_ANZAHL = 10 'Anzahl der 8*8 Module
ANZEIGE_ANZAHL = 8 'Anzahl der 8*8 Module
ANZEIGE_PIN = 15 'CS-Pin der Anzeige
ANZEIGE_PIXEL = ANZEIGE_ANZAHL*8 'Anzahl der horizontalen Pixel der Anzeige
CHAR_PIXEL = 6 'Anzahl der Pixel für einen einzelnen Charakter
POSITION = 0 'Variable für die Textposition (von rechts beginnend!)
SEKUNDEN_ZAEHLER = 0 'Variable für Schleifenzähler
TUERSTATUS = 1 '1 = Schalter offen, O = Schalter geschlossen
TUERSTATUS_ALT = 3 'Zwischenspeicher für vorherigen Tuerstatus
OFFEN = 1 'Variable für Statusvergleich bei offenem Schalter
GESCHLOSSEN = 0 'Variable für Statusvergleich bei geschlossenem Schalter
TEXT_TIMER = 30 'ms Verzögerung für den timer zum schnellen Lauf des Textes
WLOG "INIT Display ..."
MaxScroll.Setup ANZEIGE_ANZAHL,ANZEIGE_PIN 'Die Anzeige initialisieren
GOSUB ZEIGE_DIE_IP_ADR
GOSUB OPENWEATHER_EINSTELLUNGEN 'APPID etc für Wetterdatenabfrage bei openweather.org
onWgetAsync ERZEUGE_WETTER_INFO 'Wenn OPENWEATHER antwortet, dieses Unterprogramm aufrufen
' Der Timer1 ruft jetzt endlos einmal pro Sekunde die Hauptroutine auf
TIMER1 1000, HAUPT_ROUTINE 'Der Timer1 ruft nun endlos alle 1000ms das Unterprgm auf
WAIT 'Ab jetzt werden nur noch Hintergrundprozesse abgewickelt;
' hier also der timer1 und der Schalterinterrupt
END
' #######################################################################################
' #######################################################################################
' Hinter dem WAIT und END stehen ab hier nur noch Unterprogramme,
' die mit ihrem Namen aus dem obigen Skript-Code aufgerufen werden,
' und die jeweils mit RETURN enden müssen.
' - - - - - - - - - - - - - - - - - U N T E R P R O G R A M M E - - - - - - - - - - - -
'==========================================================================
HAUPT_ROUTINE:
'==========================================================================
'Dieses Unterprgm wird einmal pro Sekunde vom TIMER1 aufgerufen.
'Je nach dem aktuellen Stand des Sekundenzählers innerhalb eines Intervals
'werden wechselnd einige Informationen ermittelt und angezeigt
'
TUERSTATUS = (ADC(LDR_PIN) > LDR_SCHWELLE) 'TUERSTATUS ist nun O wenn Spannungswert <=2000, sonst 1
'Bei einem Wechsel des Tuerstatus diesen neuen Status sofort anzeigen
If TUERSTATUS <> TUERSTATUS_ALT then
SEKUNDEN_ZAEHLER = 0
TUERSTATUS_ALT = TUERSTATUS
PRINT TIME$,"DER TUERSCHALTER WURDE BETRAETIGT"
ENDIF
SEKUNDEN_ZAEHLER = (SEKUNDEN_ZAEHLER mod 55) + 1 'Zaehler erhöhen und am Sequenzende auf 1 setzen
SELECT CASE SEKUNDEN_ZAEHLER
CASE 1 to 15 'Sekunde 1 bis 15
'NUR BEI JEDEM 5. SCHLEIFENDURCHGANG DAS WETTER HOLEN
IF SEKUNDEN_ZAEHLER = 1 then
WETTER_ZAEHLER= (WETTER_ZAEHLER + 1) mod 5
IF WETTER_ZAEHLER=1 then
wgetasync("api.openweathermap.org/data/2.5/weather?q=" + Openweather_TOWN$ + "&lang=" + Openweather_LANG$ + "&units=" + Openweather_UNIT$ + "&appid=" + Openweather_ID$, 80)
ENDIF
ENDIF
IF TEXT_WIRD_NICHT_BEWEGT then TIMER0 TEXT_TIMER ,BEWEGE_DEN_TEXT 'SCROLLENDEN TEXT ANSCHALTEN
IF TUERSTATUS = OFFEN then TEXT$ = TEXT_FREI$ + TEXT_FREI_EN$ 'FREI!!
IF TUERSTATUS = GESCHLOSSEN then TEXT$ = TEXT_BESETZT$ + TEXT_BESETZT_EN$ 'BESETZT!!
TEXT$ = TEXT$ + TEXT$ + TEXT$
MAXSCROLL.TEXT TEXT$
CASE 16 to 19 'Sekunde 16 bis 19 DATUM mittig anzeigen
TIMER0 0 'scrollen abschalten
TEXT$ = DATE$
TEXT$ = REPLACE$(TEXT$, "/", ".")
GOSUB ZEIGE_DEN_TEXT_MITTIG
CASE 20 to 32 ' WETTER_TEXT scrollend anzeigen
TEXT$ = WETTER_TEXT$
GOSUB ZEIGE_DEN_TEXT_ALS_LAUFSCHRIFT
CASE 33 to 42 ' Werbetext scrollend anzeigen
TEXT$ = WERBETEXT$
GOSUB ZEIGE_DEN_TEXT_ALS_LAUFSCHRIFT
CASE ELSE 'alle anderen Sekunden LAUFENDE UHRZEIT anzeigen
TEXT$ = TIME$ 'in TEXT$ steht nun die aktuelle Zeit
GOSUB ZEIGE_DEN_TEXT_MITTIG
END SELECT
RETURN
'==========================================================================
ZEIGE_DEN_TEXT:
'==========================================================================
TIMER0 0 'timer0 für das scrollen deaktivieren
TEXT_WIRD_NICHT_BEWEGT = 1 'Variable zeigt ob der Timer0 zum scrollen schon aktiv ist
MAXSCROLL.PRINT TEXT$ 'hier geht TEXT$ nur in den Puffer
MAXSCROLL.SHOW POSITION 'Erst jetzt wird der Puffer an der Position angezeigt
WLOG TEXT$ 'Zusätzlich nur zur Rückmeldung in der Entwicklungsoberfläche
RETURN 'Zurück zur aufrufenden Zeile
'==========================================================================
ZEIGE_DEN_TEXT_MITTIG:
'==========================================================================
TEXT_PIXEL = Len(TEXT$)*CHAR_PIXEL 'Anzahl der horizontalen Pixel für diesen Text
POSITION = (ANZEIGE_PIXEL/2)+(TEXT_PIXEL/2) 'Berechnen der mittigen Ausgabe-Position
GOSUB ZEIGE_DEN_TEXT
RETURN
'==========================================================================
ZEIGE_DEN_TEXT_ALS_LAUFSCHRIFT:
'==========================================================================
IF TEXT_WIRD_NICHT_BEWEGT then
'Timer0 anschalten, nur dann wenn nicht bereits an
TIMER0 TEXT_TIMER,BEWEGE_DEN_TEXT
ENDIF
TEXT_WIRD_NICHT_BEWEGT = 0
MAXSCROLL.TEXT TEXT$
RETURN
'==========================================================================
BEWEGE_DEN_TEXT:
'==========================================================================
'Den Text einen Punkt nach links scrollen
MAXSCROLL.scroll
TEXT_WIRD_NICHT_BEWEGT = 0
RETURN
'==========================================================================
OPENWEATHER_EINSTELLUNGEN:
'==========================================================================
' appid default fuer xxxxxxxxxxxxxxxxxxxx
Openweather_ID$ = "d5fb6a022cdac80367fa8ed862c8ee07"
Openweather_TOWN$ = "Krefeld,DE"
Openweather_TOWN$ = "Berlin,DE"
Openweather_LANG$ = "de"
Openweather_UNIT$ = "metric"
WETTER_TEXT$ = "NOCH KEINE WETTERDATEN ERHALTEN"
WETTER_ZAEHLER = 0
RETURN
'==========================================================================
ERZEUGE_WETTER_INFO:
'=========================================================================
'Aus der JSON-Rückmeldung von OPENWEATHER einige Infos selektieren
W$ = WGETRESULT$
WETTER_TEXT$ = " "
WETTER_TEXT$ = WETTER_TEXT$ + "Heute in "+ replace$(Openweather_TOWN$,",DE"," ")
WETTER_TEXT$ = WETTER_TEXT$ + json$(W$, "weather.temp") + chr$(248) + "C "
'WETTER_TEXT$ = WETTER_TEXT$ + json$(W$, "weather.pressure")+ "hPa "
'WETTER_TEXT$ = WETTER_TEXT$ + json$(W$, "weather.humidity") + "% "
WETTER_TEXT$ = WETTER_TEXT$ + json$(W$, "weather.description") + " "
WETTER_TEXT$ = WETTER_TEXT$ + "Sonnenuntergang: "+UNIXTIME$(json$(W$, "weather.sunset"))
WETTER_TEXT$ = WETTER_TEXT$ + " "
'einige Zeichen fuer das MAX7219-Display konvertieren
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "é", chr$(130))
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "è", chr$(138))
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "à", chr$(133))
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ö", "oe")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "Ö", "Oe")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ü", "ue")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "Ü", "Ue")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ä", "ae")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "Ä", "Ae")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "ß", "ss")
WETTER_TEXT$ = REPLACE$(WETTER_TEXT$, "not found", "???")
print TIME$, WETTER_TEXT$
RETURN
print TIME$,"DER TUERSCHALTER WURDE BETRAETIGT"
wlog TIME$,"DER TUERSCHALTER WURDE BETRAETIGT"
'==========================================================================
ZEIGE_DIE_IP_ADR:
'==========================================================================
' Beim Start kurz die IP-Adresse anzeigen
Text$ = Word$(IP$,1) 'Die eigene IP-Adreese ist das erste Wort in IP$
TEXT_PIXEL= Len(TEXT$)*CHAR_PIXEL 'Anzahl der horizontalen Pixel dieses Textes
POSITION = TEXT_PIXEL 'damit der rechte Teil der Adresse immer zu sehen ist
GOSUB ZEIGE_DEN_TEXT
PAUSE 1500
RETURN
'----- last line not empty to avoid problems -----