'-------------------------------------------------------------- ' Steuerung von 7 Rolläden mittels OM-Mini - 5.06.2009 ' 5-Volt-Version ' Fahren der Rolladenmotoren geschieht entweder mittels ' Tastatur (hoch/runter) Einzel-o. Gesamtsteuerung ' Uhrzeit (hoch/runter) ' Fotozelle (runter bei Dunkelheit) ' RolladenMotorSteuerung ' Die Motoren erhalten ihre Stromversorgung über mechanische ' Relais. Vorherige Steuerung mittels elektronischer Lastrelais ' (Sharp bzw. Crydom) war störanfällig und konnte auch nicht durch ' RC-Glieder gemindert werden... ' Relais werden mittels ULN2803 getrieben, die ULN-Steuerung erfolgt ' über Portexpander PCF8574 ' Aktuelle Rolladenstellung ' Rolladenstellung wird über die gefahrene Zeit für ' jeden einzelnen Rolladen gemerkt. Bei Weiterfahren kann ' dadurch Zeit eingespart werden. Diese Funktion wird nach ' vollkommen neuem Neustart erst nach der ersten Rolladenfahrt ' aktiviert ' Um Stromunterbrechungen zu überbrücken, werden alle ' FestEinstellungen im externen EEprom gespeichert, die ' OM-Uhrzeit wird bei jeder automatischen Rollofahrt auf die Uhren- ' bausteinzeit gesetzt. Uhrenbaustein ist Goldcap gepuffert - ' reicht für ca 96 Stunden. Im Uhrenbaustein werden auch ' Rolladenstellungen und Zahl der durch Watchdog ausgelösten ' Neustarts temporär gespeichert. Nach Neustart werden alle Daten ' aus Speicher o. externer Uhr (wenn noch vorhanden) in die OM geholt. ' Einstellungen (Hoch/Runterfahrzeiten, FotozellenAuslösWert, ' Uhrzeit) sind mittels Tastatur jeder Zeit einstellbar ' Watchdog ist mittels SCL-Leitung realisiert: Bei intakter ' Arbeit wird SCL ständig zwischen 5V und GND geschaltet, dies wird ' durch die "Watchdog" überwacht. Spannung der SCL-Leitung ' wird über Diode und RC-Glied in eine zusätzliche OM-Micro an deren ' AD-Wandler eingelesen. Ein Absinken oder Ansteigen über ' den ermittelten Mittelwert führt zum Neustart über einen gesteuerten ' PNP-Transistor. ' Als Watchdog wird eine OM-Micro in der 3Volt-Version verwendet, da die ' robuster auf evtl. Spannungsschwankungen reagiert... ' *********************************************************** ' Open-Mini : 2430 ProgrammBytes; 64 VariablenBytes ' genutzt: 2286 ; 51 (nicht optimiert) ' Betriebssystem von Dietmar Harlos; 5V Version ' *********************************************************** 'Intern genutzte I2C-Bausteine: ' 4 PCF8574A, EEPROM(AT24C256), Uhr(PCF8583) 'PCF8574A Adr.: 114 = Byteport 6 - LCD-Steuerung 'PCF8574A Adr.: 112 = Byteport 5 - ULN(1) 'PCF8574A Adr.: 120 = Byteport 9 - ULN(2) 'PCF8574A Adr.: 124 = Byteport 11 - Tastatur 'AT24C256 Adr.: 160 - EEPROM = 256 Bytes =(32 Pages x 8 Bytes) 'PCF8583P Adr.: 162 Uhrenbaustein, über Dioden an Goldcap ' Extern: weiterer PCF8574 Adr.:122 als externe Tastatur ' vorgesehen: Temperaturanzeige ' automatische Sommer/Winterzeit - Umstellung ' Realisierung mit OM-Midi..... '******************************************************************* ' SICHERHEIT: ' Da beim OM-Einschalten alle Ports 5V haben und so auch alle PCFs ' und dadurch auch alle ULN-Motortreiber - die dadurch durchstarten ' würden, wird deren 5V-Freigabe über PNP-Transistor und Port 12 ' gesteuert (PNP = ON = 5V => ALLE PCFs bekommen kein Strom.... '******************************************************************* ' Tastaturwerte und Bedeutung ' 239 223 LCD_Modus: AN/AUS | LCD_Anzeige weiter ' 95 Alle Rollo hoch;- im LCD-Modus: Zahl hoch ' 127 Alle Rollo runter;- LCD-Modus: Zahl runter ' 247 251 253 254 Rollos:Tür, Fenster links, mitte, rechts hoch ' 207 79 243 249 Rollos:Tür, Fenster links, mitte, rechts runter ' 11101111 11011111 ' zugehörige Binärwerte ' 01011111 ' 01111111 ' 11110111 11111011 11111101 11111110 ' 11001111 01001111 11110011 11111001 ' 191 = &B10111111 'Ein/Aus-Schalter auf GND; optische Leuchtdioden-Kontrolle ' Byteports f. ULN1 ULN2 ' PlatinePins 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 ' belegt - - + + + + + + + + + + + + + + ' SteuerWrt - - 32 64 128 8 4 2 16 32 64 128 1 2 4 8 ' TastaturWrt - - 32 16 8 4 2 1 249 254 243 253 79 251 207 247 ' externer PCF8574 interner Tastatur-PCF8574 ' extra Tastaturen INCLUDE "D:\Elektron\OpMicr\ExtPorts\om.def" ' Definitionen fuer die Open-Mini ' INCLUDE "D:\Elektron\OpMicr\ExtPorts\omid.def" ' und Open_Midi ' INCLUDE "D:\Elektron\OpMicr\OM042010\OMAC.def" ' Defin. fuer Open_Macro DEFINE TON PORT[15] ' akustische Ausgabe DEFINE VoltAus PORT[16] ' am Port16 hängt die Spannungsversorgung der PCFs für die ULNs DEFINE FotoZell AD[ 2] ' FotoDiode über 10kOhmPoti an GND/5V, wann Rollos runter DEFINE PCFADR &B01110000 ' PCF8574A-Basisadresse für ExtPort-Programm (dez.:112) ' LCD_PCF8574 hat Adresse 114 und hängt an BytePort 6 ' A2:A1:A0 = 0:0:1 66/114 ' ULN1_PCF8574 hat Adresse 112 und hängt an BytePort 5 ' A2:A1:A0 = 0:0:0 64/112 ' ULN2_PCF8574 hat Adresse 120 und hängt an BytePort 9 ' A2:A1:A0 = 1:0:0 72/120 ' Tast_PCF8574 hat Adresse 124 und hängt an BytePort 11 ' A2:A1:A0 = 1:1:0 76/124 ' Tast2_PCF8574 hat Adresse 122 und hängt an BytePort 10 ' A2:A1:A0 = 1:0:1 74/122 DEFINE ULN1 BYTEPORT[ 5] ' Steuerung des ersten ULN (Rollos 4H/3R) oben/unten DEFINE ULN2 BYTEPORT[ 9] ' Steuerung des zwoten ULN (Rollos 3H/4R) oben/unten DEFINE TTuer Port[10] ' Detektor für offene/geschlossene Terassentür DEFINE Tast BYTEPORT[11] ' Tastaturabfrage an Haupttastatur Wohnzimmer DEFINE Tast2 BYTEPORT[10] ' Tastaturabfrage in AZ,Kü,Bad DEFINE PCFUhr &B10100010 ' Adresse des Uhrenbausteins (dezimal:162) DEFINE PCFMemory &B10100000 ' Adresse des AT2456 (dezimal:160) DEFINE LCD_Port BYTEPORT[6] ' das LCD ist am Extended Byteport angeschlossen DEFINE lcd_e PORT[47] ' Enableleitung - LCD - Steuerung (pcf2_p6) DEFINE LCD_OFF PORT[48] ' PORT_BIT auf GND versorgt LCD (pcf2_p7) DEFINE Test_SCL PORT[ 5] ' Definition nur benoetigt um Watchdog zu testen ' BIT- und Bytevariablen DEFINE M_HOUR BYTE[ 1] ' * Setzen d. Uhrzeit-Stunde | DEFINE M_MINUTE BYTE[ 2] ' * Setzen d. Uhrzeit-Minute | DEFINE M_Dark BYTE[ 3] ' * DunkelWert gespeichert \ DEFINE HOCH_H BYTE[ 4] ' * Stunde der Hochfahrzeit \* über Anzeige DEFINE HOCH_M BYTE[ 5] ' * Minute der Hochfahrzeit / manipulierbar DEFINE RUNT_H BYTE[ 6] ' * Stunde der Runterfahrzeit / DEFINE RUNT_M BYTE[ 7] ' * Minute der Runterfahrzeit | DEFINE ERROR BYTE[ 8] ' Prüf-Dummy zum Lesen/Speichern DEFINE DAUER BYTE[ 9] ' Fahrdauer DEFINE DARK BYTE[10] ' Dunkelwert aktuell gemessen DEFINE Manip BYTE[11] ' Tastatur-Manipulation (LCD oder Steuerung) DEFINE a BYTE[12] ' ein paar Variablen DEFINE b BYTE[13] ' ein paar Variablen DEFINE temp BYTE[14] ' fuer LCD-Routinen DEFINE MTast BYTE[15] ' Merken der gedrückten Taste = Entprellschutz DEFINE Wert BYTE[16] DEFINE x BYTE[17] DEFINE y BYTE[18] DEFINE ADRPCF BYTE[19] ' Übergabeadresse des PCFs DEFINE Value BYTE[20] ' temporäre Rechengröße DEFINE Schon_Unt BYTE[21] ' Wenn alle Rollos unten sind DEFINE StartZahl BYTE[22] ' Zählt jeden Neustart Speicherung in UHRenMemory DEFINE Zeit_TT Byte[23] ' Zeit die TerasTr Rollo gefahren ist Sp. in UhrM DEFINE Zeit_FL Byte[24] ' Zeit die FenstLi Rollo gefahren ist Sp. in UhrM DEFINE Zeit_FM Byte[25] ' Zeit die FenstMi Rollo gefahren ist Sp. in UhrM DEFINE Zeit_FR Byte[26] ' Zeit die FenstRe Rollo gefahren ist Sp. in UhrM DEFINE Zeit_AZ Byte[27] ' Zeit die ArbZimm Rollo gefahren ist Sp. in UhrM DEFINE Zeit_Ku Byte[28] ' Zeit die Küchen Rollo gefahren ist Sp. in UhrM DEFINE Zeit_Bd Byte[29] ' Zeit die Bad Rollo gefahren ist Sp. in UhrM DEFINE Schon_Obn BYTE[30] ' Wenn Rollos schon oben, dann nicht nochmal DEFINE DSPL_ON BYTE[31] ' Displayzustand:ON/OFF DEFINE FAKT BYTE[32] ' Faktor, ändert die Tasteneinstellung (LCD o. Rollo) DEFINE RolloWzt BYTE[33] ' Verfolgt über Dauer Rollofahrtzeit DEFINE CURSOR BYTE[34] ' CursorOrt DEFINE BytRAM BYTE[35] ' Adresse des ByteRAMs - nicht benötigt DEFINE ^pb BYTE[36] ' Zeiger (pb=0 = BYTE[1])@pb=Wert an Adr. pb DEFINE DisplWTZ BYTE[37] ' Wartezeit, wie lange das Display an ist DEFINE AlleRollo BYTE[38] ' Wenn 1, dann betrifft es alle Rollos DEFINE DisplSek BYTE[39] ' Zähler für Display-Abschaltung nach NichtsTun DEFINE LCD BYTE[40] ' Variable für interne LCD-Operationen DEFINE i BYTE[41] ' LCD_Anzeige Laufvariable DEFINE CMD BYTE[42] ' Rechnungskonstante für LCD DEFINE Register BYTE[42] ' Registerwert zum Uhrenbaustein lesen/schreiben DEFINE EEPROM BYTE[43] ' EEPROM-Adresse DEFINE ACK BYTE[44] ' Nur in Kontrollprogramm "TestI2C" genutzt DEFINE Adresse Byte[45] ' Nur in Kontrollprogramm "TestI2C" genutzt DEFINE Uhrabgleich Byte[44] ' Uhrabgleich PCF8583=>OM IF 4 Uhr & Byte[44]=0 DEFINE Dark0 BYTE[46] ' Für Berechnung des Dark-Mittelwertes DEFINE DarkNummer BYTE[47] ' Für Berechnung des Dark-Mittelwertes DEFINE DarkCarry BYTE[48] ' Für Berechnung des Dark-Mittelwertes DEFINE Dummy Byte[49] ' SCL-Dummy-Ruf, damit die Watchdog nicht arbeiten muss DEFINE BeepDauer Byte[50] ' Dauer des BeepTones = BEEPBefehl braucht 18 Speicher- DEFINE BeepFrequ Byte[51] ' Beepfrequenz = plätze, deshalb über GOSUB ' ' --------------------------------------------------------------------------- ' Die Erweiterung fuer Extended Ports einbinden ' --------------------------------------------------------------------------- INCLUDE "d:\elektron\OPMicr\EXTPOrts\extports.iia" ' --------------------------------------------------------------------------- ' Das Hauptprogramm ' --------------------------------------------------------------------------- #main URTOK=ON ' Erweiterung fuer Extended Ports aktivieren 'End2Host=ON ' Nach Programmende in den HOST-Modus '****************************************************************************** ' Neustart '------------------------------------------------------------------------------ #Neustart ULN1=0:ULN2=0:Pause 10 ' Muss am Anfang stehen, sonst klappern die Relais.... VoltAus = OFF ' PNP-Transistor aus, dadurch haben PCFs nun 5 Volt an den Ausgängen GOSUB ROLLO_AUS ' vorsichtshalber nochmals alle Rollomotoren ausstellen PRINT HOUR;":";MINUTE ' Zeiten auf RS232-Ausgabe GOSUB Setze_OMUhr ' Setzt OM auf Uhrzeit vom Uhrenbaustein ' GOSUB LIES ' Liest die Festwerte aus dem EEPROM ' PRINT HOUR;":";MINUTE ' Zeiten auf RS232-Ausgabe Dauer= 27 ' s RolladenFahrzeit (durch Probieren gefunden) FOR I=40 to 60 Step 10 ' BEEPfrequ=i:Beepdauer=i/4' Akustik, wenn OM GOSUB BEEPER ' neu hoch fährt NEXT IF StartZahl>0 THEN GOTO Start 'alte Werte existieren noch im Uhrenbaustein '----------------------------------------------------------------------------- ' wenn keine Werte aus dem UhrenMemory verfügbar sind '----------------------------------------------------------------------------- #Neubewertung ' Taste rechts unten + Schalter auf "Aus" For pb=24 to 30 ' Sind keine alten Werte vorhanden, muss @pb=128 ' bei allen Werten [@pb=24=Byte[23]] eine 128 rein next ' 128 heisst: Volle Fahrzeit, egal wo sie stehen PRINT HOUR;":";MINUTE ' Zeiten auf RS232-Ausgabe ' PRINT ERROR ' FehlerTyp auf RS232-Ausgabe DarkNummer=0 ' Berechnungszähler zur Berechnung des Dark-Mean '-------------------------------------------------------------------------- ' Start, wenn die Watchdog ausgelöst hat oder manuell neu gestartet wurde ' RolloMotoren ausgelöst durch Zeit- oder Lichtsensor ' Die Fotozelle wird mittels gleitender Mittelwertbildung einigermaßen träge '--------------------------------------------------------------------------- #Start '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' Testprogramme, welche einzeln zugeschaltet werden können.... ' Gosub TestWatchdog ' Testprogramm Watchdog ' GOSUB Test_I2C_Bausteine ' Testprogramm I2C-Bausteine ' GOTO Test_ULNs ' Testprogramm ULN_Ausgabe ' GOTO TastaturEinzelRollotest ' Testen der Tastatur für Einzelrolladenbewegung ' GOSUB Test_PCF8583 ' Testprogramm PCF8583 Ein/Ausgabe '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ' Fotozelle träge machen durch Bildung eines gleitenden Mittelwertes ' Wert wird aus der Summe (n=255) der Carry-Summation gebildet Dark0=Dark0+Fotozell ' IF CARRY THEN ADD DarkCarry, 1 ' Carry summieren ADD DarkNummer,1 ' Zähler für DarkCarry IF DarkNummer=255 THEN ' DARK=(DARK SHR 1) + (DarkCarry SHR 1)'Summe d. Werte/2; dadurch Mean DarkNummer=0:DarkCarry=0:Dark0=Dark ' ca 255*2 = 510 mal gemittelt ENDIF IF HOUR=24 THEN HOUR =0 ' OM erkennt den 24 h-Überlauf nicht, IF Tast<255 THEN ? "T:";Tast ' RS232-Kontrolle, Tast<255 anzeigen IF TAST =191 THEN GOTO Start ' RolloAutomatik mit Schalter AUSgestellt IF Fakt>0 THEN GOTO NachAutomatisch ' Wenn Fakt>0 mache nichts automatisch IF DARK1 THEN GOTO ALL_RUNT ' und Rollos noch oben sind, alle runter #DarkWei END IF IF HOCH_H=HOUR THEN ' Wenn Hochfahrzeit erreicht, IF HOCH_M=MINUTE THEN GOTO All_HOCH ' dann alle Rollos hochfahren ' END IF Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht IF RUNT_H=HOUR THEN ' Wenn Runterfahrzeit erreicht, IF RUNT_M=MINUTE THEN IF SCHON_UNT<>1 THEN GOTO All_RUNT ' dann alle Rollos runterfahren ' END IF ' aber nicht, wenn Rollos schon unten ' END IF Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht '***************************************************************************** ' Display - und Beleuchtung nach 40 Sekunden "Nichts-Tun" abschalten '----------------------------------------------------------------------------- #NachAutomatisch ' IF DisplWTZ=1 THEN ' Wenn Display_AN_Zähler =1, dann GOTO LCD_AUS ' LCD Ausschalten ' END IF Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht IF DisplSek<>SECOND THEN ' Wenn Display eine Sekunde an war, dann SUB DisplWTZ,1 ' Display_AN_Zähler um 1 mindern DisplSek=SECOND ' DisplSek auf aktuellen Wert setzen END IF '********************************************************************************** MTast=Tast AND Tast2 - Fakt ' Für Entprellung Taste merken & Tastenfelder vereinigen ' ?Tast;" Tast2:";Tast2;" MT:";MTast ' Mit Faktor Tastendoppelbelegung ermöglichen ' ? FOTOZell IF MTast=255 OR MTast=246 THEN GOTO Start ' Wenn keine Taste gedrückt, zum Start ' IF MTast=190 THEN GOTO Neubewertung ' Wenn nichts mehr geht: Schalter "Aus" + rechte obere Taste Print MTast ' Kontrollausgabe auf RS232 Beepdauer=14:Beepfrequ=MTast/2 ' akustische Qittung (/2=Tonkorrekt) GOSUB BEEPER #ULN_TestProgramm_Einsprung ' zur Prüfung der Tastatur; manuelle MTast-Zuordnung DBNZCTR=14 ' 14 Rollostellungen => 7 Rolläden mit je zwei Motoren #Loop_Tast2 ' fragt periphere Tastaturen (ext. PCF8574) über I2C Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht IF Mtast = LOOKTAB (Tast_Wert,DBNZCTR-1) THEN ' Zählung ab 0, Wenn Taste gefunden I=DBNZCTR-1 ' Übergabe des TabellenMarkers für die 2 kommenden GOSUBS AlleRollo=0 ' nur einen Rollomotor bewegen GOSUB HOL_PCF8574_ULN_WERT ' hole den Wert für den zugehörigen PCF8574/ULN Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht GOSUB Motor_aus_Tabelle_An ' schalte den richtigen ULN-Port durch ?"A:";a;" DB";DBNZCTR;" pB"; ' RS232-Kontrollausgabe IF DBNZCTR<8 THEN pb=23+DBNZCTR ' Setze RolladenstellungsZeiger[23-29](pB=24=>Byte[23] ?pB; ' RS232-Kontrollausgabe GOTO Hoch_Warte ' und gehe zum richtigen SubProgramm ' ELSE pb=16+DBNZCTR ' Setze RolladenstellungsZeiger[23-29](pB=24=>Byte[23] ?pB; ' RS232-Kontrollausgabe GOTO Runt_Warte ' und gehe zum richtigen SubProgramm ' ENDIF ENDIF DBNZ Loop_Tast2 IF Mtast= 95 THEN GOTO All_HOCH ' alle Rollos hochfahren ' IF Mtast= 127 THEN GOTO ALL_RUNT ' alle Rollos runterfahren ' '************************************************************************ ' über Display Datenänderung (Hoch/Runter-Uhrzeit, akt. Uhrzeit, Dunkelwrt) ' wird linke ober Taste gedrückt, werden mit Fakt die Tastenwerte geändert) '************************************************************************* IF MTast=239 THEN ' Wenn linke/oben Taste mit Fakt=0 gedrückt, FAKT=9 ' Tasten nur zur DatenÄnderung nutzen DisplWTZ=40 ' nach 40 Sek. nichts tun - Display aus M_HOUR=HOUR:M_MINUTE=MINUTE ' OM-Zeiten für Manipulation aktivieren pb=255 ' Anfangsadresse des Zeigers auf "minus 1" GOTO Anzeige ' gehe zur LCD-Anzeige END IF IF MTast=230 THEN ' Li. Taste mit Fkt=9(230=239-Fakt=> LCD aus #LCD_AUS FAKT=0 ' TastenManipulation beenden DisplWTZ=0 ' LCD - AnZeit auf 0 setzen LCD_Port=&b10000000 ' GND wegnehmen, dadurch LCD=AUS IF Manip>0 THEN ' Wenn Werte geändert wurden, Manip=0: Schreib ' dann speichern in EEPROM HOUR = M_HOUR ' und OM-Uhrzeit aktualisieren MINUTE = M_MINUTE ' sowie die aktuelle Uhrzeit GOSUB Setze_PCFUhr ' in den Uhrenbaustein eintragen END IF END IF '************************************************************************** ' Editieren der Werte im LCD-Display '************************************************************************** IF MTast=214 THEN ' Wenn rechte obere Zeiger-Taste, Cursor schieben DisplWTZ=40 ' Display-An-Zähler neu setzen ADD pb,1 ' Zeiger +1 (1. Zeigerstellung jetzt 0) IF pb>7 THEN pb=0 ' 8 Änderungsobejkte Value=@pb: GOTO AnzWei ' Nacheinander WerteÜbergabe aus Byte[Speicher] END IF IF MTast= 86 THEN ' Wenn All-Hoch-Taste im LCD-Modus (Fakt=9) gedrückt, ADD value,1 ' dann Wert um 1 erhöhen Manip=1 ' Manipulation, also nachher Änderung speichern GOTO AnzWei0 ' zur Anzeige END IF IF MTast=118 THEN ' Wenn All-Runter-Taste im LCD-Modus (Fakt=9) gedrückt, SUB value,1 ' dann Wert um 1 mindern Manip=1 ' Manipulation, also nachher Änderung speichern GOTO AnzWei0 ' zur Anzeige END IF GOTO Start ' nötig für "GOTO LCD_AUS" #AnzWei0 IF pb=2 then GOTO Anzwei1 'Dunkelsensor mit Wertebereich 0-255 IF Value>59 Then Value=0 'Minutenbereich 0-60 #Anzwei1 DisplWTZ=40 ' Display-An - Zähler neu setzen GOSUB ZEHN ' Value ausgeben #AnzWei CURSOR = LOOKTAB (CursZeil,pb) 'KursorOrt&Zeile holen lcd_writecmd &B00001111 'Display ON, Cursor ON, Blinken ON lcd_writecmd &B10000000 OR CURSOR 'Ort wo Cursor blinkt @pb=value ' Wert eintragen wo Zeiger hinweist GOTO START '----------------------------------------------------------------------------------- ' Rollos fahren ' Bei Neustart der OM wurde die Rolladenstellung "vergessen". ' Rolladen oben = Rollowert = Dauer; ' Rolladen unten = Rollowert = 0 ' Rolladenstellg irgendwo, dann Hochfahrzeit=Dauer-Rollowert ' Runterfahrzeit=Rollowert ' Hochfahren: Mit Terassentür anfangen; Runterfahren: Mit Terassentür aufhören ' Wenn Terassentür auf ist (Magnetsensor), dann Terassentür nicht autom. runter ' Merken, wenn schon runter/hoch gefahren wurde, damit nicht bei DunkelSensor nochmal ' Ebenso, wenn Summenfahrzeit <1 Minute, dass dann nicht nochmal gefahren wird ' Schon_Oben=1 wenn alle Rollos oben sind, sonst Schon_Oben=0 ' Schon_Unten=1 wenn alle Rollos unten sind, sonst Schon_Unten=0 '------------------------------------------------------------------------------------ #ALL_RUNT ' Alle Rollos runterfahren BEEPfrequ=160:Beepdauer=25 ' Akustik GOSUB BEEPER ' AlleRollo=1:I=12 ' Betrifft alle Rollos, fange mit AZ,Kü, Bad an #ALL_RUNT_Weiter ' Fange mit AZ an (AZ,Kü,Bad an versch. 230V-Stromkreisen, IF i<8 THEN Schon_Unt=1:GOTO STart' alles fertig SUB i,1 ' deshalb zusammen, dann einzeln bis Terassentür Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht pb=I+17 ' schon gefahrene Zeit (Byte[23-27 (pB=28=>Byte[27]] IF I=11 THEN a=164:@pb=0 ' 164=Binärcode der drei Motoren, volle Zeit fahren... ELSE ' "Dauer"= Byte[10] da Zählung von 0 =>pb=9 GOSUB HOL_PCF8574_ULN_WERT ' ansonsten hole ULN_Wert ENDIF Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht IF i=7 and TTuer<>255 THEN ' wenn Terassentür aufsteht soll das Rollo nicht automatisch GOTO Start ' die Tür verschließen um Aussperren zu vermeiden... ENDIF Print"Ru:";i; GOSUB Motor_aus_Tabelle_An #Runt_Warte Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht If @pb>Dauer THEN @pb=0 ' Wenn Neustart, volle Fahrzeit RolloWzt=Dauer-@pb ' Fahrzeit vorgeben GOSUB Warte @pb=Dauer-RolloWzt ' Merkt aktuelle RolloPosition IF AlleRollo=1 THEN GOTO ALL_Runt_Weiter ' nächstes Rollo GOTO Einsprung_RuntWarte ' nach Abbruch/Ende der Fahrt #ALL_HOCH ' Alle Rollos hochfahren BEEPfrequ=200:Beepdauer=25 ' Akustik GOSUB BEEPER ' AlleRollo=1:I=&B11111111 ' Betrifft alle Rollos ;i=i+1=0 #ALL_HOCH_Weiter ' Fange mit TerassenTür an, bis zum Bad,AZ&Küche ADD i,1 IF i>4 THEN Schon_Obn=1:GOTO Start ' alle Rollos oben Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht pb =I + 24 ' schon gefahrene Zeit, ab Byte 23 (Zählung ab Byte[0].. IF I=4 THEN ' Sondersituation:3 unabhängige Stromkreise a=74:@pb=Dauer ' dadurch gleichzeitiges Fahren d. Motoren ohne ELSE ' Motorfehler, dafür aber immer volle Zeit ^pB(26)=dauer GOSUB HOL_PCF8574_ULN_WERT ' ansonsten hole ULN_Wert (hole a) ENDIF ? "Ho"; i; ' RS232-Kontrollausgabe GOSUB Motor_aus_Tabelle_An ' schalte Motor an und fahr das jeweilige Rollo hoch #Hoch_Warte Dark=255 ' FotoZellVerzögerung austricksen;255 => sehr hell Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht If @pb> Dauer THEN ' Wenn Neustart, RolloWzt=Dauer ' volle Fahrzeit ELSE RolloWzt=@pb ' ansonsten alte Fahrzeit einlesen Endif ' Fahrzeit vorgeben GOSUB Warte @pb=RolloWzt ' Merkt aktuelle RolloPosition IF AlleRollo=1 THEN GOTO ALL_Hoch_Weiter ' nächstes Rollo #Einsprung_RuntWarte GOSUB Rollo_AUS ' nach Abbruch/Ende der Fahrt GOSUB SpeicherOMBytes ' Speichere die Rolladenstellung & GOTO Start ' setze OM-Uhr auf Uhrenbaustein #Warte ?"Wzt:"; RolloWzt;" "; ' RS232-Kontrollausgabe Schon_Obn=0:Schon_Unt=0 ' Nicht alle Rollos sind oben o. unten BEEPdauer=10:BeepFrequ=50 ' akustische Quittierung GOSUB Beeper temp=SEcond ' Merkt sich die Sekundenzeit #Warteweiter IF temp<>sECOND THEN ' wenn neue Sekunde angefangen, dann SUB RolloWzt,1 ' Wartezeit um 1 Sekunde mindern Temp=Second ' neue Sekunde merken ' ?"s:";RolloWzt ' RS232-Kontrollausgabe ENDIF IF 255 <>Tast AND Tast2 THEN ' wenn irgendeine Taste gedrückt wurde, ?"TG" AlleRollo=0 ' kein Rollo mehr anfahren GOTO Rollo_AUS ' STOP aller Motoren und Rücksprung ENDIF ' nutzt dessen "RETURN" Dummy=Tast ' Dummy-Aufruf, damit SCL die Watchdog hochzieht IF RolloWzt<1 THEN ' wenn Fahrtzeit kleiner 1 Sekunde, dann GOTO Rollo_AUS ' STOP aller Motoren und Rücksprung ENDIF ' nutzt dessen "RETURN" GOTO Warteweiter ' warte auf Änderungen #Rollo_AUS ULN1=0:ULN2=0 ' Beide Motorsteuerungen ausstellen ?"AUS" ' RS232-Kontrollausgabe Pause 20 ' braucht nen Break sonst steigt die OM aus Beepdauer=10 Beepfrequ=150 GOSUB Beeper ' akust. Kommentierung #ReturnAdresse ' wird auch als RETURN von anderen Programm- RETURN ' teilen genutzt #HOL_PCF8574_ULN_WERT ' hole aus Tabelle den zugehörigen Steuerwert a=LOOKTAB (Tast_Wert,i+14) ' für den jweiligen PCF8674-ULN RETURN #Motor_aus_Tabelle_An ' schalte den jeweiligen Motor über den IF LOOKTAB(Tast_wert,i+28)=1 THEN ' entsprechenden PCF8574-ULN an ULN1=a: ?"U1"; ' UlN1=ON;Ausgabe des Rolladenmotors ELSE ULN2=a :?"U2"; ' UlN2=ON;Ausgabe des Rolladenmotors ENDIF RETURN '----------------------------------------------------------------------------------- ' LCD-Betrieb '----------------------------------------------------------------------------------- #Anzeige GOSUB LCD_INIT ' LCD Initiieren #wei 'HH:MM xxx of yyy (Uhrzeit MessDunkelWrt VorgabeDunkelWrt ' HH:MM^ HH:MMv Ex (Hoch- Runterfahrzeit Errorwert lcd_writecmd &B10000000 ' 1.Zeile, 1. Position 0 (0-17) SCHREIB_ZEIT (HOUR, MINUTE) ' ++++++++++++++++ lcd_writechar ASC(" ") ' HH:MM xxx of yyy SCHREIBE(FotoZell) ' akt. Dunkelwert lcd_writechar ASC(" ") ' lcd_writechar ASC("o") ' lcd_writechar ASC("f") ' lcd_writechar ASC(" ") ' SCHREIBE(M_Dark) ' gewählter Dunkelwert ' 2. Zeile beschreiben ' 2. Zeile lcd_writecmd &B11000000 ' ++++++++++++++++ SCHREIB_ZEIT (HOCH_H, HOCH_M) ' HH:MM^ HH:MMv Ex lcd_writechar 0 ' Pfeil nach oben lcd_writechar ASC(" ") ' Space SCHREIB_ZEIT (RUNT_H, RUNT_M) ' HH:MM lcd_writechar 1 ' Pfeil nach unten lcd_writechar ASC(" ") lcd_writechar ASC("E") ' Errorvariable VALUE = ERROR: GOSUB EIN GOTO Start '*************************************************************************** ' Dezimalausgabe '**************************************************************************** FUNCTION SCHREIBE (value) 'Wert ausgeben IF Value>=100 THEN temp = ASC("0") + Value/100:Value=Value Mod 100: ELSE temp = ASC("0") LCD_WRITECHAR temp #ZEHN' Zehner-Dezimalstelle oder Leerzeichen IF Value >= 10 THEN temp = ASC("0") + Value/10 ELSE temp = ASC("0") LCD_WRITECHAR temp #EIN' einer Dezimalstelle oder Leerzeichen temp = ASC("0") + Value MOD 10 LCD_WRITECHAR temp RETURN END FUNCTION FUNCTION SCHREIB_ZEIT (A,B) Value=A:GOSUB ZEHN:lcd_writechar ":" Value=B:GOSUB ZEHN RETURN ' -------------------------------- UHR ------------------------------------ ' Holen der Uhrzeit vom externen Uhrenbaustein und Schreiben in die OM ' oder Schreiben der Systemzeit der OM in den externen Uhrenbaustein ' Uhrenbaustein PCF8573 wird auch genutzt, um die durch die Watchdog ' ausgelösten Neustarts und die Lage der einzelnen Rolläden zu speichern. ' Ist CountNeustart=0, muß die OM so lange aus gewesen sein, dass ' die Goldcap-Pufferung aus ist und alles "vergessen" wurde ' freier RAM ab 1F - FF '***************************************************************************** #Setze_PCFUhr ' PRINT"SetzPCFUhr" ' Setzt Uhrenbaustein auf OM-Systemuhrzeit ReGISTER=0 ' It is recommended to set the stop counting flag GOSUB UhrStart ' of the control/status register before loading i2c_write(&B10000000) ' a new time. 0=stop counting Register=3 ' Register 3: Speicherplatz MINUTE GOSUB UhrStart ' Initiiert Uhr ab Register 3 GOSUB Dez_to_BCD(MINUTE) ' Wandele Dezimal in BCDzahl und schreibe GOSUB Dez_to_BCD (HOUR) ' Minute/Stunde in Uhrenbaustein ReGISTER=0 GOSUB UhrStart i2c_write(&B00000000) ' Count pulses #SpeicherOMBytes ' Schon_Unt,StartZahl,HoRuZeiten,Schon_Obn Register=20 ' Save OM-Bytes 21-30 pb=20=>Byte[21]=Schon_Unt GOSUB UhrStart ' Initiiert Uhr ab Register 21 For pb=Register to 29 ' pb weist auf OM-Speicherplatz i2c_write(@pb) ' @pb Wert am Speicherplatz next ' in den Uhrenspeicher #Setze_OMUhr ' Setzt OM-Zeit auf UhrenbausteinZeit Register=3 ' Register 3: Minuten, nächstes: Stunden GOSUB Uhr_Lesen ' Setze Uhrenbaustein auf Lesestatus ab 'MINUTEn ' Register 3 (Minuten) GOSUB BCD_to_Dez:MINUTE=y ' Lies aus und setze OM-Uhr auf MINUTE 'Stunden GOSUB BCD_to_Dez:Hour=y ' Lies aus und setze OM-Uhr auf Stunden I2C_STOP Register=20 ' pB=20=Byte[21] ;pB=29=Byte[30];Schon_Obn GOSUB Uhr_Lesen ' Ab Speicher 21 steht Zahl der Watchdog- For pb=Register To 29 ' Neustarts und Rollladenfahrzeiten @pb=I2C_READ ' Schreibe alles in OM-Byte-Speicher next RETURN #UhrStart InitStartWrite(PCFUhr) ' Initiiert Uhr PAUSE 20 i2c_write(Register) ' Register 3: MINUTEn RETURN #Uhr_Lesen ' Uhr zum Lesen auf Register setzen GOSUB UhrStart ' Initiiert Uhr I2C_STOP:PAUSE 20 ' gib dem PCF seine Zeit AdrPCF=PCFUhr+1 ' Leseadresse GOSUB Einsprung0 ' Bringe Uhrenbaustein in Lesestatus RETURN #BCD_to_Dez ' Wandele BCD in Dezimalzahl Wert=i2c_read ' Hole BCD-Zahl (Minute/Stunde usw. aus UhrMemory x= Wert and &hF ' BCD-Zahl (ohne obere 4 BITs in x)=EINER y= x+10*(WERT SHR 4) RETURN FUNCTION Dez_to_BCD (Wert) ' Wandele Dezimal in BCDzahl (Zahl in Wert) Y=Wert/10 ' Zehner ' ' x= Wert -(Y*10)+ (Y SHL 4) ' Zehner(Y SHL 4) Einer (Wert-Y*10) i2c_write(x) ' MINUTEn oder Stunden gesetzt PAUSE 20 RETURN FUNCTION InitStartWrite (AdrPCF) GOSUB I2C_INIT ' Initiiert und #Einsprung0 ' anderes Programm springt hier ein GOSUB I2C_START ' startet GOSUB I2C_WRITE(AdrPCF) ' Adresse des PCFs + 1 zum Lesen RETURN '------------------------------------------------------------------------ ' Schreiben der zu merkenden Bytes in den EEPROM ' BYTE[3] - Byte[7] Hoch/Runterfahrzeit, Dunkelwert ' PRINT I2C_WRITE - mit Rückgabewert; I2C_WRITE - ohne Rückgabewert '------------------------------------------------------------------------ #Schreib ERROR=ERROR AND &B11111110 ' WriteReadControl: Bit_0 von Byte[8] auf 0 'Print "Schreib" ' Ausgabe auf RS232 GOSUB I2C_Stop GOSUB I2C_Stop ' Anfangsbedingung GOSUB InitStartWrite (160) ' EEPROM-Adresse I2C_WRITE (1) ' StartadresseEEproms; Falle: Adressraum d. I2C_WRITE (0) ' 2456-er 8 o. 16Bit (hier 16 Bit) FOR pb=2 TO 6 ' Auslesen der OM-Bytes[3]- [7]; pB=2 =>Byte[3] I2C_WRITE(@pb) ' Schreib Byte[3]-[7] in EEProm KurzzeitMemory ' Print @pb ' Ausgabe auf RS232 NEXT pb GOSUB I2C_STOP ' Stop-Befehl: Daten in Langzeitspeicher GOSUB ACK_POLLING ' Wartet bis EEPROM fertig ist ' und macht mit "LIES" Kontrollesung '---------------------------------------------------------------------------------- ' Auslesen der zu merkenden Bytes in den EEPROM, dadurch dauerhafte Speicherung ' BYTE[3] - Byte[7] Hoch/Runterfahrzeit, Dunkelwert '---------------------------------------------------------------------------------- #LIES 'Print "Lies" ' Ausgabe auf RS232 ERROR=ERROR OR &B00000001 ' WriteReadControl: Bit_0 von BYTE[8] auf 1 setzen InitStartWrite(160) ' Write-Adresse (LSB=0) I2C_WRITE (1) ' Start-Adresse für Lesevorgang I2C_WRITE (0) ' Start-Adresse für Lesevorgang I2C_START ' Starten I2C_WRITE (161) ' I2C-Leseadresse (LSB=1) FOR pb=2 TO 6 ' OM-Bytes[3]- [7] ; pb=2 => Byte[3] @pb=I2C_READ ' EEPROM-Werte nach OM-Bytes[3]- [7] PRINT @pb ' Ausgabe auf RS232 NEXT pb ' sonst bleibt der oben eingetragene Wert von 1 I2C_STOP ' Sequentielles Lesen beendet 'Print "FF" ' Kontrollausgabe auf RS232 RETURN ' Wenn alles ok, ist Bit[0] von BYTE[8](ERROR)=0 ' sonst ERROR=0 #ACK_POLLING a=0 REPEAT '"ACKNOWLEDGE POLLING", so lange Schreibadresse senden, I2C_START ' bis EEPROM für ACK ein ON ausgibt 'PRINT "P" ' auf RS232 sichtbar machen ADD a,1 ' wenn zu lange, dann Abbruch UNTIL I2C_WRITE(160) OR a>254 ' Loop "Fuß-gesteuert" wird mindestens einmal RETURN ' durchlaufen '**************************************************************************** ' LCD initiieren, Steuerbefehle, Definition neuer Zeichen '***************************************************************************** #lcd_init LCD_Port=&b10000000 ' GND wegnehmen PAUSE 15 ' damit RESET genug Zeit hat LCD_Port=&b00000000 ' LCD an GND anschliessen ' dadurch wird LCD initialisiert PAUSE 10 ' damit RESET genug Zeit hat ' mit 8-Bit-Commando in 4-Bit-Modus umschalten LCD_Port=&b01000010 ' Einlesen bei Enable (Bit 7) Änderung von 1 lcd_e=OFF ' auf 0 'ab jetzt versteht das Display nur 2 Halbbytes lcd_writecmd &B00101000 'Display hat 2 Zeilen und 5x8 Pixel 'Neue Zeichen (Pfeile, °C) in den CGRAM schreiben lcd_writecmd &B01000000 ' Sets CGRAM-Address auf 1 FOR i=0 TO 15 ' Nachfolgend werden fortlaufend jeweils ' 8 Byte für ein Zeichen in den CGRAM lcd_writechar LOOKTAB(LCDextraDefinition,i) ' eingelesen und CGRAM-Adresse NEXT ' um 1 erhöht 'Display anschalten lcd_writecmd &B00001111 'Display ON, Cursor ON, Blinken ON RETURN ' bei "AND" bleibt die 0 bei "OR" die 1 erhalten PROCEDURE lcd_writecmd (a) 'Steuerbefehle: RS=0 (Bit 5) CMD=&b01000000:GOSUB LCD_Write RETURN END PROCEDURE PROCEDURE lcd_writechar (a) 'DateneingabeBefehl: RS=1 (Bit 5) CMD=&b01100000 #LCD_WRITE ' Write HI and Low Nibble lcd_port=a SHR 4 OR CMD ' High-Nibble, EN auf high lcd_e=OFF ' x0xx xxxx ' EN auf low lcd_port=a AND &B00001111 OR CMD ' Low-Nibble, EN auf high lcd_e=OFF ' x0xx xxxx EN auf low RETURN END PROCEDURE '--------------------------------------------------------------------------- ' BEEPER - der Beepaufruf benötigt 18 Speicherplätze, deshalb werden alle ' BEEPs über Gosub realisiert '--------------------------------------------------------------------------- #BEEPER BEEP BEEPFrequ, BEEPDauer, Ton RETURN '******************************************************************** ' Werteablage in Tabellen '******************************************************************** TABLE Tast_Wert BYTE ' RolloTasten, ULN-Werte ' RolloTasten, ULN-Werte ' -----------Hoch----------- ----------Runt---------- ' Tür FeL FeM FeR AZ K Bd Tür FL FeM FeR A K Bad 247 251 253 254 1 4 16 207 79 243 249 2 8 32 ' 14 Tastaturwerte 7 Hoch; 7 Runter ' 4 2 8 6 2 4 7 3 1 7 5 3 8 6 zugehörige PC48574-Pins 8 2 128 32 2 8 64 4 1 64 16 4 128 32 ' ULN-Kodierung 1 1 1 1 2 2 2 1 1 1 1 2 2 2 'ULN-Typ ' 0 2 4 6 8 10 12 '\ Tabelle lese- ' 14 16 18 20 22 24 26 '/ Indicees 'Speich 23 24 25 26 27 28 29 23 24 25 26 27 28 29 ' Speicher der Rollostellungen TABEND TABLE CursZeil BYTE ' Kodierung von Zeile & Ort für LCD-Ausgabe &B10000000 &B10000011 &B10001110 &B11000000 &B11000011 &B11000111 &B11001010 &B11001111 ' 1&0 1&3 1&14 2&0 2&3 2&7 2&10 2&15 TABEND TABLE LCDextraDefinition BYTE 'Kodierung von Sonderzeichen im CGRAM des LCDs ' Pfeil nach oben &B00000100 &B00001110 &B00010101 &B00000100 &B00000100 &B00000100 &B00000100 &B00000000 ' Pfeil nach unten &B00000100 &B00000100 &B00000100 &B00000100 &B00010101 &B00001110 &B00000100 &B00000000 ' Grad Celsius ' &B000011001 &B00011010 &B00000100 &B00000100 &B00000100 &B00000010 &B00000001 &B00000000 TABEND '***************************************************************************** ' Testprogramme zum Festlegen einzelner Werte oder ProgrammierKontrolle ' Da nicht genug Speicherplatz => ' (a) Testprogrammaufruf in den Zeilen 203-207 freigeben ' (b) zugehöriges Testprogramm entsperren... '***************************************************************************** '**************************************************************************** ' Testen der Watchdog ' legt für 2 Minuten SCL auf GND, 5V oder Eingang mit und ohne PULLUP '**************************************************************************** ' #Test_Watchdog ' ? "ON(1)OFF(2)Deact(3) AUS(4)" ' Input i: ' IF i=1 THEN Test_SCL=ON ' IF i=2 THEN Test_SCL=OFF ' IF i=3 THEN DEACT Test_SCL ' mit PULLUPA ' IF i=4 THEN PULLUPA=PULLUPA AND &B11101111 ' ohne Pullup ' IF I<1 or I>4 THEN GOTO Zurueck ' for I=1 to 20:? "P": Pause 150:next '150*20*20=> 120 sec #Zurueck 'RETURN '------------------------------------------------------------------------------ '**************************************************************************** ' Testen der I2C-Bausteine ' Gibt aus, welche der I2C-Bausteine gefunden wurden '******************************************************************************* '#Test_I2C_Bausteine '?:? "I2C-Bus Suche.." ' Text Ausgabe 'for A=0 to 254 step 2 ' I2C-Bus such - Adressen vorgeben 'gosub i2c_start 'Adresse=a ' I2C-Bus starten 'ACK = i2c_write(Adresse) ' Adr. senden, ACK empfangen 'gosub i2c_stop ' I2C-Bus stoppen 'if ACK=255 and A=0 then goto i2c_fehler ' Fehler im I2C-Bus 'if ACK = 255 then gosub gefunden ' Wenn "ACK" empfangen, dann auswerten 'next '?:? "Suche "; ' Leerzeile 'if b=0 then ? "erfolglos "; '? "beend." ' Text Ausgabe 'RETURN ' --------------------------------------------------------------------------- #i2c_fehler '? "I2C-Bus nicht ok" ' Text Ausgabe 'end ' --------------------------------------------------------------------------- #gefunden 'b=b+1 '? "IC_Adr.: "; Adresse; " (Dez) " ' Text Ausgabe 'return ' --------------------------------------------------------------------------- '****************************************************************************** ' Testen der ULNs: PCF8574A Adr.: 112 = Byteport 5 - ULN(1) ' PCF8574A Adr.: 120 = Byteport 9 - ULN(2) '****************************************************************************** ' #Test_ULNs ' PRINT "UlnPin(1-16,H/R 17/18):":Input i ' Eingabe über RS232 ' GOSUB Rollo_AUS ' Alle UlNs auf aus ' IF I=17 THEN GOTO All_HOCH ' IF I=18 THEN GOTO All_RUNT '------------------------------- ' Einzel-Pin-Selektion ' a=1: IF i>8 THEN a=2:i=i-8 ' ULN/Pin-Selektion ' b=1:b= b SHL (i-1):? "b:";b;"a:";a ' Ausgabe d. berechneter Wertes ' IF a= 1 THEN ULN1=b ELSE ULN2=b ' GND am selekt. ULN_PIN ' GOTO Test_ULNs '***************************************************************************** ' Testen der Tastatur mit Einzelrolladenaufruf '***************************************************************************** '#TastaturEinzelRollotest ' ?"Tast 1- 4" ' TT FL FM FR Einzelrollos nach oben ' ?"Tast 8-11" ' Einzelrollos nach unten ' Input i ' IF i>12 or i<8 and i>4 THEN GOTO TastaturEinzelRollotest ' MTast= LOOKTAB (Tast_Wert,i-1) ' ?"MT:";MTast ' GOTO ULN_TestProgramm_Einsprung '****************************************************************************** ' Testen des Uhrenbausteins: PCF8583 (Ein/Ausgabe) ' Register: Minute(3), Stunde(4), Jahr/Monatstag(5),Wochentag/Monat(6) ' 16-255 RAM-Speicher (erlischt bei VersorgungsSpannung <1 >6 Volt ' Register=5: &Baabbcccc Jahr=aa; Tage(10-er)=bb; Tage(einer;BCD-Kodierung)=cccc ' Register=6: &Baaabcccc Wochentag=a; Monat(10-er)=b; Monat(einer;BCD-Kodierung)=cccc ' Jahre(a=0-3), Schaltjahre:2004,2008,2012...=>aa=0 'Die mitteleuropäische Sommerzeit beginnt jeweils am letzten Sonntag im März um 2 Uhr mitteleuropäischer Zeit. 'Im Zeitpunkt des Beginns der Sommerzeit wird die Stundenzählung um eine Stunde von 2 Uhr auf 3 Uhr vorgestellt. ' Die mitteleuropäische Sommerzeit endet jeweils am letzten Sonntag im Oktober um 3 Uhr mitteleuropäischer Sommerzeit. ' Im Zeitpunkt des Endes der Sommerzeit wird die Stundenzählung um eine Stunde von 3 Uhr auf 2 Uhr zurückgestellt. ) ' Schaltjahrberechnung passt nicht mehr in die OM-Mini - evt. OM-Macro... '****************************************************************************** '29.03.2009 25.10.2009 #Test_PCF8583 ' I2C_STOP:? "Speich.(1) Lies(2)":Input i ' IF I=2 THEN GOTO UhrTestLese else IF I>2 THEN GOTO Test_Zurueck ' IF i=3 THEN GOTO TestDatum #UhrTestSpeicher ' ? "Speicher-"; ' GOSUB Test_UhrSpeicherplatz ' Hole Speicherplatz ' GOSUB UhrStart ' UhrInitation zum Speichern ' ?"Zahl";: Input a: GOSUB Dez_to_BCD(a) ' Speichere in Uhr als BCD-Zahl ' GOTO Test_PCF8583 #UhrTestLese ' ? "Lese-";: ' GOSUB Test_UhrSpeicherplatz ' Hole Speicherplatz ' GOSUB Uhr_Lesen ' Setze Uhr in Lesestatus ab Register ' GOSUB BCD_to_Dez ' Hole BCD-Zahl und wandele ' ? "Dez:"; Y ' Ausgabe als Dezimalzahl ' For i=1 to 8:Wert=Wert SHL 1 ' IF Carry Then ? 1; else ? 0; ' Ausgabe als Binärzahl ' next:? ' GOTO Test_PCF8583 #Test_UhrSpeicherplatz ' ? "Reg. 0-255 ?": Input Register ' Register wo Ein/Ausgabe #Test_Zurueck ' RETURN ' #Faertsch END ' --------------------------------------------------------------------------- ' Die von "extports.iia" benoetigten INCLUDE-Dateien einbinden ' --------------------------------------------------------------------------- INCLUDE "d:\elektron\OPMicr\Extports\om_i2c.pro" INCLUDE "d:\elektron\OPMicr\ESCI\omfwia.pro" '---------------------------------------------------------------------------- ' Erklärungen '---------------------------------------------------------------------------- '2430