Die Geburtstagskalenderuhr -...

68
Die Geburtstagskalenderuhr Video: http://www.youtube.com/watch?v=czhl8_Aprc8 Beschreibung des Projekts Da ich leider manchmal die Geburtstage lieber Mitmenschen vergesse, habe ich mir gedacht, ein Geburtstagskalender könnte vielleicht ganz nützlich sein. Wie bei einem Geburtstagskalender in Papierform, sollten die Termine unabhängig vom jeweiligen Jahr und Wochentag am Geburtsda- tum angezeigt werden. Nebenbei sollten auch andere Feiertage mit angezeigt werden. Dazu sollte die Kalenderuhr Datum, Uhrzeit und Wochentag anzeigen und optisch und akustisch daran erinnern, dass Heute ein besonderer Tag ist. Da ich gern fotografiere und bei Sonnenaufgang oder Sonnenuntergang das beste Licht ist, wollte ich, dass mir die Uhr die entsprechenden Zeiten angibt. Datum, Uhrzeit und andere Informationen sollten auf einem 16x4 LCD-Modul angezeigt werden, Uhrzeit und Datum der besseren Ablesbarkeit wegen auf einer zusätzlichen 7-Segmentanzeige. - 1 -

Transcript of Die Geburtstagskalenderuhr -...

Page 1: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Die Geburtstagskalenderuhr

Video: http://www.youtube.com/watch?v=czhl8_Aprc8

Beschreibung des ProjektsDa ich leider manchmal die Geburtstage lieber Mitmenschen vergesse, habe ich mir gedacht, ein

Geburtstagskalender könnte vielleicht ganz nützlich sein. Wie bei einem Geburtstagskalender in

Papierform, sollten die Termine unabhängig vom jeweiligen Jahr und Wochentag am Geburtsda-

tum angezeigt werden. Nebenbei sollten auch andere Feiertage mit angezeigt werden.

Dazu sollte die Kalenderuhr Datum, Uhrzeit und Wochentag anzeigen und optisch und akustisch

daran erinnern, dass Heute ein besonderer Tag ist. Da ich gern fotografiere und bei Sonnenaufgang

oder Sonnenuntergang das beste Licht ist, wollte ich, dass mir die Uhr die entsprechenden Zeiten

angibt.

Datum, Uhrzeit und andere Informationen sollten auf einem 16x4 LCD-Modul angezeigt werden,

Uhrzeit und Datum der besseren Ablesbarkeit wegen auf einer zusätzlichen 7-Segmentanzeige.

- 1 -

Page 2: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Als Grundlage sollte das myAVR Board light dienen, von dem möglichst alle verfügbaren Kompo-

nenten eine Funktion bekommen sollten. Zeit und Datum sollte eine RTC-Komponente (DS1307)

liefern und sämtliche Daten sollten in einem seriellen EEPROM gespeichert werden. Die Daten-

übertragung sollte PC-gesteuert über das myUSBtoUART-Modul erfolgen.

HardwareDas myAVR Board light ist die Grundlage der Kalenderuhr, auf die eine zweite (Lochraster)Platine

mit den Anzeigekomponenten gesetzt wird (Abbildung 1). Die Anzeigen sind ein 16x4 LCD-Modul

(Displaytech 164A) und eine serielle 7-Segment LED Anzeige (blau, Sparkfun Electronics). Die 7-

Segemtanzeige sieht nicht nur super aus (wie ich finde), sie hat auch den Vorteil nur eine einzige

Datenleitung zu benötigen. Der ATmega8 des myAVR Board light wird durch einen ATmega168

ersetzt, um etwas mehr Platz für das Programm zu haben.

Sämtliche Daten für Geburtstage, Feiertage, Sonnenaufgänge und Sonnenuntergänge werden in

einem EEPROM (24AA128-I/P, Microchip) gespeichert. Eine Echtzeituhr (DS1307, Dallas) liefert

Datum und Uhrzeit. Das batteriegepufferte NV-RAM der Uhr dient als Speicher für Einstellungen.

Beide Komponenten werden über den seriellen I2C-Bus angesteuert. Strom liefert ein Netzteil (5V)

basierend auf dem externPowerKit von Laser & Co. Solutions GmbH. Alle diese Komponenten

werden auf dem Rasterfeld des myAVR Board light untergebracht.

- 2 -

Abbildung 1: Seitenansicht der Kalenderuhr

Page 3: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Stückliste

Bauteil Anzahl Anbieter

myAVR Board light, Bausatz 1 Laser & Co. Solutions GmbH

16x4 LCD-Modul 164A (Displaytech) 1 Reichelt, Art.-Nr.: LCD 164A LED

7-Segment LED Anzeige blau (seriell) 1 Watterott electronic, Art.-Nr.: COM-09765

IC1: ATmega168PA-PU 1

IC2: EEPROM 24AA128-I/P 1

IC3: RTC DS1307 1

VR1: Spannungsregler µA 1705 1

BR1: Gleichrichter DIL B80C800DIP 1

T1: Transistor BC547C 1

D1: Diode BAT46 1

D2: Diode 1A - 1N4001 1

C6,8: Kondensator 47µF 2

C7,9: Kondensator 100nF 2

P1: Einstellpotentiometer, liegend, 5 K-Ohm 1

R2,3,6: Widerstand 10 K-Ohm 3

R5: Widerstand 480 Ohm 1

Q2: Uhrenquarz 32,768kHz (12.5 pF) 1

BAT1: Lithium-Knopfzelle: CR 2032 1

Batteriehalter 20 mm 1

IC-Sockel 28-polig (optional) 1

IC-Sockel 8-polig (optional) 2

Lochrasterplatine 100 x 100 mm 1

20 pol. Buchsenleiste gerade (RM 2,54, H: 8,5 mm) 1

10 pol. Buchsenleiste gerade (RM 2,54, H: 8,5 mm) 1

50-pol Stiftleiste gerade, RM 2,54 1

Hohlstecker-Einbaubuchse, gewinkelt 1

Wannenstecker 6-polig gerade 1

Buchsen-/Stiftleisten für Anzeigen (optional)

- 3 -

Page 4: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Schaltplan

- 4 -

Abbildung 2: Schaltplan

Page 5: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Zusammebau des myAVR BoardsDas myAVR Board light wird fast wie in der Anleitung angegeben aufgebaut. Zusätzlich wird der

6-polige Wannenstecker aufgelötet, um den ATmega168 über die ISP-Schnittstelle programmieren

zu können.

Die gewinkelte Buchsenleiste wird durch eine gerade Buchsenleiste ersetzt, die auf der Rückseite

des myAVR Boards angebracht wird. Eine Diode (D1) wird zwischen das myAVR Board light und

myUSBtoUART-Modul gelötet.

Zusätzlich wird bzw. werden:

• PD2 und PD3 auf der Rückseite des Boards mit Taster 1 und 2 über Drähte verbunden

• PB1 mit dem Summer verbunden.

• PC2 mit der Photodiode verbunden.

Bestückung des Rasterfeldes auf dem myAVR Board lightZuerst werden die Komponenten der Spannungsversorgung aufgebracht, dann die 8-poligen IC-So-

ckel, die Widerstände R2 und R3, der Uhrenquarz Q2 und der Batteriehalter (Abbildung 3) Nach-

dem die Komponenten gemäß Abb. 2 – 4 eingesetzt und verdrahtet sind, wird noch eine 10-polige

Buchsenleiste auf die Rückseite des myAVR Boards gelötet und entsprechend angeschlossen

(Abbildung 4). SDA und SCL werden mit PC4 und PC5 verbunden. LED-out wird mit der grünen

LED verbunden. Zuletzt wird der Hohlstecker über zwei Drähte mit dem Brückengleichrichter BR1

verbunden. An diesen Hohlstecker wird später das Netzteil angeschlossen.

- 5 -

Abbildung 3: Rasterfeld Oberseite

Page 6: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Dieser Aufbau stellt für sich genommen schon eine vollständig funktionierende Einheit dar und

kann unabhängig von der Anzeigekomponente betrieben werden.

Aufbau der AnzeigekomponenteDie Anzeigekomponente wird auf einer herkömmlichen 100 x 100 mm Punktrasterplatine aufge-

baut. Zuerst werden die Stiftleisten (20- und 10-polig) auf der Cu-Seite der Platine aufgelötet. Das

gestaltet sich schwierig, da Lötzinn nicht auf der unbeschichteten Seite haftet. Man muss die Stift-

leisten leicht herausziehen und diese mit der Spitze des Lötkolben auf der Cu-Seite löten

(Abbildung 5).

Die Stiftleisten werden später mit dem myAVR Board verbunden. Man sollte sicherstellen, dass

das Board mittig auf der Punktrasterplatine sitzt. Dann werden optional die Buchsenleisten für die

- 6 -

Abbildung 5: Anbringen der Stiftleiste

Abbildung 4: Rasterfeld Unterseite (Durchsicht)

Page 7: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Anzeigeelemente angebracht. Auch hier sollte man darauf achten, dass hinterher alles so ange-

bracht werden kann, wie man es sich gewünscht hat. Dann werden Trimmer P1, die Widerstände

R5, R6 und der Transistor T1 aufgelötet und gemäß Abbildung 6 und Abbildung 7 verdrahtet. Es ist

hilfreich, etwas Lötzinn von der Stiftleiste bis zum nächsten Punkt auf der Rasterplatine zu ziehen,

um von hier aus die Verdrahtung durchzuführen. Die Drähte direkt an der Stiftleiste anzulöten, ist

recht schwierig.

- 7 -

Abbildung 6: Anzeigekomponente Oberseite (R4 und T1 liegen im realen Aufbau unterhalb des LCD-Moduls)

Page 8: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Die Anzeigekomponente kann jetzt mit dem myAVR Board verbunden werden. Mit P1 lässt sich

der Kontrast des LCD-Moduls regeln, die Hintergrundbeleuchtung kann über die Software (PB2)

an und ausgestellt werden. Die Kommunikation mit der seriellen 7-Segmentanzeige erfolgt über

PB0. PD4-PD7 und PC0/PC1 dienen zur Ansteuerung des LCD-Moduls.

Jetzt fehlt nur noch die Stromversorgung. Die erledigt ein Steckernetzteil mit 9V Spannung.

Anmerkung: Auf den Fotos sind noch 3 Jumper zu erkennen. Diese hatte ich zum testen des Auf-

baus genutzt (Hintergrundbeleuchtung, Direktverbindung PC > 7-Segementanzeige und RW-Mo-

dus des LCD-Moduls). Für die Funktion der Uhr sind sie nicht notwendig.

- 8 -

Abbildung 7: Anzeigekomponente Unterseite (Durchsicht)

Page 9: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

- 9 -

Abbildung 8: Bestücktes Rasterfeld mit dem myUSBtoUART-Modul und der BAT46-Diode (links)

Abbildung 9: Rückseite des myAVR Boards und der Anzeigekomponente (siehe dazu auch die An-merkung auf der vorhergehenden Seite)

Page 10: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Programmierung Als Programmiersprache wurde BASCOM v2 gewählt. Das fertige Programm gelangt über die ISP-

Schnittstelle auf den Mikrocontroller. Das Programm, dass die Daten vom PC überträgt, wurde mit

AutoIt v3 realisiert.

Programmstruktur (Atmega168)Das Programm kann in 3 Teilbereiche gegliedert werden:

1. Anzeige von Uhrzeit, Datum, Geburtstagen, Feiertagen, Sonnenaufgängen/-untergängen

2. Empfang und Speichern von Daten und Einstellungen über das myUSBtoUART-Modul

3. Einstellungen; dazu gehören:

Uhrzeit und Datum

Hintergrundbeleuchtung des LCD-Moduls

Sommer-/Winterzeit

Zeitkorrektur

Anzeige von Uhrzeit, Datum, Geburtstagen, Feiertagen etc. (Übersicht)Auf dem 16x4 LCD-Modul werden jeweils nach Tastendruck nacheinander folgende Bildschirme

angezeigt:

- 10 -

Abbildung 10: Verschiedene Anzeigen auf dem 16x4-LCD-Modul (für besser Lesbarkeit bitte vergrößern). Video: http://www.youtube.com/watch?v=czhl8_Aprc8

Startbildschirm

Termine

Sonnenaufgänge / Sonnenuntergänge

Datum & Uhrzeit einstellen

Taster1

Taster1

Taster1

Taster1

Anzeige für einen:normalen Tag Geburtstag Feiertag

Geburtstagskind „Klaus“

geboren „1951“, wird heute „60“

um „7:43“ wird eine Melodie abgespielt

Page 11: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Wie in Abbildung 10 gezeigt, ändert sich die Anzeige des Startbildschirms, wenn ein besonderes

Datum erreicht ist. Die in der zweiten Zeile angegebene Uhrzeit ist dann die Zeit, an der eine Melo-

die abgespielt werden kann; es kann sich dabei natürlich auch um die genaue Geburtszeit handeln.

Bei einem Geburtstag sieht man noch das Geburtsjahr und das erreichte Alter.

Die nachfolgenden Bildschirme zeigen die nächsten 3 Termine bzw. Sonnenaufgänge / Sonnenun-

tergänge der nächsten 3 Tage.

Der letzte Bildschirm verzweigt in den Bereich zur manuellen Zeit- bzw. Datumseinstellung. Viel

komfortabler lassen sich diese Einstellungen allerdings mit dem PC-Programm machen.

Die 7-Segmentanzeige zeigt unabhängig von den ersten 3 Bildschirmen in wechselnden Zeitabstän-

den Uhrzeit & Datum wie folgt an:

Wenn Bildschirm 4 (Datum & Uhrzeit einstellen) erreicht wird, gibt die Anzeige „Set“ aus. Der

Doppelpunkt bei der Zeitanzeige und der Punkt bei der Datumsangabe blinken im 2s-Takt. Wenn

das Jahr angezeigt wird, wird kein (Doppel-)Punkt angezeigt

Ausgabe auf dem LCD-Modul

Die Realisierung einer Ausgabe auf einem LCD-Modul ist mit BASCOM sehr komfortabel. Dazu

muss am Anfang des Programms folgende Befehlssequenz eingefügt werden:

Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7Config Lcd = 16 * 4Cursor = Off

In der Hauptprogrammschleife wird dann beispielsweise folgende Befehlssequenz verwendet:

Locate 1 , 1 : Lcd "Datum & Uhrzeit "Locate 2 , 1 : Lcd Weekdaystr ; Spc(spaces)Locate 3 , 1 : Lcd Date$ ; Spc(8)Locate 4 , 1 : Lcd Time$ ; Spc(8)

Der Befehl „Cls“ wird kaum verwendet; stattdessen wird jede Zeile des LCD-Moduls vollständig

überschrieben, ggf. werden Leerzeichen (Anweisung Spc) eingefügt.

Die Umschaltung zwischen den einzelnen Bildschirmen (Abbildung 10) erledigt eine Select Case-

- 11 -

Abbildung 11: Wechselnde Darstellung der 7-Segmentanzeige

UhrzeitHH:MM

Anzeigedauer: 52s

DatumTT.MM

Anzeigedauer: 4s

DatumJJJJ

Anzeigedauer 4s

Page 12: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Anweisung in der Hauptprogrammschleife, welche die Zahl der Tastendrücke auswertet (Variable

Cntb1). Jeder Tastendruck des Tasters 1 wird über einen Debounce-Befehl ausgewertet. Debounce

(eine Art Software-Entprellung) ist optimal, allzu „nervöse“ Taster zu bändigen. Um wirklich sicher

zu gehen, wartet in der Button1-Subroutine noch ein Bitwait-Befehl auf den Taster.

Debounce Pind.2 , 0 , Button1 , Sub...Button1: Bitwait Pind.2 , Reset If Cntb1 = 3 Then Cntb1 = 0 Else Incr Cntb1 ClsReturn

Select Case Cntb1

Case 0: 'Startbildschirm...Case 1: 'Termine...Case 2: 'Sonnenauf/-untergänge...Case 3: 'Datum & Uhrzeit einstellen...End Select

Ausgabe auf der seriellen 7-Segmentanzeige

Für die Ausgabe auf der seriellen 7-Segmentanzeige muss zuerst ein Software-UART in BASCOM

realisiert werden, da das Hardware-UART für den Datenempfang zuständig sein soll:

Open "comb.0:9600,8,n,1" For Output As #1

Die serielle 7-Segementanzeige wird in der Hauptprogrammschleife dann über eine Print #1-

Anweisung folgendermaßen angesteuert:

Timestr = Time$...A = Mid(timestr , 1 , 2)B = Mid(timestr , 4 , 2)...Print #1 , A ; B;

Die serielle 7-Segementanzeige kennt einige Steuerbefehle (siehe Datenblatt beim Anbieter), so

etwa zum setzen des Doppelpunkts oder des Dezimalpunkts:

Print #1 , "w";Printbin #1 , 16 ;...Print #1 , "w";Printbin #1 , 2;

Wichtig ist ein “;“ am Ende eines Print-Befehls, sonst zeigt das Modul nur „Müll“ an.

Die im 2s-Takt blinkende Anzeige des (Doppel)Punktes wird über den 16 Bit-Timer des

ATmega168 realisiert, dabei wird die Variable Colon_onoff auf 0 oder 1 gesetzt (Toggle-

Anweisung):

- 12 -

Page 13: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Config Timer1 = Timer , Prescale = 64On Timer1 Toggle_colonEnable Timer1Start Timer1

Enable Interrupts...Toggle_colon: Timer1 = 7936 Toggle Colon_onoff If All_off = 1 Then Colon_onoff = 0Return

Der automatische Wechsel von Datum, Uhrzeit und (Doppel-)Punkt (siehe Abbildung 11) wird

dann über einige If-Then-Else Anweisungen in der Hauptprogrammschleife realisiert

(Colon_onoff/Dp_onoff/All_off schaltet :/./ / AN bzw. AUS):

Timestr = Time$ Datestr = Date$

A = Mid(timestr , 1 , 2) B = Mid(timestr , 4 , 2) C = Mid(timestr , 7 , 2)

If Colon_onoff = 0 And Dp_onoff = 0 Then Print #1 , "w"; Printbin #1 , 0 ; Elseif Colon_onoff = 1 And Dp_onoff = 0 And All_off = 0 Then Print #1 , "w"; Printbin #1 , 16 ; Elseif Colon_onoff = 1 And Dp_onoff = 1 And All_off = 0 Then Print #1 , "w"; Printbin #1 , 2 ; Else Print #1 , "w"; Printbin #1 , 0; End If

If C > "30" And C < "35" Then All_off = 0 A = Mid(datestr , 1 , 2) B = Mid(datestr , 4 , 2) Dp_onoff = 1 Elseif C > "34" And C < "39" Then All_off = 1 A = "20" B = Mid(datestr , 7 , 2) Else Dp_onoff = 0 All_off = 0 End If

If A < "10" Then A = Mid(a , 2 , 1) Print #1 , "x" ; A ; B; Else Print #1 , A ; B; End If

In der letzten If-Then-Else-Anweisung wird bei einer führenden Null das erste Segment der 7-

Segemtanzeige ausgeschaltet ("x"). Aus z.B. „07:34“ wird „7:34“ bzw. wird aus dem „07.04“ der

„7.04“.

Steuerung der Hintergrundbeleuchtung des LCD-Moduls

Die Hintergrundbeleuchtung des LCD-Moduls kann über das PC-Programm AN/AUS gestellt wer-

- 13 -

Page 14: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

den. Daneben gibt es noch den Auto-Modus. Dieser Modus wertet die Helligkeit im Raum über den

Fotowiderstand des myAVR Boards und nutzt den A/D-Wandler des ATmega. Wenn es zu dunkel

ist, wird die Beleuchtung ein- und wenn es hell genug ist wieder ausgeschaltet. Unabhängig davon

wird die Hintergrundbeleuchtung um 0.00 Uhr vollständig ausgestellt und ab 7.00 wieder in den

Auto-Modus versetzt. Immer AN ist die Hintergrundbeleuchtung bei der manuellen Zeiteinstellung

und beim Abspielen einer Melodie:

Config Portc.2 -1 = OutputConfig Adc = Single , Prescaler = Auto , Reference = Avcc

Dim Licht As Word

Lcd_bl Alias Portb.2Config Lcd_bl = Output...Lcd_blonoff:

Licht = Getadc(2) If Lcd_blst = "1" Then Lcd_bl = 1 Elseif Lcd_blst = "3" And Licht < 120 And _hour > 6 Then Lcd_bl = 1 Else Lcd_bl = 0 End If

Return

Die Lcd_blonoff-Subroutine wird dann in der Hauptprogrammschleife aufgerufen. Lcd_bl (ein

„Alias“ für Portb.2) schaltet die Hintergrundbeleuchtung AN oder AUS. Lcd_blst bestimmt, wel-

cher Modus vorliegt. Die Variable Licht steuert, ab wann die Beleuchtung angeschaltet wird; 120

war hier ein guter Wert. Die Variable Lcd_blst wird im NV SRAM der DS1307-RTC gespeichert.

Wie das funktioniert, wird im Abschnitt Schreiben & Lesen von Daten & Zeiteinstellung beschrie-

ben.

Uhrzeit & DatumAktuelle Uhrzeit und Datum sind in den Variablen Time$ und Date$ enthalten, die BASCOM gene-

riert. Über den I2C-Bus wird die DS1307-RTC wie folgt angesprochen:

$lib "i2c_twi.lbx" 'TWIConfig Sda = Portc.4Config Scl = Portc.5Const Ds1307w = &HD0 'DS1307 schreibenConst Ds1307r = &HD1 'DS1307 lesen...Config Clock = UserConfig Date = Dmy , Separator = ....Getdatetime: I2cstart I2cwbyte Ds1307w I2cwbyte 0 I2cstart I2cwbyte Ds1307r I2crbyte _sec , Ack I2crbyte _min , Ack I2crbyte _hour , Ack I2crbyte Weekday , Ack I2crbyte _day , Ack

- 14 -

Page 15: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

I2crbyte _month , Ack I2crbyte _year , Nack I2cstop _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)Return

Eine Ausgabe auf dem LCD-Modul wird wie oben angegeben realisiert:

Locate 1 , 1 : Lcd "Datum & Uhrzeit "Locate 2 , 1 : Lcd Weekdaystr ; Spc(spaces)Locate 3 , 1 : Lcd Date$ ; Spc(8)Locate 4 , 1 : Lcd Time$ ; Spc(8)

Der Wochentag „Weekday“ ist eine Zahl, die über eine Data-Tabelle in den entsprechenden Wo-

chentag „Weekdaystr“ umgesetzt wird:

Weekdaystr = Lookupstr(weekday , Weekdays)...Weekdays:

Data "dummy" , "Montag" , "Dienstag" , "Mittwoch" , "Donnerstag" , "Freitag" , "Samstag" , "Sonn-tag"

Empfang von Daten über das UARTDer Empfang der Zeichen erfolgt Interrupt-gesteuert. Im Gegensatz zum Input-Befehl wird das

Programm weiter ausgeführt und wartet nicht auf eine Eingabe:

Dim L As String * 4Dim S As String * 30Dim Z(31) As Byte At S OverlayDim N As Byte...On Urxc OnrxdEnable Urxc'ggf. „Enable Interrupts“ falls noch nicht anderweitig aktiviert...Onrxd: Incr N Z(n) = UDRReturn

Eine weitere schöne Sache an BASCOM sind „Overlays“ (siehe BASCOM-Hilfe). Die über UART

empfangenen Zeichen „Z(n)“ werden zum String „S“ zusammengesetzt.

Bei jeder Übertragung werden 31 Zeichen „N“ gesendet, die ersten vier Zeichen „L“ geben an, um

welche Art von Daten es sich handelt und was der ATmega damit machen soll (Select Case,

Case...):

If N > 30 Then

L = Left(s , 4)

Select Case L

Case "TEST": ... Case "TIME":

- 15 -

Page 16: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

... Case "SETT": ... Case "SUNS": ... Case "DATE": ... Case "CDAT": ... End Select

End If

Der „Case“ TEST ist der einfachste Fall, hier wird der empfangene String an den PC zurück gesen-

det. Das dient zur Kontrolle, ob die Kommunikation zwischen Kalenderuhr und PC funktioniert:

...Case "TEST":

N = 0 Print S;...

N muss nach jeder CASE-Anweisung wieder auf 0 gesetzt werden.

Schreiben & Lesen von Daten & Zeiteinstellung

Zeiteinstellungen

Datum, Wochentag und Uhrzeit können über folgende Unterprozeduren gesetzt werden (man be-

achte jeweils das I2Cwbyte nach Ds1307w):

Const Ds1307w = &HD0 'DS1307 schreiben...Setdate: _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year) I2cstart I2cwbyte Ds1307w I2cwbyte 4 I2cwbyte _day I2cwbyte _month I2cwbyte _year I2cstop Waitms 10Return

Setweekday: I2cstart I2cwbyte Ds1307w I2cwbyte 3 I2cwbyte Weekday I2cstop Waitms 10Return

Settime: _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) I2cstart I2cwbyte Ds1307w I2cwbyte 0 I2cwbyte _sec I2cwbyte _min I2cwbyte _hour I2cstop Waitms 10Return

- 16 -

Page 17: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Zeit und Datum lassen sich in BASCOM aber auch komfortabel über die Variablen Time$ und

Date$ setzen.

Die Echtzeituhr verfügt außerdem über 56 Byte batteriegepuffertes NV SRAM. In diesem werden

diverse Einstellungen der Kalenderuhr gespeichert. Nachfolgend die Angabe, ob momentan Som-

merzeit (Stset=1, Wtset=0) oder Winterzeit (Stset=0, Wtset=1) ist (man beachte wieder das

I2Cwbyte nach Ds1307w):

Const Ds1307w = &HD0 'DS1307 schreiben...Writenvram: I2cstart I2cwbyte Ds1307w I2cwbyte 8 I2cwbyte Stset I2cwbyte Wtset I2cstop Waitms 10Return

Die Zeitdaten, die das Programm über den PC empfängt (siehe Empfang von Daten über das

UART), sehen folgendermaßen aus:

TIME :07.04.1140121:56:57xxxxxx

TIME kennzeichnet, dass es sich um eine Zeitübertragung handelt

07.04.11 ist das Datum

4 ist der Wochentag (Donnerstag)

01 zeigt an, dass wir Sommerzeit haben (10 wäre Winterzeit)

21:56:57 ist die Uhrzeit

xxxxxx ist einfach ein Platzhalter, da immer 31 Zeichen übertragen werden.

Die Echtzeituhr wird dann wie folgt eingestellt:

...Case "TIME":

N = 0 Time$ = Mid(s , 18 , 8) Date$ = Mid(s , 7 , 8) Weekdayst = Mid(s , 15 , 1) Weekday = Weekdayst Call Setweekday

Wtsetst = Mid(s , 16 , 1) Stsetst = Mid(s , 17 , 1)

Wtset = Val(wtsetst) Stset = Val(stsetst)

Call Writenvram...

Aus dem empfangenen String „s“ werden Zeit und Datum über die Mid-Anweisung extrahiert und

gesetzt. Der Wochentag „Weekday“ wird über Call Setweekday gesetzt. Ob momentan Sommer-

bzw. Winterzeit vorliegt, wird in das NV SRAM über Call Writenvram geschrieben.

- 17 -

Page 18: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Einstellen von Sommerzeit und Winterzeit

Sommer- und Winterzeit werden von der Kalenderuhr automatisch eingestellt (Letzter Sonntag im

März oder Oktober). Wichtig ist, dass bei einer Zeitübertragung vom PC aus immer angegeben wer-

den muss, ob momentan Sommerzeit oder Winterzeit vorliegt. Bei einer Übertragung werden die

Variablen Stset und Wtset im NV SRAM gespeichert und von der nachfolgenden Routine ausge-

wertet:

Dst_onoff: If _month = 3 And _day > 24 And Weekday = 7 And _hour = 2 Then _hour = _hour + 1 Waitms 10 Call Settime Stset = 1 Wtset = 0 Waitms 10 Call Writenvram End If

If Wtset = 0 And _month = 10 And _day > 24 And Weekday = 7 And _hour = 3 Then _hour = _hour - 1 Waitms 10 Call Settime Wtset = 1 Stset = 0 Waitms 10 Call Writenvram End IfReturn

Die Anweisung _hour = _hour + 1 bzw. _hour = _hour – 1 stellt die Uhr eine Stunde vor bzw.

zurück. Über Call Settime wird die Uhrzeit gespeichert und die aktuellen Variablen Wtset und

Stset werden im NV SRAM gespeichert (Call Writenvram). Die Subroutine Dst_onoff wird in

der Hauptprogrammschleife aufgerufen.

Weitere Einstellungen

Weitere Einstellungen, die NV SRAM gespeichert werden, ist der Modus der

Hintergrundbeleuchtung und die Zeitkorrektur. Die Variablen werden über das PC-Programm

gesendet (siehe Empfang von Daten über das UART) und im NV SRAM abgelegt. Der gesendete

String ist folgendermaßen aufgebaut:

SETT: 310300000000000000000000x

SETT kennzeichnet, dass es sich um eine Einstellung handelt

3 bedeutet, dass die Hintergrundbeleuchtung auf Auto gestellt werden soll (1 = AN; 2=AUS)

1 bedeutet, dass die nachfolgende Sekundenzahl immer nach 24h abgezogen wird

(Zeitkorrektur) ; 0 würde bedeuten, dass die nachfolgende Sekundenzahl immer nach 24h

addiert wird

03 ist die Zahl der Sekunden, um die nach 24h korrigiert wird

die restlichen Nullen und das x sind Platzhalter, da immer 31 Zeichen übertragen werden.

Um die Zeitkorrektur nach 24h durchzuführen, muss die Kalenderuhr wissen, wann die Korrektur-

- 18 -

Page 19: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

daten übertragen wurden. Dazu werden die BASCOM-Routinen Sysday() und Secofday() aufge-

rufen und die Ergebnisse zusammen mit den übertragenen Daten im NV SRAM abgelegt (Call

Writenvram_sett). Die Definition der Variablen als „Overlay“ ermöglicht eine direkte Transfor-

mation der Variablen (Systemtag, Sekdestages) als abspeicherbare Bytes (Systemtagby,

Sekdestagesby):

Dim Systemtag As LongDim Systemtagby(4) As Byte At Systemtag Overlay

Dim Sekdestages As LongDim Sekdestagesby(4) As Byte At Sekdestages Overlay

...Case "SETT":

N = 0

Systemtag = Sysday() Sekdestages = Secofday()

Call Writenvram_sett Call Readnvram...

Die Zeichen aus der Datenübertragung vom PC können direkt im NV SRAM abgelegt werden; Z(7)

ist z.B. das 7. übertragene Zeichen. Das I2Cwbyte nach Ds1307w ist diesmal 10, da 8 und 9 bereits

belegt sind (siehe Writenvram):

Writenvram_sett: I2cstart I2cwbyte Ds1307w I2cwbyte 10 I2cwbyte Z(7) I2cwbyte 0 I2cwbyte Z(8) I2cwbyte 0 I2cwbyte Z(9) I2cwbyte Z(10) I2cwbyte 0 I2cwbyte Systemtagby(1) I2cwbyte Systemtagby(2) I2cwbyte Systemtagby(3) I2cwbyte Systemtagby(4) I2cwbyte Sekdestagesby(1) I2cwbyte Sekdestagesby(2) I2cwbyte Sekdestagesby(3) I2cwbyte Sekdestagesby(4) I2cstop Waitms 10Return

Da wichtige Einstellungsvariablen nicht im RAM des ATmega gelandet sind, muss der gerade ins

NV SRAM geschriebene Inhalt sofort wieder über Call Readnvram gelesen werden (hier erfolgt

dann die Zuordnung der Daten aus dem NV SRAM zu Variablen):

Dim Lcd_blst As String * 1Dim Lcd_blby(2) As Byte At Lcd_blst Overlay

Dim Plusminst As String * 1Dim Plusminby(2) As Byte At Plusminst Overlay

Dim Sekundest As String * 2Dim Sekundeby(3) As Byte At Sekundest Overlay

- 19 -

Page 20: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Dim Systemtag As LongDim Systemtagby(4) As Byte At Systemtag Overlay

Dim Sekdestages As LongDim Sekdestagesby(4) As Byte At Sekdestages Overlay...Readnvram: I2cstart I2cwbyte Ds1307w I2cwbyte 8 I2cstart I2cwbyte Ds1307r I2crbyte Stset , Ack I2crbyte Wtset , Ack I2crbyte Lcd_blby(1) , Ack I2crbyte Lcd_blby(2) , Ack I2crbyte Plusminby(1) , Ack I2crbyte Plusminby(2) , Ack I2crbyte Sekundeby(1) , Ack I2crbyte Sekundeby(2) , Ack I2crbyte Sekundeby(3) , Ack I2crbyte Systemtagby(1) , Ack I2crbyte Systemtagby(2) , Ack I2crbyte Systemtagby(3) , Ack I2crbyte Systemtagby(4) , Ack I2crbyte Sekdestagesby(1) , Ack I2crbyte Sekdestagesby(2) , Ack I2crbyte Sekdestagesby(3) , Ack I2crbyte Sekdestagesby(4) , Nack I2cstopReturn

Bei jedem Reset oder direkt nach dem Einschalten der Kalenderuhr wir vor der Hauptprogramm-

schleife Call Readnvram ausgeführt.

Zeitkorrektur

Die DS1307-RTC + Quarz ist nicht unbedingt ein hochpräzises Zeitmessinstrument, was am Quarz

liegen kann oder allgemein am Aufbau. Die nachfolgende Subroutine korrigiert die Uhrzeit alle 24h

zu einer bestimmten Uhrzeit um +/– x Sekunden. Die nachfolgende Routine ist recht komplex, was

daran liegt, dass die Zeitkorrektur erst am darauffolgenden Tag passieren darf und dass bei einer

negativen Zeitkorrektur die Kalenderuhr nicht in einer Korrekturschleife hängen bleibt. Sekundest

(Sekunde, um die korrigiert wird) und Plusminst (Zeitkorrektur + oder – ) werden aus dem NV

SRAM gelesen (Readnvram) (über „Overlay“ umgewandelt), ebenso Systemtag (Datum der Zeit-

korrekturübertragung) und Sekdestages (Sekunde des Tages, an dem die Zeitkorrekturübertra-

gung stattfand) (siehe vorheriger Abschnitt):

Dim Korrektur As LongDim Sekundelong As LongDim Sysd As LongDim Secd As LongDim Zeitkorrekturbit As Bit...Zeitkorrektur:

Call Readnvram

Sysd = Sysday() Secd = Secofday() Sekundelong = Val(sekundest)

If Secd = 86399 Then Zeitkorrekturbit = 0

- 20 -

Page 21: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

If Plusminst = "0" Then Korrektur = Sekdestages + Sekundelong If Plusminst = "1" Then Korrektur = Sekdestages - Sekundelong

If Sysd <> Systemtag And Secd = Sekdestages And Sekundelong <> 0 And Zeitkorrekturbit = 0 Then ' Time$ = Time(korrektur) Zeitkorrekturbit = 1 End IfReturn

Sysd und Secd entsprechen der aktuellen Systemsekunde und dem aktuellen Systemdatum. Nur

wenn diese nicht den gespeicherten Daten entsprechen, wird die Zeitkorrektur angewendet (letzte

If-Then-Else-Anweisung). Die Zeit wird über die BASCOM-Funktion Time aus der korrigierten

Sekunde des Tages eingestellt (Time$ = Time(korrektur)). Danach muss das Zeitkorrektur-

bit auf 1 gesetzt werden, um zu verhindern, dass bei einer negativen Korrektur die Zeit immer

wieder neu eingestellt wird. Am Ende des Tages wird das Zeitkorrekturbit wieder auf 0 gesetzt

(If Secd = 86399 Then Zeitkorrekturbit = 0).

Sonnenaufgänge und Sonnenuntergänge speichern und abrufen

Sonnenaufgänge und Sonnenuntergänge für einen bestimmten Standort zu berechnen, ist recht

aufwendig, so dass diese Daten nur übertragen (siehe Empfang von Daten über das UART) und im

EEPROM abgespeichert werden. Der gesendete String ist folgendermaßen aufgebaut:

SUNS: 421704:2420:280000000000x

SUNS kennzeichnet, dass es sich um einen Sonnenauf/untergang handelt

4217 ist der Tag des Sonnenauf/untergangs (gerechnet ab dem 01.01.2000)

04:24 ist der Zeitpunkt des Sonnenaufgangs

20:28 ist der Zeitpunkt des Sonnenuntergangs

die restlichen Nullen und das x sind Platzhalter, da immer 31 Zeichen übertragen werden.

Die nachfolgende CASE-Anweisung ruft die Subroutine Eepromwsonne auf:

... Case "SUNS":

N = 0

Call Eepromwsonne...

Const Eeprw = &HA0Const Eeprr = &HA1

Dim Adresse_sonne As WordDim Adresse_sonne_high As ByteDim Adresse_sonne_low As ByteDim X As Byte...Eepromwsonne:

N = 0

For X = 7 To 20

Adresse_sonne_high = High(adresse_sonne)

- 21 -

Page 22: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Adresse_sonne_low = Low(adresse_sonne)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_sonne_high I2cwbyte Adresse_sonne_low I2cwbyte Z(x) I2cstop

Waitms 10

Incr Adresse_sonne

Next

If Adresse_sonne > 1399 Then Adresse_sonne = 0 '14 bytes pro sonnenauf/-untergang /

Return

Da es sich um ein größeres EEPROM handelt, muss man den Adressbereich in High- und Low

trennen, was BASCOM praktischerweise über die Funktionen High und Low erledigt. Ansonsten

muss man noch beachten, dass von jedem übertragenen String nur die Zeichen 7 bis 20 gespeichert

(For X = 7 To 20....I2cwbyte Z(x)...). Nach 100 übertragenen Tagen wird die Adresse wie-

der auf 0 gesetzt.

Gelesen werden diese Daten über die nachfolgende Funktion. Übergeben wird der Funktion als Ar-

gument die Adresse (adresse_sonne) und man erhält als Ergebnis einen String, der den Tag und

die Uhrzeiten für Sonnenaufgang bzw. Sonnenuntergang beinhaltet:

Const Eeprw = &HA0Const Eeprr = &HA1

Dim Sonnetagst As String * 14Dim Sonnetagby(14) As Byte At Sonnetagst Overlay

Dim Adresse_sonne As WordDim Adresse_sonne_high As ByteDim Adresse_sonne_low As ByteDim X As Byte

Dim Stageeprom As String * 14Dim Stageepromday As String * 4Dim Sahst As String * 2Dim Sarest As String * 3Dim Suhst As String * 2Dim Surest As String * 3Dim Sahstn As IntegerDim Suhstn As Integer

...Function Eepromrsonne(adresse_sonne As Word) As String * 14

For X = 1 To 14

Adresse_sonne_high = High(adresse_sonne) Adresse_sonne_low = Low(adresse_sonne)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_sonne_high I2cwbyte Adresse_sonne_low

I2cstart I2cwbyte Eeprr I2crbyte Sonnetagby(x) , Nack I2cstop

- 22 -

Page 23: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Incr Adresse_sonne

Next

Stageeprom = Sonnetagst Stageepromday = Left(stageeprom , 4)

If Stset = 1 And Wtset = 0 Then

Sahst = Mid(stageeprom , 5 , 2) Sarest = Mid(stageeprom , 7 , 3) Suhst = Mid(stageeprom , 10 , 2) Surest = Mid(stageeprom , 12 , 3)

Sahstn = Val(sahst) Incr Sahstn Sahst = Str(sahstn) Sahst = Format(sahst , "00")

Suhstn = Val(suhst) Incr Suhstn Suhst = Str(suhstn) Suhst = Format(suhst , "00")

Stageeprom = Stageepromday + Sahst + Sarest + Suhst + Surest

End If

Eepromrsonne = Stageeprom

End Function

Auf den ersten Blick wirkt diese Funktion recht umfangreich, da ggf. die Sommerzeit berücksichtigt

werden muss. Eigentlich werden sonst nur 14 Bytes zu einem String zusammengesetzt, der den Tag

und die Uhrzeiten für Sonnenaufgang bzw. Sonnenuntergang beinhaltet.

Geburtstagstermine und Feiertage (kurz Termine) speichern und abrufen

Im Vergleich zur Sonnenaufgangs- oder Sonnenuntergangsdaten sind die Funktionen, um Geburts-

tage und Feiertage im EEPROM abzuspeichern oder von dort zu lesen etwas komplexer. Das liegt

hauptsächlich darin begründet, dass die Anzahl der abzuspeichernden Daten nicht konstant ist (im

Fall Sonnenaufgänge und Sonnenuntergänge waren es genau 100) und das zu bestimmten Termi-

nen bestimmte Aktionen ausgeführt werden sollen.

Als erstes muss bei jeder Datenübertragung vom PC die Startadresse der Datenspeicherung auf Ih-

ren Ursprungswert zurück gesetzt werden, da der ATmega nicht weiß, ob jetzt der erste oder ir-

gendeinen nachfolgender Termin gesendet wird. Dazu wird vom PC vor der eigentlichen Daten-

übertragung folgender String gesendet (siehe Empfang von Daten über das UART):

CDATxxxxxxxxxxxxxxxxxxxxxxxxxxx

CDAT kennzeichnet, dass die Startadresse zur Terminspeicherung im EEPROM angesteuert

werden soll

die restlichen x sind Platzhalter, da immer 31 Zeichen übertragen werden.

Die nachfolgende CASE-Anweisung setzt dann das EEPROM auf die Startadresse:

- 23 -

Page 24: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Dim Adresse_terminw As Word... Case "CDAT":

N = 0

Adresse_terminw = 0...

Danach sendet der PC folgenden String (bzw. mehrere Strings, je nach der Anzahl der Termine):

DATE0304195127780G1Klaus 1

DATE kennzeichnet, dass es sich um einen Termin handelt

03041951 ist das Geburtsdatum (03.04.1951)

27780 ist die Uhrzeit und gleichzeitig die Zeit, an der eine Melodie abgespielt wird;

angegeben als Sekunde des Tages (07:43)

G kennzeichnet, dass es sich um einen Geburtstag handelt (F = Feiertag)

1 ist die abzuspielende Melodie (0= Keine Melodie)

Klaus ist das Geburtstagskind; bis zu 10 Zeichen sind hier möglich

1 kennzeichnet, dass 1 Termin übertragen wird (2 für 2 Termine, 3 für 3 usw.; max. 99).

Am Ende der Übertragung werden zwei DATE-Strings gesendet, die nur Nullen enthalten,

DATE000000000000000000000000000. Das hat den Zweck, das Ende der aktuell übertragenen Ter-

minliste zu kennzeichnen. Da die Daten im EEPROM nicht gelöscht, sondern nur immer wieder

überschrieben werden, könnte der Fall eintreten, dass eine evtl. vorher im EEPROM abgelegte Lis-

te länger war als die gerade übertragene. Durch die beiden letzten DATE-Strings wird verhindert,

dass die Termine der alten Liste auf der Kalenderuhr angezeigt werden.

Die nachfolgende CASE-Anweisung ruft die Subroutine Eepromwtermine auf:

...Case "DATE":

N = 0

Call Eepromwtermine

...

Const Eeprw = &HA0Const Eeprr = &HA1

Dim Adresse_terminw As WordDim Adresse_termine14k As WordDim Adresse_termine_high14k As ByteDim Adresse_termine_low14k As Byte...Eepromwtermine:

N = 0

For X = 5 To 31

Adresse_termine14k = 1400 + Adresse_terminw Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

- 24 -

Page 25: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k I2cwbyte Z(x) I2cstop

Waitms 10 Incr Adresse_terminw

Next

Return

Diese Subroutine ist analog zur Subroutine Eepromwsonne, mit dem Unterschied, dass die Start-

adresse mit 1400 addiert wird (sonst würden die Daten für den Sonnenaufgang bzw. Sonnenunter-

gang überschrieben werden) und dass die Startadresse am Ende nicht zurückgesetzt wird (das erle-

digt „CDAT“). Von jedem übertragenen String werden nur die Zeichen 5 bis 31 gespeichert (For X =

5 To 31....I2cwbyte Z(x)...).

Gelesen werden diese Daten über die nachfolgende Funktion. Übergeben wird der Funktion als Ar-

gument die Speicheradresse eines Termins (adresse_termine) und man erhält als Ergebnis über

die BASCOM-Funktion Dayofyear den Tag im Jahr, an dem das Ereignis stattfindet (Termin-

date):

Const Eeprw = &HA0Const Eeprr = &HA1

Dim Adresse_termine As WordDim Adresse_termine14k As WordDim Adresse_termine_high14k As ByteDim Adresse_termine_low14k As Byte

Dim Terminest As String * 28Dim Termineby(28) As Byte At Terminest Overlay

Dim Termine_t As String * 2Dim Termine_m As String * 2Dim Termine_j As String * 2Dim Termine_jv As String * 4Dim Termine_jvi As IntegerDim Terminedatest As String * 8Dim Terminedate As Integer

Dim Schaltjahr As IntegerDim Termine_ij As Integer

...Function Gettermintag(adresse_termine As Word) As Integer

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

- 25 -

Page 26: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Incr Adresse_termine

Next

Termine_t = Left(terminest , 2) Termine_m = Mid(terminest , 3 , 2) Termine_j = Mid(terminest , 7 , 2) Termine_jv = Mid(terminest , 5 , 4) Terminedatest = Termine_t + "." + Termine_m + "." + Termine_j Terminedate = Dayofyear(terminedatest)

Termine_ij = Val(termine_j) Schaltjahr = Termine_ij Mod 4

If Schaltjahr = 0 And Terminedate > 59 Then 'Schaltjahr Decr Terminedate End If

Gettermintag = Terminedate

End Function

Zuerst muss das im EEPROM abgelegte Datum (z.B. 03041951) in ein für die Funktion Dayofyear

verwertbares Datumsformat umgeformt werden (aus 030411951 wird 03.04.1951). Das Jahr wird

noch einmal extra als Zahl in die Variable Termine_ij geschrieben. Wenn man mit Dayofyear ar-

beitet, muss man wissen, ob das Jahr ein Schaltjahr ist. Das lässt sich bequem über die Anweisung

Schaltjahr = Termine_ij Mod 4 ermitteln (jedes Schaltjahr zwischen 1901 und 2099 ist ohne

Rest durch 4 teilbar). Das betrifft natürlich nur Termine nach dem 28. Februar (...Terminedate

> 59).

Für die Nutzung der Terminfunktion der Kalenderuhr sind aber noch ein paar weitere Funktionen

nötig. Die folgende Funktion, Getterminadresse, ermittelt die Speicheradresse eines bestimmten

Termins im EEPROM. Übergeben wird der Funktion als Argument der Tag heute, der über die

BASCOM-Funktion Dayofyear(Date$) in der Hauptprogrammschleife erzeugt wird und man er-

hält als Ergebnis die Speicheradresse des Termins des heutigen Tages:

Dim Maxadressew As WordDim Heute As IntegerDim Alarm_heute As Bit...Function Getterminadresse(heute As Integer) As Word

Maxadressew = Getmaxadressetermine(0)

For Adresse_termine = 0 To Maxadressew Step 27

Terminedate = Gettermintag(adresse_termine)

If Terminedate = Heute Then Alarm_heute = 1 Else Alarm_heute = 0

If Terminedate >= Heute Then Exit For

Next

Getterminadresse = Adresse_termine

End Function

Hauptsächlich bedient sich diese Funktion der Ergebnisse der Funktionen

Getmaxadressetermine und Gettermintag. Falls der heutige Tag ein besonderer Tag ist

- 26 -

Page 27: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

(Geburtstag oder Feiertag), setzt die Funktion die Variable Alarm_heute auf 1.

Die Funktion Getmaxadressetermine ermittelt die Speicheradresse des letzten Termins einer Rei-

he von Terminen. Übergeben wird der Funktion als Argument adresse_termine (Speicheradres-

se eines bestimmten Termins), das aber im Programm immer 0 ist. Es wäre also nicht wirklich not-

wendig gewesen, die nachfolgenden Anweisungen in eine Funktion zu packen, der Übersichtlich-

keit halber habe ich es aber so gelassen. Als Ergebnis erhält man die oben erwähnte Speicher-

adresse des letzten Termins:

Const Eeprw = &HA0Const Eeprr = &HA1

Dim Maxadressew As WordDim Maxadressest As String * 2

...Function Getmaxadressetermine(adresse_termine As Word) As Word

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

Incr Adresse_termine

Next

Maxadressest = Mid(terminest , 26 , 2) Maxadressew = Val(maxadressest) Maxadressew = Maxadressew * 27

Getmaxadressetermine = Maxadressew

End Function

Die Funktion setzt den ersten im EEPROM gespeicherten Termin-String wieder zusammen. Die

letzten zwei Zeichen des Strings (Maxadressest = Mid(terminest , 26 , 2)) enthalten die

maximale Anzahl an übertragenen Datensätzen (siehe DATE-String). Daraus lässt sich dann die

Speicheradresse des letzten Termins ermitteln.

Die Funktionen Eepromrtermine gibt einen im EEPROM abgelegten String aus. Übergeben wird

der Funktion als Argument adresse_termine, also die Speicheradresse eines bestimmten Ter-

mins:

Const Eeprw = &HA0Const Eeprr = &HA1

Dim Termine_t As String * 2Dim Termine_m As String * 2Dim Termine_p As String * 10Dim Terminelcdst As String * 16

- 27 -

Page 28: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

...Function Eepromrtermine(adresse_termine As Word) As String * 16

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

Incr Adresse_termine

Next

Termine_t = Left(terminest , 2) Termine_m = Mid(terminest , 3 , 2) Termine_p = Mid(terminest , 16 , 10)

Terminelcdst = Termine_t + "." + Termine_m + " " + Termine_p

If Termine_t = "00" Then Terminelcdst = Space(16)

Eepromrtermine = Terminelcdst

End Function

Die Funktion setzt im ersten Schritt einen im EEPROM gespeicherten Termin-String wieder zu-

sammen. Dabei wird aus „0304195127780G1Klaus 1“ „03.04 Klaus „. Das sind

dann genau 16 Zeichen, entsprechend der Anzeigegröße des LCD-Moduls. Das Ergebnis wird in der

Variable Terminelcdst gespeichert. Falls der Termin-String nur Nullen enthält (bzw. die ersten

beiden Zeichen 00 sind), werden 16 Leerzeichen ausgegeben (If Termine_t = "00" Then

Terminelcdst = Space(16)).

Eine letzte Funktion in diesem Zusammenhang ist Eepromrtermine_alarm. Übergeben wird der

Funktion als Argument adresse_termine, also die Speicheradresse eines bestimmten Termins.

Als Ergebnis ermittelt die Funktion die Sekunde des Tages, an dem ggf. eine Melodie abgespielt

werden soll:

Const Eeprw = &HA0Const Eeprr = &HA1

Dim Termine_sek As String * 5Dim Termine_mu As String * 1Dim Termine_geburtstag As String * 1Dim Termine_alarml As Long...Function Eepromrtermine_alarm(adresse_termine As Word) As Long

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k

- 28 -

Page 29: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

Incr Adresse_termine

Next

Termine_sek = Mid(terminest , 9 , 5) Termine_mu = Mid(terminest , 15 , 1) 'Musik abspielen? Termine_geburtstag = Mid(terminest , 14 , 1) 'Geburtstag oder Feiertag

Termine_alarml = Val(termine_sek)

Eepromrtermine_alarm = Termine_alarml

End Function

Die Funktion ermittelt wie beschrieben aus einem im EEPROM gespeicherten Termin-String die

Sekunde des Tages (Termine_sek), die Information, ob Musik abgespielt werden soll und welche

(Termine_mu) und die Information, ob es sich um einen Geburtstag oder Feiertag handelt

(Termine_geburtstag) (siehe dazu auch DATE-String). Die Variablen Termine_mu und

Termine_geburtstag werden zwar nicht direkt als Ergebnis der Funktion übermittelt, werden

aber innerhalb der Funktion mit Werten gefüllt, die in der Hauptprogrammschleife abgerufen wer-

den.

Ausgabe von gespeicherten Daten auf dem 16x4-LCD-ModulSämtliche gespeicherten Daten, sowie Datum & Uhrzeit werden innerhalb der Hauptprogramm-

schleife ausgegeben. Durch drücken des Tasters kann zwischen verschiedenen Ausgabebildschir-

men umgeschaltet werden. Die Zahl der Tastendrücke wird über eine CASE-Anweisung ausgewertet

(siehe Anzeige von Uhrzeit, Datum, Geburtstagen, Feiertagen etc. (Übersicht)). Der erste Ausgabe-

bildschirm zeigt normalerweise Wochentag, Datum und Uhrzeit an. Liegt ein besonderer Termin

vor, wir dieser angezeigt:

Dim Adresse_termine As WordDim Termine_geburtstag As String * 1Dim Termine_alarmst As String * 6Dim Termine_alarml As LongDim Alarm_heute As BitDim Termin_heute As String * 16Dim Termine_jv As String * 4Dim Termine_jvi As IntegerDim Bdate As String * 2Dim Bdatei As IntegerDim Alter As IntegerDim Spaces As Integer...Select Case Cntb1

Case 0:

If Alarm_heute = 1 Then

Adresse_termine = Getterminadresse(heute) Termin_heute = Eepromrtermine(adresse_termine) Termin_heute = Mid(termin_heute , 7 , 10)

- 29 -

Page 30: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Termine_alarml = Eepromrtermine_alarm(adresse_termine) Termine_alarmst = Time(termine_alarml) Termine_alarmst = Left(termine_alarmst , 5)

Bdate = Mid(datestr , 7 , 2) Bdate = "20" + Bdate Termine_jvi = Val(termine_jv) Bdatei = Val(bdate) Alter = Bdatei - Termine_jvi

Locate 1 , 1 : Lcd "Heute " ; Termin_heute

If Termine_geburtstag = "G" Then Locate 2 , 1 : Lcd Termine_alarmst ; " " ; Termine_jv ; " " ; Alter ; " J" Else Locate 2 , 1 : Lcd Termine_alarmst ; Spc(11) End If

Locate 3 , 1 : Lcd Date$ ; Spc(8) Locate 4 , 1 : Lcd Time$ ; Spc(8)

Else

Spaces = Len(weekdaystr) Spaces = 16 - Spaces

Locate 1 , 1 : Lcd "Datum & Uhrzeit " Locate 2 , 1 : Lcd Weekdaystr ; Spc(spaces) Locate 3 , 1 : Lcd Date$ ; Spc(8) Locate 4 , 1 : Lcd Time$ ; Spc(8)

End If...

Ob ein besonderer Termin vorliegt, gibt die Variable Alarm_heute an. Die auszugebenden Daten

werden aus dem EEPROM geladen. Die entsprechenden Funktionen dazu (Getterminadresse,

Eepromrtermine, Eepromrtermine_alarm) wurden im vorangegangenen Kapitel vorgestellt. Das

Alter (Variable Alter) des Geburtstagskindes wird ebenfalls berechnet. Die Ausgabe eines Feierta-

ges oder Geburtstages ist unterschiedlich. Die Variable Termine_geburtstag zeigt an, ob es sich

bei dem Termin um einen Feiertag (F) oder Geburtstag (G) handelt. Der Variablen wird durch das

Aufrufen der Funktion Eepromrtermine_alarm der entsprechende Wert zugewiesen. Die verschie-

denen Ausgabebildschirme sind in Abbildung 10 dargestellt.

Der nächste Ausgabebildschirm zeigt die nächsten 3 anstehenden Termine:

Dim Adresse_termine As WordDim Heute As IntegerDim Maxadressew As WordDim Eepromrtermine_heute As String * 17...Case 1:

Heute = Dayofyear(date$) Maxadressew = Getmaxadressetermine(0) Adresse_termine = Getterminadresse(heute) Eepromrtermine_heute = Eepromrtermine(adresse_termine)

If Adresse_termine > Maxadressew Then Adresse_termine = 0

Locate 1 , 1 : Lcd "Termine" ; Spc(9)

If Eepromrtermine_heute <> " " Then Locate 2 , 1 : Lcd Eepromrtermine(adresse_termine) Else Adresse_termine = 0 Locate 2 , 1 : Lcd Eepromrtermine(adresse_termine)

- 30 -

Page 31: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

End If

Adresse_termine = Adresse_termine + 27 Locate 3 , 1 : Lcd Eepromrtermine(adresse_termine) Adresse_termine = Adresse_termine + 27 Locate 4 , 1 : Lcd Eepromrtermine(adresse_termine)...

Zuerst wird der Variablen Heute der Tag des Jahres zugewiesen. Die Variable Maxadressew ent-

hält die Gesamtzahl der Termine. Sollte der letzte Termin erreicht sein, wird Adresse_termine

auf null gesetzt. Das bedeutet, nachdem der letzte im EEPROM abgelegte Termin angezeigt wurde,

wird wieder der erste im EEPROM abgelegte Termin angezeigt. Nachdem die Adresse des ersten

anzuzeigenden Termins bekannt ist, werden einfach die beiden nächsten abgespeicherten Termine

angezeigt (Adresse_termine = Adresse_termine + 27). Damit nicht irgendwann Termine aus

einer alten Terminliste oder Datenmüll angezeigt wird, enthalten die letzten beiden im EEPROM

abgelegten Einträge nur Nullen (siehe DATE-String). Die Funktionen Getmaxadressetermine,

Getterminadresse und Eepromrtermine wurden im vorangegangenen Kapitel vorgestellt. Der

Ausgabebildschirm ist in Abbildung 10 dargestellt.

Im nächsten Ausgabebildschirm werden die Uhrzeiten für die Sonnenaufgänge bzw. Sonnenunter-

gänge der heutigen Tages und der folgenden 2 Tage angegeben. Der Übersichtlichkeit halber, wer-

den im folgenden Abschnitt Funktionsaufrufe und Berechnungen teilweise ausführlicher darge-

stellt, als eigentlich für die Funktion der Kalenderuhr notwendig.

Dim Stageeprom As String * 14Dim Stageepromday As String * 4Dim Sahst As String * 2Dim Sarest As String * 3Dim Suhst As String * 2Dim Surest As String * 3Dim Sahstn As IntegerDim Suhstn As Integer

Dim Sa As String * 5Dim Su As String * 5

Dim Sysdx As LongDim Sysdw As Word

Dim Systemtageepr As String * 5Dim Systemtageeprl As Long...Case 2:

Sa = Eepromrsonne(0) Systemtageepr = Mid(sa , 1 , 4) Systemtageeprl = Val(systemtageepr)

Sysdx = Sysday() Sysdw = Sysdx - Systemtageeprl Sysdw = Sysdw * 14 Sa = Eepromrsonne(sysdw) Sa = Mid(sa , 5 , 5) Su = Eepromrsonne(sysdw) Su = Mid(su , 10 , 5)

Locate 1 , 1 : Lcd "SonnenA/U 3 Tage" Locate 2 , 1 : Lcd "A " ; Sa ; Spc(2) ; "U " ; Su

Sysdx = Sysday() Sysdx = Sysdx + 1

- 31 -

Page 32: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Sysdw = Sysdx - Systemtageeprl Sysdw = Sysdw * 14 Sa = Eepromrsonne(sysdw) Sa = Mid(sa , 5 , 5) Su = Eepromrsonne(sysdw) Su = Mid(su , 10 , 5)

Locate 3 , 1 : Lcd "A " ; Sa ; Spc(2) ; "U " ; Su

Sysdx = Sysday() Sysdx = Sysdx + 2 Sysdw = Sysdx - Systemtageeprl Sysdw = Sysdw * 14 Sa = Eepromrsonne(sysdw) Sa = Mid(sa , 5 , 5) Su = Eepromrsonne(sysdw) Su = Mid(su , 10 , 5)

Locate 4 , 1 : Lcd "A " ; Sa ; Spc(2) ; "U " ; Su

...

Zuerst wird der erste im EEPROM gespeicherte String über die Funktion Eepromrsonne abgefragt

(siehe dazu auch Sonnenaufgänge und Sonnenuntergänge speichern und abrufen). Aus diesem

String wird der (System)Tag (gerechnet ab dem 01.01.2000) ermittelt (Systemtageeprl). Danach

wird der aktuelle Systemtag über die BASCOM-Funktion Sysday ermittelt. Über die Subtraktion

des aktuellen Systemtages mit dem ersten gespeicherten Systemtag (Sysdw = Sysdx - System-

tageeprl) erhält man nach der Multiplikation mit 14 (Sysdw = Sysdw * 14) die Speicheradresse

des heutigen Tages im EEPROM. Der gespeicherte String, der die Daten des heutigen Tages ent-

hält, wird über die Funktion Eepromrsonne ermittelt. Aus diesem String werden die Zeitangaben

für den Sonnenaufgang (Sa) und Sonnenuntergang (Su) ermittelt. Für die Anzeige der Daten des

nächsten Tages wird der aktuelle Systemtag mit 1 addiert (Sysdx = Sysdx + 1) , für den über-

nächsten Tag mit 2 (Sysdx = Sysdx + 2). Der Ausgabebildschirm ist in Abbildung 10 dargestellt.

Der nächste Ausgabebildschirm (Case 3)widmet sich der manuellen Einstellung von Wochentag,

Datum und Zeit (Abbildung 10). Auf eine ausführliche Erläuterung dieses Programmteils wird an

dieser Stelle verzichtet, da sich Datum und Zeit bequemer über das PC-Programm einstellen lassen

(siehe Zeiteinstellungen).

Abspielen einer MelodieOb eine und wann eine Melodie abgespielt wird, wird in der Hauptprogrammschleife ermittelt:

Dim Adresse_termine As WordDim Termine_alarml As LongDim Alarm_heute As BitDim Termin_heute As String * 16Dim Termine_mu As String * 1... Heute = Dayofyear(date$)... Adresse_termine = Getterminadresse(heute) Termine_alarml = Eepromrtermine_alarm(adresse_termine)

If Termine_alarml = Secofday() And Alarm_heute = 1 And Termine_mu <> "0" Then Call Play_music(termine_mu) End If...

- 32 -

Page 33: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Zuerst wird die Speicheradresse des heutigen Tages über die Funktion Getterminadresse ermit-

telt. Die Funktion Eepromrtermine_alarm ermittelt die Sekunde des Tages, an dem die Melodie

abgespielt werden soll. Mit der If-Anweisung wird ermittelt, ob alle Bedingungen für das Abspie-

len einer Melodie erfüllt sind. Den Variablen Alarm_heute und Termine_mu werden Werte durch

das Aufrufen der Funktionen Getterminadresse und Eepromrtermine_alarm zugewiesen. Die

aktuelle Sekunde des Tages wird über die BASCOM-Funktion Secofday ermittelt. Ist diese Se-

kundenzahl gleich der Sekunde, die im EEPROM gespeichert wurde und ist der heutige Tag ein be-

sonderer Tag und ist die Variable Termine_mu ungleich “0“, wird schließlich Call Play_mu-

sic(termine_mu) ausgeführt. Der Subroutine Play_music wird die Nummer der abzuspielenden

Melodie übergeben. Durch den Aufruf der Subroutine und der nachfolgenden Select Case...Case-

Anweisungen wir die Melodie abgespielt:

Lcd_bl Alias Portb.2Config Lcd_bl = Output

Config Portb.1 = OutputSpeaker Alias Portb.1...Dim Note As IntegerDim Laenge As IntegerDim Pause As Integer...Sub Play_music(song_nr As String * 1)

If Lcd_bl = 0 Then Lcd_bl = 1

Select Case Song_nr

Case "1"

For I = 0 To 55 Note = Lookup(i , Happyb) Incr I If Note = 0 Then Pause = Lookup(i , Happyb) Waitms Pause Else Laenge = Lookup(i , Happyb) Sound Speaker , Note , Laenge End If Next I

Case "2"

For I = 0 To 57 Note = Lookup(i , Merryx) Incr I If Note = 0 Then Pause = Lookup(i , Merryx) Waitms Pause Else Laenge = Lookup(i , Merryx) Sound Speaker , Note , Laenge End If Next I

End Select...Happyb:Data 65% , 587% , 65% , 587% , 147% , 523% , 131% , 587% , 175%Data 440% , 165% , 466% , 0% , 250% , 65% , 587% , 65% , 587% , 147%Data 523% , 131% , 587% , 196% , 392% , 175% , 440% , 0% , 250% , 65%Data 587% , 65% , 587% , 262% , 294% , 220% , 349% , 175% , 440% , 165%Data 466% , 147% , 523% , 0% , 125% , 117% , 330% , 117% , 330% , 220%Data 349% , 175% , 440% , 196% , 392% , 175% , 440%

- 33 -

Page 34: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Merryx:Data 147% , 523% , 196% , 392% , 98% , 392% , 110% , 349% , 98% , 392%Data 92% , 415% , 165% , 466% , 131% , 587% , 165% , 466% , 220% , 349%Data 110% , 349% , 124% , 311% , 110% , 349% , 98% , 392% , 185% , 415%Data 294% , 523% , 247% , 311% , 124% , 311% , 131% , 294% , 124% , 311%Data 110% , 349% , 196% , 392% , 165% , 466% , 73% , 523% , 73% , 523%Data 165% , 466% , 220% , 349% , 185% , 415% , 196% , 392%

Die Tonausgabe erledigt in BASCOM die Anweisung Sound mit den Variablen Speaker, Note,

Laenge. Speaker ist dabei ein Alias auf Portb.1 (siehe auch Schaltplan), die Werte für Note und

Laenge werden über Lookup aus einer Data-Tabelle gelesen. Die Variable I in der For-Next-An-

weisung gibt die Nummer des Wertes in der Tabelle an. Pausen (ohne Ton) werden über den Wert

Note = 0 ermöglicht. Im oberen Code-Abschnitt sind zwei Melodien angegeben. Insgesamt wären

9 möglich. Beim Abspielen einer Melodie wird die Hintergrundbeleuchtung des LCD-Moduls ein-

geschaltet. Die Berechnung der Werte für die Variablen Note und Laenge wird im nächsten Kapitel

erläutert.

Programmstruktur des PC-Programms (tool.au3)Die Programmierung des PC-Programms erfolgte mit AutoIt v3. Die Datenübertragung nutzt die

Bibliothek CommMG.au3 v2.8 von Martin Gibson. Die Programmoberfläche wurde mit Koda er-

stellt. Auf die Programmierung werde ich nachfolgend nicht so ausführlich eingehen, wie im voran-

gegangenen Kapitel. Der Programmcode ist (so denke ich) recht übersichtlich. Innerhalb der

Hauptprogrammschleife werden über Switch und Case jeweils nach bestimmten Aktionen (Maus-

klick) bestimmte Programmteile ausgeführt. Der Befehl _CommSendString sendet die im Kapitel

Empfang von Daten über das UART erwähnten Strings an die Kalenderuhr. Die Übertragung ist

relativ langsam (dafür sicher), kann aber je nach System und Anbindung auch schneller erfolgen.

Das muss man individuell austesten. Wenn die Kalenderuhr nur Datenmüll anzeigen sollte, erfolgt

die Übertragung jedenfalls zu schnell für das System. Daneben enthält das Programm Funktionen,

um Sonnenaufgänge bzw. Sonnenuntergänge und variable Feiertage, wie etwa die Osterfeiertage zu

berechnen.

Das Programm besteht aus 3 Tabs, die verschiedene Funktionen des Programms zusammenfassen.

Diese Funktionen werden nachfolgend kurz vorgestellt.

- 34 -

Page 35: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Datum, Uhrzeit, Einstellungen, Sonnenaufgänge und SonnenuntergängeNach dem Öffnen des Programms wird folgender Tab gezeigt:

Die Funktionen sind relativ selbsterklärend. Zuerst muss der passende COM-Port ausgewählt wer-

den. Die Einstellung kann getestet werden, in dem man einen Test-String sendet. Datum und Uhr-

zeit können zu Testzwecken auf jeden beliebigen Wert eingestellt und übertragen werden. Sind die

Häkchen bei Systemdatum und/oder Systemzeit gesetzt, wird das aktuelle Datum bzw. die aktuelle

Uhrzeit des PCs übertragen (siehe Zeiteinstellungen). Einstellungen zur Hintergrundbeleuchtung

und zur Zeitkorrektur können ebenfalls gesetzt und gesendet werden (siehe Weitere Einstellungen

und Steuerung der Hintergrundbeleuchtung des LCD-Moduls). Als letzte Funktion auf diesem Tab

können Sonnenaufgänge und Sonnenuntergänge an die Kalenderuhr gesendet werden (siehe

Sonnenaufgänge und Sonnenuntergänge speichern und abrufen). Im Programmcode des AutoIt-

Skripts müssen ggf. noch Breitengrad und Längengrad des Ortes angepasst werden.

- 35 -

Abbildung 12: Erstes Tab (Registerkarte) des PC-Programms. Die dem Screenshot hinzugefügten Erläuterungen zu den Steuerfunktionen sind Blau gedruckt.

Auswahl des COM-Ports Test-String sendenTEST: Gesendet & Empfangen 1234

Test-String senden

Datum und Zeit individuell einstellen Sommerzeit?Datum und Zeit individuell einstellen

Datum und Zeit des PCs

Einstellungen senden

TIME :18.04.1110122:27:40xxxxxx

Datum / Zeit senden Gesendeter String

ZeitkorrekturHintergrundbeleuchtung

Gesendeter String

Fortschrittsbalken

SETT: 100000000000000000000000x

Sonnena./u. senden

Page 36: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Geburtstage und FeiertageEine Liste von Geburtstagen und Feiertage kann im folgenden Tab angelegt, gespeichert und an die

Kalenderuhr übertragen werden:

Die Termine werden automatisch nach Datum (Tag und Monat) sortiert und können auf dem PC

gespeichert und wieder geladen werden. Feiertage hinzufügen fügt automatisch eine Reihe von

Feiertagen zur Terminliste hinzu. Das Datum der variablen Feiertage (Ostern, Pfingsten und Him-

melfahrt) wird vom PC-Programm jeweils vorher berechnet. Momentan kann nur zwischen 2 Me-

lodien bzw. keiner Melodie gewählt werden. Ohne größere Anpassung des Codes wären bis zu 9

Melodien möglich. Mit Senden wird die Terminliste schließlich übertragen (siehe

Geburtstagstermine und Feiertage (kurz Termine) speichern und abrufen).

- 36 -

Abbildung 13: Zweites Tab (Registerkarte) des PC-Programms. Die dem Screenshot hinzugefügten Erläuterungen zu den Steuerfunktionen sind Blau gedruckt.

(Geburts-)Datum(Geburts-)Zeit Geburtstag oder Feiertag?

Welche Melodie?

Ausgabetext (10 Zeichen)

Hinzufügen

Termine: Speichern / Laden / an die Kalenderuhr senden

Gesendeter String FortschrittsbalkenDATE3112201143200F0Silvester 15

Page 37: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Der MelodiegeneratorDas ist eine Funktion des Programms, die mit Hilfe des myAVR Boards Klingeltöne, wie sie etwa

um das Jahr 2000 herum üblich waren, wieder abspielbar macht. Auf der folgenden Internetseite

ist recht ausführlich erklärt, wie Noten für die BASCOM-Sound Anweisung umgesetzt werden

können:

http://www.mcselec.com/index.php?option=com_content&task=view&id=221&Itemid=57

Anhand der dort angegebenen Berechnungen, die hauptsächlich von der Frequenz des eingesetzten

Quarzes abhängen, können z.B. über eine Tabellenkalkulation für jede mögliche Note die entspre-

chenden Werte ausgerechnet werden.

Auf der nachfolgenden Internetseite finden sich z.B. noch jede Menge Klingeltöne, die einfach nur

in das Programmfenster des PC-Programms kopiert werden müssen:

http://www.xs4all.nl/~vbergen/ringtones/siemens/index_2000.html

- 37 -

Abbildung 14: Drittes Tab (Registerkarte) des PC-Programms. Die dem Screenshot hinzugefügten Erläuterungen zu den Steuerfunktionen sind Blau gedruckt.

Name der Melodie

Klingelton im Siemens (C25/S25/C35/S35/M35)-Format

BASCOM-Code

Page 38: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Im unteren Bereich steht der BASCOM-Code für den entsprechenden Klingelton bzw. die Melodie,

der nur noch in das Programm eingefügt werden muss. Die entsprechenden Variablen wurden zu

Programmbeginn deklariert.

FazitSoviel zum Projekt der Kalenderuhr. Fast alle Funktionen des myAVR Boards konnten genutzt

werden. Nur die beiden Potis sind noch frei, sowie ein Pin des ATmega.

Softwareseitig ist noch etwas Speicherplatz vorhanden, der mit weiteren Melodien oder mit

Programmcode gefüllt werden kann, auch das EEPROM hat noch Platz für Daten.

Der Programmcode bietet bestimmt dem einen oder anderen erfahrenen BASCOM-Programmierer

noch Ansätze zum optimieren. Funktionsfähig ist er jedenfalls und läuft so wie er ist, seit einiger

Zeit stabil.

Ohne Hilfe hätte ich die Kalenderuhr niemals zum laufen bekommen. An erster Stelle soll hier die

BASCOM-Hilfe stehen, die wirklich sehr umfangreich ist und schon viele Lösungsansätze bietet:

http://avrhelp.mcselec.com/index.html

Sehr hilfreich bei der Programmierung waren auch die folgenden Internetseiten:

http://halvar.at/elektronik/kleiner_bascom_avr_kurs/

http://www.rn-wissen.de/index.php/Kategorie:Quellcode_Bascom

http://www.rowalt.de/mc/index.htm

Die im PC-Programm verwendeten Funktionen sind, soweit übernommen, dort gekennzeichnet.

Hardwareseitig waren mir die von der Laser & Co. Solutions GmbH bereitgestellten Schaltpläne

eine große Hilfe, so wurde der Aufbau fast zum Kinderspiel.

Bei der Zusammenstellung von Texten und Abbildungen bin ich mit großer Sorgfalt vorgegangen.

Trotzdem kann ich Fehler nicht vollständig ausschließen. Für fehlerhafte Angaben und deren

Folgen kann ich weder irgendeine Haftung noch juristische Verantwortung übernehmen.

Sebastian Dechert

- 38 -

Page 39: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

BASCOM-QuellcodeDie wichtigsten Programmteile werden im Kapitel Programmierung ausführlich erklärt.

$regfile = "m168def.dat"$crystal = 3686400$baud = 9600

$lib "i2c_twi.lbx" 'Config Sda = Portc.4Config Scl = Portc.5Const Ds1307w = &HD0Const Ds1307r = &HD1Const Eeprw = &HA0Const Eeprr = &HA1

Config Timer1 = Timer , Prescale = 64On Timer1 Toggle_colonEnable Timer1Start Timer1

Enable Interrupts

Config Lcdpin = Pin , Rs = Portc.0 , E = Portc.1 , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , Db7 = Portd.7Config Lcd = 16 * 4Cursor = Off

Config Clock = UserConfig Date = Dmy , Separator = .

On Urxc OnrxdEnable Urxc

Config Pind.2 = 0Config Pind.3 = 0Portd.2 = 1Portd.3 = 1

Lcd_bl Alias Portb.2Config Lcd_bl = Output

Config Portb.1 = OutputSpeaker Alias Portb.1

Config Portc.2 -1 = OutputConfig Adc = Single , Prescaler = Auto , Reference = Avcc

Dim Licht As Word

Dim A As String * 10Dim B As String * 10Dim C As String * 10Dim D As IntegerDim E As IntegerDim F As IntegerDim G As IntegerDim H As IntegerDim I As IntegerDim J As IntegerDim K As IntegerDim Timestr As String * 10Dim Datestr As String * 10Dim Weekdaystr As String * 10Dim Colon_onoff As BitDim Dp_onoff As BitDim All_off As BitDim Weekday As ByteDim Weekdayst As String * 1Dim Cntb1 As IntegerDim Cntb2 As IntegerDim Exitbyte As Byte

- 39 -

Page 40: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Dim Stset As ByteDim Wtset As ByteDim Stsetst As String * 1Dim Wtsetst As String * 1

Dim L As String * 4Dim S As String * 30Dim Z(31) As Byte At S OverlayDim N As Byte

Dim Lcd_blst As String * 1Dim Lcd_blby(2) As Byte At Lcd_blst Overlay

Dim Plusminst As String * 1Dim Plusminby(2) As Byte At Plusminst Overlay

Dim Sekundest As String * 2Dim Sekundeby(3) As Byte At Sekundest Overlay

Dim Systemtag As LongDim Systemtagby(4) As Byte At Systemtag Overlay

Dim Sekdestages As LongDim Sekdestagesby(4) As Byte At Sekdestages Overlay

Dim Korrektur As LongDim Sekundelong As LongDim Sysd As LongDim Secd As LongDim Zeitkorrekturbit As Bit

Dim Sonnetagst As String * 14Dim Sonnetagby(14) As Byte At Sonnetagst Overlay

Dim Adresse_sonne As WordDim Adresse_sonne_high As ByteDim Adresse_sonne_low As ByteDim X As Byte

Dim Xx As WordDim Stageeprom As String * 14Dim Stageepromday As String * 4Dim Sahst As String * 2Dim Sarest As String * 3Dim Suhst As String * 2Dim Surest As String * 3Dim Sahstn As IntegerDim Suhstn As Integer

Dim Sa As String * 5Dim Su As String * 5

Dim Sysdx As LongDim Sysdw As Word

Dim Systemtageepr As String * 5Dim Systemtageeprl As Long

Dim Terminest As String * 28Dim Termineby(28) As Byte At Terminest Overlay

Dim Adresse_terminw As WordDim Adresse_termine As WordDim Adresse_termine14k As WordDim Adresse_termine_high14k As ByteDim Adresse_termine_low14k As Byte

Dim Termine_t As String * 2Dim Termine_m As String * 2Dim Termine_j As String * 2Dim Termine_x As String * 1Dim Termine_p As String * 10Dim Terminedatest As String * 8Dim Terminedate As IntegerDim Heute As IntegerDim Terminelcdst As String * 16Dim Maxadressest As String * 2

- 40 -

Page 41: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Dim Maxadressew As Word

Dim Schaltjahr As IntegerDim Termine_ij As Integer

Dim Termine_sek As String * 5Dim Termine_mu As String * 1Dim Termine_geburtstag As String * 1Dim Termine_alarmst As String * 6Dim Termine_alarml As LongDim Alarm_heute As BitDim Termin_heute As String * 16Dim Termine_jv As String * 4Dim Termine_jvi As IntegerDim Bdate As String * 2Dim Bdatei As IntegerDim Alter As IntegerDim Spaces As Integer

Dim Eepromrtermine_heute As String * 17Dim Dummy As Byte

Dim Note As IntegerDim Laenge As IntegerDim Pause As Integer

Declare Sub Happy_melDeclare Sub Merry_melDeclare Sub SetupDeclare Sub SetupweekdayDeclare Sub SetweekdayDeclare Sub SetdateDeclare Sub SettimeDeclare Sub SetuptimeDeclare Sub GotomainDeclare Sub Dst_onoffDeclare Sub Sun_risesetDeclare Sub DelnvramDeclare Sub WritenvramDeclare Sub Writenvram_settDeclare Sub ReadnvramDeclare Sub Setup1Declare Sub Lcd_blonoffDeclare Sub ZeitkorrekturDeclare Sub EepromwsonneDeclare Sub EepromwtermineDeclare Sub Play_music(song_nr As String)

Declare Function Eepromrsonne(byval Adresse_sonne As Word) As StringDeclare Function Eepromrtermine(byval Adresse_termine As Word) As StringDeclare Function Getterminadresse(byval Heute As Integer) As WordDeclare Function Getmaxadressetermine(byval Adresse_termine As Word) As WordDeclare Function Gettermintag(byval Adresse_termine As Word) As IntegerDeclare Function Eepromrtermine_alarm(byval Adresse_termine As Word) As Long

'Wochentag, Uhrzeit und Datum ohne Setup einstellen'Time$ = "00:04:00"'Date$ = "08:02:11"'Weekday = 1'Call Setweekday

Open "comb.0:9600,8,n,1" For Output As #1

Waitms 500

Print #1 , "v"; 'Reset der 7Seg.-AnzeigeClose #1

'Print #1 , "z"; 'Helligkeit der 7Seg.-Anzeige einstellen'Printbin #1 , 128 ;'Close #1

Waitms 500

- 41 -

Page 42: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Call Readnvram

Waitms 500'Call Delnvram 'NV-Ram der RTC loeschen

Cls

'#####################################################'# main loop #'#####################################################

Do

Call Dst_onoff Call Lcd_blonoff Call Zeitkorrektur

Heute = Dayofyear(date$)

Termine_j = Mid(date$ , 7 , 2) Termine_ij = Val(termine_j) Schaltjahr = Termine_ij Mod 4

If Schaltjahr = 0 And Heute >= 60 Then 'Schaltjahr Decr Heute End If

Adresse_termine = Getterminadresse(heute) Termine_alarml = Eepromrtermine_alarm(adresse_termine)

If Termine_alarml = Secofday() And Alarm_heute = 1 And Termine_mu <> "0" Then Call Play_music(termine_mu) Else End If

Timestr = Time$ Datestr = Date$ Weekdaystr = Lookupstr(weekday , Weekdays)

A = Mid(timestr , 1 , 2) B = Mid(timestr , 4 , 2) C = Mid(timestr , 7 , 2)

If Colon_onoff = 0 And Dp_onoff = 0 Then Print #1 , "w"; Printbin #1 , 0 ; 'Close #1 Elseif Colon_onoff = 1 And Dp_onoff = 0 And All_off = 0 Then Print #1 , "w"; Printbin #1 , 16 ; 'Close #1 Elseif Colon_onoff = 1 And Dp_onoff = 1 And All_off = 0 Then Print #1 , "w"; Printbin #1 , 2 ; Else Print #1 , "w"; Printbin #1 , 0; End If

If C > "30" And C < "35" Then All_off = 0 A = Mid(datestr , 1 , 2) B = Mid(datestr , 4 , 2) Dp_onoff = 1 Elseif C > "34" And C < "39" Then All_off = 1 A = "20" B = Mid(datestr , 7 , 2) Else Dp_onoff = 0 All_off = 0 End If

If A < "10" Then A = Mid(a , 2 , 1) Print #1 , "x" ; A ; B;

- 42 -

Page 43: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Else Print #1 , A ; B; End If

Select Case Cntb1

Case 0:

If Alarm_heute = 1 Then

Adresse_termine = Getterminadresse(heute) Termin_heute = Eepromrtermine(adresse_termine) Termin_heute = Mid(termin_heute , 7 , 10)

Termine_alarml = Eepromrtermine_alarm(adresse_termine) Termine_alarmst = Time(termine_alarml) Termine_alarmst = Left(termine_alarmst , 5)

Bdate = Mid(datestr , 7 , 2) Bdate = "20" + Bdate Termine_jvi = Val(termine_jv) Bdatei = Val(bdate) Alter = Bdatei - Termine_jvi

Locate 1 , 1 : Lcd "Heute " ; Termin_heute

If Termine_geburtstag = "G" Then Locate 2 , 1 : Lcd Termine_alarmst ; " " ; Termine_jv ; " " ; Alter ; " J" Else Locate 2 , 1 : Lcd Termine_alarmst ; Spc(11) End If

Locate 3 , 1 : Lcd Date$ ; Spc(8) Locate 4 , 1 : Lcd Time$ ; Spc(8)

Else

Spaces = Len(weekdaystr) Spaces = 16 - Spaces

Locate 1 , 1 : Lcd "Datum & Uhrzeit " Locate 2 , 1 : Lcd Weekdaystr ; Spc(spaces) Locate 3 , 1 : Lcd Date$ ; Spc(8) Locate 4 , 1 : Lcd Time$ ; Spc(8)

End If

Case 1:

Heute = Dayofyear(date$) Maxadressew = Getmaxadressetermine(0) Adresse_termine = Getterminadresse(heute) Eepromrtermine_heute = Eepromrtermine(adresse_termine)

If Adresse_termine > Maxadressew Then Adresse_termine = 0

Locate 1 , 1 : Lcd "Termine" ; Spc(9)

If Eepromrtermine_heute <> " " Then Locate 2 , 1 : Lcd Eepromrtermine(adresse_termine) Else Adresse_termine = 0 Locate 2 , 1 : Lcd Eepromrtermine(adresse_termine) End If

Adresse_termine = Adresse_termine + 27 Locate 3 , 1 : Lcd Eepromrtermine(adresse_termine) Adresse_termine = Adresse_termine + 27 Locate 4 , 1 : Lcd Eepromrtermine(adresse_termine)

Case 2:

Sa = Eepromrsonne(0) Systemtageepr = Mid(sa , 1 , 4) Systemtageeprl = Val(systemtageepr)

- 43 -

Page 44: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Sysdx = Sysday() Sysdw = Sysdx - Systemtageeprl Sysdw = Sysdw * 14 Sa = Eepromrsonne(sysdw) Sa = Mid(sa , 5 , 5) Su = Eepromrsonne(sysdw) Su = Mid(su , 10 , 5)

Locate 1 , 1 : Lcd "SonnenA/U 3 Tage" Locate 2 , 1 : Lcd "A " ; Sa ; Spc(2) ; "U " ; Su

Sysdx = Sysday() Sysdx = Sysdx + 1 Sysdw = Sysdx - Systemtageeprl Sysdw = Sysdw * 14 Sa = Eepromrsonne(sysdw) Sa = Mid(sa , 5 , 5) Su = Eepromrsonne(sysdw) Su = Mid(su , 10 , 5)

Locate 3 , 1 : Lcd "A " ; Sa ; Spc(2) ; "U " ; Su

Sysdx = Sysday() Sysdx = Sysdx + 2 Sysdw = Sysdx - Systemtageeprl Sysdw = Sysdw * 14 Sa = Eepromrsonne(sysdw) Sa = Mid(sa , 5 , 5) Su = Eepromrsonne(sysdw) Su = Mid(su , 10 , 5)

Locate 4 , 1 : Lcd "A " ; Sa ; Spc(2) ; "U " ; Su

Case 3:

Exitbyte = 0 Call Setup

End Select

Debounce Pind.2 , 0 , Button1 , Sub

If N > 30 Then

L = Left(s , 4)

Select Case L

Case "TEST":

N = 0 Print S;

Case "TIME":

N = 0 Time$ = Mid(s , 18 , 8) Date$ = Mid(s , 7 , 8) Weekdayst = Mid(s , 15 , 1) Weekday = Weekdayst Call Setweekday

Wtsetst = Mid(s , 16 , 1) Stsetst = Mid(s , 17 , 1)

Wtset = Val(wtsetst) Stset = Val(stsetst)

Call Writenvram

Case "SETT":

N = 0

Systemtag = Sysday() Sekdestages = Secofday()

- 44 -

Page 45: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Call Writenvram_sett Call Readnvram

Case "SUNS":

N = 0

Call Eepromwsonne

Case "DATE":

N = 0

Call Eepromwtermine

Case "CDAT":

N = 0

Adresse_terminw = 0

End Select

End If

Loop

'#####################################################'# UART Interuppt / Zeichen über UART empfangen #'#####################################################

Onrxd: Incr N Z(n) = UdrReturn

'#####################################################'# Datum & Uhrzeit einstellen / CASE 2 #'#####################################################

Setup:

Bitwait Pind.2 , Reset Lcd_bl = 1 Cls

Print #1 , "SEtx" ; Print #1 , "w"; Printbin #1 , 0 ;

While Cntb1 = 3 Locate 1 , 1 : Lcd "Datum & Uhrzeit" Locate 2 , 1 : Lcd " einstellen" Locate 3 , 1 : Lcd ">T1=Uebernehmen<" Locate 4 , 1 : Lcd ">T2=Einstellen<" Debounce Pind.2 , 0 , Gotomain , Sub Debounce Pind.3 , 0 , Setupweekday , Sub Wend

Return

'-------

Setupweekday:

Cls While Exitbyte = 0 Weekdaystr = Lookupstr(weekday , Weekdays) Locate 1 , 1 : Lcd "Wochentag einst." Locate 2 , 1 : Lcd Weekdaystr ; " " Debounce Pind.2 , 0 , Setupdate , Sub Debounce Pind.3 , 0 , Incrweekday , Sub Waitms 20

- 45 -

Page 46: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Wend

Return

'-------

Incrweekday:

Bitwait Pind.3 , Reset If Weekday < 7 Then Incr Weekday Else Weekday = 1

Return

'--------

Setupdate:

Call Setweekday

Locate 2 , 1 : Lcd "Tag" ; Spc(13)

A = Mid(datestr , 1 , 2) B = Mid(datestr , 4 , 2) C = Mid(datestr , 7 , 2)

D = Val(a) : E = Val(b) : F = Val(c)

While Exitbyte = 0 A = Str(d) A = Format(a , "00") B = Str(e) B = Format(b , "00") C = Str(f) C = Format(c , "00") Locate 1 , 1 : Lcd "Datum einst. " Locate 3 , 1 : Lcd A ; "." ; B ; "." ; C Debounce Pind.2 , 0 , Setupdmy , Sub Debounce Pind.3 , 0 , Incrdmy , Sub Waitms 20 Wend

Call Setuptime

Return

'-------

Incrdmy:

Bitwait Pind.3 , Reset

Select Case I

Case 0: Locate 2 , 1 : Lcd "Tag" ; Spc(13) If D < 31 Then Incr D Else D = 1 Case 1: Locate 2 , 1 : Lcd "Monat" ; Spc(11) If E < 12 Then Incr E Else E = 1 Case 2: Locate 2 , 1 : Lcd "Jahr" ; Spc(12) If F < 30 Then Incr F Else F = 11 End Select

Return

'--------

Setupdmy:

Bitwait Pind.2 , Reset

If I > 1 Then I = 0 _day = D : _month = E : _year = F Call Setdate Exitbyte = 1

- 46 -

Page 47: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Else Incr I End If

Return

'--------

Setuptime:

Locate 2 , 1 : Lcd "Stunde" ; Spc(10)

A = Mid(timestr , 1 , 2) B = Mid(timestr , 4 , 2) C = Mid(timestr , 7 , 2)

G = Val(a) : H = Val(b) : J = Val(c)

While Exitbyte = 1 A = Str(g) A = Format(a , "00") B = Str(h) B = Format(b , "00") C = Str(j) C = Format(c , "00") Locate 1 , 1 : Lcd "Uhrzeit einst. " Locate 4 , 1 : Lcd A ; ":" ; B ; ":" ; C Debounce Pind.2 , 0 , Setuphms , Sub Debounce Pind.3 , 0 , Incrhms , Sub Waitms 20 Wend

Return

'-------

Incrhms: Bitwait Pind.3 , Reset

Select Case I

Case 0: Locate 2 , 1 : Lcd "Stunde" ; Spc(10) If G < 23 Then Incr G Else G = 0 Case 1: Locate 2 , 1 : Lcd "Minute" ; Spc(10) If H < 59 Then Incr H Else H = 0 Case 2: Locate 2 , 1 : Lcd "Sekunde" ; Spc(9) If J < 59 Then Incr J Else J = 0 End Select

Return

'--------

Setuphms:

Bitwait Pind.2 , Reset

If I > 1 Then I = 0 _hour = G : _min = H : _sec = J Call Settime Call Gotomain Exitbyte = 2 Else Incr I End If

Return

'#####################################################'# ENDE Datum & Uhrzeit einstellen #'#####################################################

- 47 -

Page 48: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

'#####################################################################'# DS1307 Datum, Uhrzeit & Einstellungen auslesen und schreiben #'#####################################################################

Getdatetime: I2cstart I2cwbyte Ds1307w I2cwbyte 0 I2cstart I2cwbyte Ds1307r I2crbyte _sec , Ack I2crbyte _min , Ack I2crbyte _hour , Ack I2crbyte Weekday , Ack I2crbyte _day , Ack I2crbyte _month , Ack I2crbyte _year , Nack I2cstop _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour) _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)Return

Setdate: _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year) I2cstart I2cwbyte Ds1307w I2cwbyte 4 I2cwbyte _day I2cwbyte _month I2cwbyte _year I2cstop Waitms 10Return

Setweekday: I2cstart I2cwbyte Ds1307w I2cwbyte 3 I2cwbyte Weekday I2cstop Waitms 10Return

Settime: _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour) I2cstart I2cwbyte Ds1307w I2cwbyte 0 I2cwbyte _sec I2cwbyte _min I2cwbyte _hour I2cstop Waitms 10Return

Delnvram:For K = 8 To 63 I2cstart I2cwbyte Ds1307w I2cwbyte K I2cwbyte 00 I2cwbyte 00 I2cstop Waitms 10 NextReturn

Writenvram: I2cstart I2cwbyte Ds1307w I2cwbyte 8 I2cwbyte Stset I2cwbyte Wtset I2cstop Waitms 10Return

- 48 -

Page 49: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Writenvram_sett: I2cstart I2cwbyte Ds1307w I2cwbyte 10 I2cwbyte Z(7) I2cwbyte 0 I2cwbyte Z(8) I2cwbyte 0 I2cwbyte Z(9) I2cwbyte Z(10) I2cwbyte 0 I2cwbyte Systemtagby(1) I2cwbyte Systemtagby(2) I2cwbyte Systemtagby(3) I2cwbyte Systemtagby(4) I2cwbyte Sekdestagesby(1) I2cwbyte Sekdestagesby(2) I2cwbyte Sekdestagesby(3) I2cwbyte Sekdestagesby(4) I2cstop Waitms 10Return

Readnvram: I2cstart I2cwbyte Ds1307w I2cwbyte 8 I2cstart I2cwbyte Ds1307r I2crbyte Stset , Ack I2crbyte Wtset , Ack I2crbyte Lcd_blby(1) , Ack I2crbyte Lcd_blby(2) , Ack I2crbyte Plusminby(1) , Ack I2crbyte Plusminby(2) , Ack I2crbyte Sekundeby(1) , Ack I2crbyte Sekundeby(2) , Ack I2crbyte Sekundeby(3) , Ack I2crbyte Systemtagby(1) , Ack I2crbyte Systemtagby(2) , Ack I2crbyte Systemtagby(3) , Ack I2crbyte Systemtagby(4) , Ack I2crbyte Sekdestagesby(1) , Ack I2crbyte Sekdestagesby(2) , Ack I2crbyte Sekdestagesby(3) , Ack I2crbyte Sekdestagesby(4) , Nack I2cstopReturn

'#####################################################################'# Ende DS1307 Datum, Uhrzeit & Einstellungen auslesen und schreiben #'#####################################################################

'#####################################################################'# I2C EEPROM Sonnenauf/-untergangsdaten lesen und schreiben #'#####################################################################

Eepromwsonne:

N = 0

For X = 7 To 20

Adresse_sonne_high = High(adresse_sonne) Adresse_sonne_low = Low(adresse_sonne)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_sonne_high I2cwbyte Adresse_sonne_low I2cwbyte Z(x) I2cstop

Waitms 10

Incr Adresse_sonne

- 49 -

Page 50: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Next

If Adresse_sonne > 1399 Then Adresse_sonne = 0

Return

'------------------

Function Eepromrsonne(adresse_sonne As Word) As String * 14

For X = 1 To 14

Adresse_sonne_high = High(adresse_sonne) Adresse_sonne_low = Low(adresse_sonne)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_sonne_high I2cwbyte Adresse_sonne_low

I2cstart I2cwbyte Eeprr I2crbyte Sonnetagby(x) , Nack I2cstop

Incr Adresse_sonne

Next

Stageeprom = Sonnetagst Stageepromday = Left(stageeprom , 4)

If Stset = 1 And Wtset = 0 Then

Sahst = Mid(stageeprom , 5 , 2) Sarest = Mid(stageeprom , 7 , 3) Suhst = Mid(stageeprom , 10 , 2) Surest = Mid(stageeprom , 12 , 3)

Sahstn = Val(sahst) Incr Sahstn Sahst = Str(sahstn) Sahst = Format(sahst , "00")

Suhstn = Val(suhst) Incr Suhstn Suhst = Str(suhstn) Suhst = Format(suhst , "00")

Stageeprom = Stageepromday + Sahst + Sarest + Suhst + Surest

End If

Eepromrsonne = Stageeprom

End Function

'#####################################################################'# ENDE I2C EEPROM Sonnenauf/-untergangsdaten lesen und schreiben #'#####################################################################

'#####################################################################'# I2C EEPROM Termine lesen und schreiben #'#####################################################################

Eepromwtermine:

N = 0

For X = 5 To 31

Adresse_termine14k = 1400 + Adresse_terminw Adresse_termine_high14k = High(adresse_termine14k)

- 50 -

Page 51: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k I2cwbyte Z(x) I2cstop

Waitms 10 Incr Adresse_terminw

Next

Return

'------------------

Function Getterminadresse(heute As Integer) As Word

Maxadressew = Getmaxadressetermine(0)

For Adresse_termine = 0 To Maxadressew Step 27

Terminedate = Gettermintag(adresse_termine)

If Terminedate = Heute Then Alarm_heute = 1 Else Alarm_heute = 0

If Terminedate >= Heute Then Exit For

Next

Getterminadresse = Adresse_termine

End Function

'------------------

Function Gettermintag(adresse_termine As Word) As Integer

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

Incr Adresse_termine

Next

Termine_t = Left(terminest , 2) Termine_m = Mid(terminest , 3 , 2) Termine_j = Mid(terminest , 7 , 2) Termine_jv = Mid(terminest , 5 , 4) Terminedatest = Termine_t + "." + Termine_m + "." + Termine_j Terminedate = Dayofyear(terminedatest)

Termine_ij = Val(termine_j) Schaltjahr = Termine_ij Mod 4

If Schaltjahr = 0 And Terminedate > 59 Then 'Schaltjahr Decr Terminedate End If

Gettermintag = Terminedate

End Function

- 51 -

Page 52: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

'-------------------

Function Eepromrtermine(adresse_termine As Word) As String * 16

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

Incr Adresse_termine

Next

Termine_t = Left(terminest , 2) Termine_m = Mid(terminest , 3 , 2) Termine_p = Mid(terminest , 16 , 10)

Terminelcdst = Termine_t + "." + Termine_m + " " + Termine_p

If Termine_t = "00" Then Terminelcdst = Space(16)

Eepromrtermine = Terminelcdst

End Function

'------------------

Function Getmaxadressetermine(adresse_termine As Word) As Word

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

Incr Adresse_termine

Next

Maxadressest = Mid(terminest , 26 , 2) Maxadressew = Val(maxadressest) Maxadressew = Maxadressew * 27

Getmaxadressetermine = Maxadressew

End Function

'---------------------------

Function Eepromrtermine_alarm(adresse_termine As Word) As Long

For X = 1 To 27

Adresse_termine14k = 1400 + Adresse_termine

- 52 -

Page 53: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Adresse_termine_high14k = High(adresse_termine14k) Adresse_termine_low14k = Low(adresse_termine14k)

I2cstart I2cwbyte Eeprw I2cwbyte Adresse_termine_high14k I2cwbyte Adresse_termine_low14k

I2cstart I2cwbyte Eeprr I2crbyte Termineby(x) , Nack I2cstop

Incr Adresse_termine

Next

Termine_sek = Mid(terminest , 9 , 5) Termine_mu = Mid(terminest , 15 , 1) 'Musik abspielen? Termine_geburtstag = Mid(terminest , 14 , 1) 'Geburtstag oder Feiertag

Termine_alarml = Val(termine_sek)

Eepromrtermine_alarm = Termine_alarml

End Function

'#####################################################################'# ENDE I2C EEPROM Termine lesen und schreiben #'#####################################################################

'-------------------Toggle_colon: Timer1 = 7936 Toggle Colon_onoff If All_off = 1 Then Colon_onoff = 0Return

'------------------

Button1: Bitwait Pind.2 , Reset If Cntb1 = 3 Then Cntb1 = 0 Else Incr Cntb1 ClsReturn

'------------------

Button2: Bitwait Pind.3 , Reset If Cntb2 = 2 Then Cntb2 = 0 Else Incr Cntb2Return

'----------

Gotomain: Bitwait Pind.2 , Reset Cntb1 = 0 ClsReturn

'#####################################################'# LCD BL an/aus #'#####################################################

Lcd_blonoff:

Licht = Getadc(2) If Lcd_blst = "1" Then Lcd_bl = 1 Elseif Lcd_blst = "3" And Licht < 120 And _hour > 6 Then Lcd_bl = 1 Else Lcd_bl = 0 End If

- 53 -

Page 54: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Return

'#####################################################'# ENDE LCD BL an/aus #'#####################################################

'#####################################################'# Sommer-/Winterzeit einstellen #'#####################################################

Dst_onoff: If _month = 3 And _day > 24 And Weekday = 7 And _hour = 2 Then _hour = _hour + 1 Waitms 10 Call Settime Stset = 1 Wtset = 0 Waitms 10 Call Writenvram End If

If Wtset = 0 And _month = 10 And _day > 24 And Weekday = 7 And _hour = 3 Then _hour = _hour - 1 Waitms 10 Call Settime Wtset = 1 Stset = 0 Waitms 10 Call Writenvram End IfReturn

'#####################################################'# Ende Sommer-/Winterzeit einstellen #'#####################################################

'#####################################################'# Zeitkorrektur #'#####################################################

Zeitkorrektur:

Call Readnvram

Sysd = Sysday() Secd = Secofday() Sekundelong = Val(sekundest)

If Secd = 86399 Then Zeitkorrekturbit = 0

If Plusminst = "0" Then Korrektur = Sekdestages + Sekundelong If Plusminst = "1" Then Korrektur = Sekdestages - Sekundelong

If Sysd <> Systemtag And Secd = Sekdestages And Sekundelong <> 0 And Zeitkorrekturbit = 0 Then Time$ = Time(korrektur) Zeitkorrekturbit = 1 End IfReturn

'#####################################################'# Ende Zeitkorrektur #'#####################################################

'#####################################################'# Musik abspielen #'#####################################################

Sub Play_music(song_nr As String * 1)

If Lcd_bl = 0 Then Lcd_bl = 1

Select Case Song_nr

Case "1"

For I = 0 To 55 Note = Lookup(i , Happyb)

- 54 -

Page 55: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Incr I If Note = 0 Then Pause = Lookup(i , Happyb) Waitms Pause Else Laenge = Lookup(i , Happyb) Sound Speaker , Note , Laenge End If Next I

Case "2"

For I = 0 To 57 Note = Lookup(i , Merryx) Incr I If Note = 0 Then Pause = Lookup(i , Merryx) Waitms Pause Else Laenge = Lookup(i , Merryx) Sound Speaker , Note , Laenge End If Next I

End Select

End Sub

'#####################################################'# Ende Musik abspielen #'#####################################################

End

Weekdays:

Data "dummy" , "Montag" , "Dienstag" , "Mittwoch" , "Donnerstag" , "Freitag" , "Samstag" , "Sonntag"

Happyb:Data 65% , 587% , 65% , 587% , 147% , 523% , 131% , 587% , 175%Data 440% , 165% , 466% , 0% , 250% , 65% , 587% , 65% , 587% , 147%Data 523% , 131% , 587% , 196% , 392% , 175% , 440% , 0% , 250% , 65%Data 587% , 65% , 587% , 262% , 294% , 220% , 349% , 175% , 440% , 165%Data 466% , 147% , 523% , 0% , 125% , 117% , 330% , 117% , 330% , 220%Data 349% , 175% , 440% , 196% , 392% , 175% , 440%

Merryx:Data 147% , 523% , 196% , 392% , 98% , 392% , 110% , 349% , 98% , 392%Data 92% , 415% , 165% , 466% , 131% , 587% , 165% , 466% , 220% , 349%Data 110% , 349% , 124% , 311% , 110% , 349% , 98% , 392% , 185% , 415%Data 294% , 523% , 247% , 311% , 124% , 311% , 131% , 294% , 124% , 311%Data 110% , 349% , 196% , 392% , 165% , 466% , 73% , 523% , 73% , 523%Data 165% , 466% , 220% , 349% , 185% , 415% , 196% , 392%

- 55 -

Page 56: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

AutoIt-Quellcode;------------------------------------------------------------------------------------------; Tool fuer die Geburtstagskalenderuhr; Benutzt CommMG.au3 V2.8 von Martin Gibson; http://www.autoitscript.com/forum/topic/45842-serial-port-com-port-udf/; http://www.mosaiccgl.co.uk/AutoItDownloads/confirm.php?get=COMMGv2.zip;; Berechnung der Zeiten für Sonnenauf bzw. -untergang aus dem AutoIt Skript; IsItDark von JustinTime ; http://www.autoitscript.com/forum/topic/20946-script-to-determine-sunrisesunset-times-etc/;; Berechnung des Osterdatums nach der Formel von Lichtenberg; http://de.wikipedia.org/wiki/Gau%C3%9Fsche_Osterformel;-------------------------------------------------------------------------------------------

#include <ButtonConstants.au3>#include <ComboConstants.au3>#include <DateTimeConstants.au3>#include <EditConstants.au3>#include <GUIConstantsEx.au3>#include <StaticConstants.au3>#include <WindowsConstants.au3>#include <Array.au3>#include <CommMG.au3>;or if you save the commMg.dll in the @scripdir use #include @SciptDir & '\commmg.dll'#Include <GuiListBox.au3>#include <File.au3>#include <GuiListView.au3>#Include <Date.au3>

Const $longitude = 9.935556 ; GoettingenConst $latitude = 51.533889 ; GoettingenConst $TZ = 1 ;ZeitzoneConst $pi = 3.1415926535897932384626433832795Const $isdst=0$RADEG=180/$pi$DEGRAD=$pi/180$MyDocsFolder = "::{450D8FBA-AD25-11D0-98A8-0800361B1103}"

Local $avArray[8]$avArray[0] = "Dummy"$avArray[1] = "Sonntag"$avArray[2] = "Montag"$avArray[3] = "Dienstag"$avArray[4] = "Mittwoch"$avArray[5] = "Donnerstag"$avArray[6] = "Freitag"$avArray[7] = "Samstag"$time = @HOUR & ":" & @MIN & ":" & @SEC $date1 = @YEAR & "/" & @MON & "/" & @MDAY $date = @MDAY & "." & @MON & "." & stringmid(@YEAR,3,2) #Region ### START Koda GUI section ### Form=$Form1_1 = GUICreate("Tool", 629, 515, 138, 42)$Tab1 = GUICtrlCreateTab(24, 24, 585, 465)$TabSheet1 = GUICtrlCreateTabItem("Einstellungen")$Combo1 = GUICtrlCreateCombo("COM1", 64, 110, 81, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))GUICtrlSetData(-1, "COM2|COM3|COM4|COM5|COM6|COM7|COM8|COM9|COM10|COM11|COM12")$TimeInp = GUICtrlCreateDate($time, 184, 174, 94, 21, BitOR($DTS_UPDOWN,$DTS_TIMEFORMAT))$DateInp = GUICtrlCreateDate($date, 64, 174, 94, 21, BitOR($DTS_SHORTDATEFORMAT,$DTS_UPDOWN))$Sommerzeit = GUICtrlCreateCheckbox("Sommerzeit", 472, 166, 97, 25)GUICtrlSetState(-1, $GUI_CHECKED)$Sysdate = GUICtrlCreateCheckbox("Systemdatum", 472, 198, 97, 25)GUICtrlSetState(-1, $GUI_CHECKED)$Systime = GUICtrlCreateCheckbox("Systemzeit", 472, 230, 97, 25)GUICtrlSetState(-1, $GUI_CHECKED)$Label1 = GUICtrlCreateLabel("COM-Port", 160, 110, 50, 17)$Sendtime = GUICtrlCreateButton("Datum / Zeit senden", 64, 222, 121, 41)$Sendtest = GUICtrlCreateButton("Test", 264, 102, 65, 33)$Input2 = GUICtrlCreateInput("", 344, 110, 208, 22, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY))

- 56 -

Page 57: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

$Weekday = GUICtrlCreateCombo($avArray[@WDAY], 296, 174, 88, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))GUICtrlSetData(-1, "Sonntag|Montag|Dienstag|Mittwoch|Donnerstag|Freitag|Samstag")$Input4 = GUICtrlCreateInput("", 208, 230, 208, 22, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY));#####$Group1 = GUICtrlCreateGroup("LCD-Hintergrundbeleuchtung", 64, 289, 201, 57)$An = GUICtrlCreateRadio("An", 80, 313, 57, 17)GUICtrlSetState(-1, $GUI_CHECKED)$Aus = GUICtrlCreateRadio("Aus", 144, 313, 57, 17)$Auto = GUICtrlCreateRadio("Auto", 208, 313, 49, 17)GUICtrlCreateGroup("", -99, -99, 1, 1)$Group2 = GUICtrlCreateGroup("Korrektur", 312, 289, 225, 57)$plus = GUICtrlCreateRadio("+", 328, 313, 25, 18)GUICtrlSetState(-1, $GUI_CHECKED)$minus = GUICtrlCreateRadio("-", 368, 313, 25, 18)$Sekunden = GUICtrlCreateCombo("00", 402, 313, 51, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))GUICtrlSetData(-1, "01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30")$Label3 = GUICtrlCreateLabel("s in 24 h", 467, 313, 54, 18)GUICtrlCreateGroup("", -99, -99, 1, 1)$Sendsettings = GUICtrlCreateButton("Einstellungen senden", 64, 360, 121, 41, $BS_MULTILINE)$Input5 = GUICtrlCreateInput("", 210, 372, 208, 22, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY))$Sonnebutton = GUICtrlCreateButton(" Zeiten für Sonnenauf-/untergänge der nächsten 100 Tage senden ", 63, 420, 233, 41, $BS_MULTILINE)$ProgressSonne = GUICtrlCreateProgress(320, 424, 241, 33)$TabSheet2 = GUICtrlCreateTabItem("Geburtstage und Feiertage")$TDate = GUICtrlCreateDate($Date, 40, 72, 81, 22, 0)$Ttime = GUICtrlCreateDate($Time, 136, 72, 73, 22, BitOR($DTS_UPDOWN,$DTS_TIMEFORMAT))$TWh = GUICtrlCreateCombo("Geburtstag", 224, 72, 76, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))GUICtrlSetData(-1, "Feiertag")$TSound = GUICtrlCreateCombo("Keine Melodie", 312, 72, 105, 25, BitOR($CBS_DROPDOWN,$CBS_AUTOHSCROLL))GUICtrlSetData(-1, "Melodie 1|Melodie 2")$TInpEreig = GUICtrlCreateInput("Klaus", 432, 72, 113, 22)GUICtrlSetLimit(-1, 10)$Tadd = GUICtrlCreateButton("+", 560, 72, 25, 25)$TChange = GUICtrlCreateButton("Eintrag ändern", 432, 136, 113, 25)$TDel = GUICtrlCreateButton("Eintrag löschen", 432, 178, 113, 25)$TDelAll = GUICtrlCreateButton("Alle löschen", 432, 218, 113, 25)$TFeiertag = GUICtrlCreateButton("Feiertage hinzufügen", 432, 256, 113, 25)$Input3 = GUICtrlCreateInput("", 264, 449, 209, 22, BitOR($GUI_SS_DEFAULT_INPUT,$ES_READONLY))$TList = GUICtrlCreateListView("Datum|Uhrzeit|Anlass|Melodie|Text|#", 40, 121, 377, 314)GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 70)GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 70)GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 60)GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 3, 60)GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 4, 90)GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 5, 0)$TSave = GUICtrlCreateButton("Speichern", 40, 448, 65, 25)$TLoad = GUICtrlCreateButton("Laden", 112, 448, 65, 25)$TSend = GUICtrlCreateButton("Senden", 184, 448, 65, 25)$TProgress = GUICtrlCreateProgress(480, 448, 113, 22)$TabSheet3 = GUICtrlCreateTabItem("Melodiegenerator")$MelodieName = GUICtrlCreateInput("Melodie", 52, 64, 169, 22)$Eingabe = GUICtrlCreateEdit("", 52, 97, 521, 137)$Ausgabe = GUICtrlCreateEdit("", 52, 309, 521, 161, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY)) ;$Generate = GUICtrlCreateButton("Code generieren", 200, 248, 217, 41)$DelAll = GUICtrlCreateButton("Alles löschen", 445, 248, 113, 41)GUICtrlCreateTabItem("")GUISetState(@SW_SHOW)#EndRegion ### END Koda GUI section ###

GUICtrlSetState($Systime, $GUI_CHECKED)GUICtrlSetState($Sysdate, $GUI_CHECKED)

- 57 -

Page 58: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

While 1 Local $sportSetError $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Sommerzeit Case $Sysdate Case $Systime Case $combo1 $setport = StringReplace(GUICtrlRead($Combo1), 'COM', '') _CommSetPort($setport, $sportSetError, 9600, 8, 0, 1, 0) if $sportSetError = '' Then MsgBox(262144, 'Verbunden','Verbunden mit COM' & $setport) Else MsgBox(262144, 'Verbindungsfehler', $sportSetError) EndIf $mode = 1 Case $Sendtest sleep (1000) GUICtrlSetData($input2, "") _CommSendString("TEST: Gesendet & Empfangen 1234") sleep (1000) $instr = _CommGetString() if $instr <> "" then GUICtrlSetData($input2, $instr) else GUICtrlSetData($input2, "Falscher Port oder Fehler") endif Case $Sendtime $a=GUICtrlRead($Sommerzeit) $b=GUICtrlRead($Sysdate) $c=GUICtrlRead($Systime) if $a=1 then $wt=0 $st=1 elseif $a <> 1 then $wt=1 $st=0 endif if $b=1 then $day=@MDAY $month=@MON $year2=stringmid(@YEAR,3,4) $date=$day & "." & $month & "." & $year2 & weekday2number($avArray[@WDAY]) else $date=stringmid(GUICtrlRead($DateInp),1,6) & stringmid(GUICtrlRead($DateInp),9,2) & weekday2number(GUICtrlRead($Weekday)) EndIf if $c=1 then $time=@HOUR &":"& @MIN &":"& @SEC else $time=GUICtrlRead($TimeInp) EndIf $Sendstr="TIME :" & $date & $wt & $st & $time & "xxxxxx" _CommSendString($Sendstr) sleep (1000) $instr = _CommGetString() if $instr <> "" then GUICtrlSetData($input4, $instr) else GUICtrlSetData($input4, "") GUICtrlSetData($input4, $sendstr) endif Case $Sendsettings if GUICtrlRead($an)=1 then $LCD=1

- 58 -

Page 59: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

if GUICtrlRead($aus)=1 then $LCD=2 if GUICtrlRead($auto)=1 then $LCD=3 if GUICtrlRead($plus)=1 then $plusminus=0 if GUICtrlRead($minus)=1 then $plusminus=1 if Number(GUICtrlRead($Sekunden)) < 10 then $null=0 else $null = "" EndIf $Sendstrsett = "SETT: " & $LCD & $plusminus & GUICtrlRead($Sekunden) & "00000000000000000000x" _CommSendString($Sendstrsett) sleep (1000) GUICtrlSetData($input5,$Sendstrsett) Case $Sonnebutton $b=GUICtrlRead($Sysdate) if $b=1 then $day = ( 367 * (@YEAR) - int((7 * ((@YEAR) + (((@MON) + 9) / 12))) / 4) + int((275 * (@MON)) / 9) + (@MDAY) - 730530) else $Jahr=stringmid(GUICtrlRead($DateInp),7,4) $Monat=stringmid(GUICtrlRead($DateInp),4,2) $MTag=stringmid(GUICtrlRead($DateInp),1,2) $day = ( 367 * ($Jahr) - int((7 * (($Jahr) + ((($Monat) + 9) / 12))) / 4) + int((275 * ($Monat)) / 9) + ($MTag) - 730530) EndIf For $Iday =0 to 99 $nday=$day+$Iday $SunTimes=SunTimes($nday,0) $Sendstrsonne="SUNS: " & $nday-1 & $SunTimes & "0000000000x" _CommSendString($Sendstrsonne) GUICtrlSetData($input5,$Sendstrsonne) GUICtrlSetData($ProgressSonne, $Iday+1) sleep(500) Next Case $Tadd _GUICtrlListView_RegisterSortCallBack($TList) $TerminT=StringLeft(GUICtrlRead($Tdate),2) $TerminM=StringMid(GUICtrlRead($Tdate),4,2) $TerminDatum = $TerminM & $TerminT GUICtrlCreateListViewItem(GUICtrlRead($Tdate) & "|" & GUICtrlRead($Ttime) & "|" & GUICtrlRead($Twh) & "|" & GUICtrlRead($TSound) & "|" & StringFormat("%-10s",GUICtrlRead($TInpEreig)) &"|" & $TerminDatum, $TList) _GUICtrlListView_SortItems($TList,5) _GUICtrlListView_UnRegisterSortCallBack ($TList) Case $TChange $line = _GUICtrlListView_GetItemTextString($TList,Number(_GUICtrlListView_GetSelectedIndices($TList))) $linesplit = StringSplit($line,"|") $date_tchange=StringMid($linesplit[1],7,4) & "/" & StringMid($linesplit[1],4,2) & "/" & StringMid($linesplit[1],1,2) GUICtrlSetData($Tdate,$date_tchange) GUICtrlSetData($Ttime,$date_tchange & " " & $linesplit[2]) GUICtrlSetData($Twh, $linesplit[3]) GUICtrlSetData($Tsound, $linesplit[4]) GUICtrlSetData($TInpEreig, $linesplit[5]) _GUICtrlListView_DeleteItem($TList,Number(_GUICtrlListView_GetSelectedIndices($TList))) Case $Tdel _GUICtrlListView_DeleteItemsSelected($TList) Case $TDelall _GUICtrlListView_DeleteAllItems($TList) Case $TFeiertag _GUICtrlListView_RegisterSortCallBack($TList) GUICtrlCreateListViewItem("01.01." & @YEAR & "|" & "00:00:01" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Neujahr " & "|" & "0101", $TList)

- 59 -

Page 60: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

GUICtrlCreateListViewItem("01.05." & @YEAR & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "1. Mai " & "|" & "0501", $TList) GUICtrlCreateListViewItem("08.05." & @YEAR & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Muttertag " & "|" & "0508", $TList) GUICtrlCreateListViewItem("03.10." & @YEAR & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "D. Einheit" & "|" & "1003", $TList) GUICtrlCreateListViewItem("24.12." & @YEAR & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Heiligab. " & "|" & "1224", $TList) GUICtrlCreateListViewItem("25.12." & @YEAR & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "1. Weihft." & "|" & "1225", $TList) GUICtrlCreateListViewItem("26.12." & @YEAR & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "2. Weihft." & "|" & "1226", $TList) GUICtrlCreateListViewItem("31.12." & @YEAR & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Silvester " & "|" & "1231", $TList) $Osterdatum=Ostern(@YEAR) $OsternT=StringLeft($Osterdatum,2) $OsternM=StringMid($Osterdatum,4,2) $OsternMT=$OsternM & $OsternT If (@MON & @MDAY) > $OsternMT then $Osterdatum=Ostern(@YEAR+1) $OsternT=StringLeft($Osterdatum,2) $OsternM=StringMid($Osterdatum,4,2) $OsternY=StringMid($Osterdatum,7,4) $OsternMT=$OsternM & $OsternT GUICtrlCreateListViewItem($Osterdatum & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Ostersonn." & "|" &$OsternMT, $TList) Dim $KarfreitagY, $KarfreitagM, $KarfreitagT $Karfreitag= _DateToDayValue ($OsternY, $OsternM, $OsternT) -2 $Karfreitag= _DayValueToDate ($Karfreitag, $KarfreitagY, $KarfreitagM, $KarfreitagT) $Karfreitag = $KarfreitagT & "." & $KarfreitagM & "." & $KarfreitagY $KarfreitagMT = $KarfreitagM & $KarfreitagT GUICtrlCreateListViewItem($Karfreitag & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Karfreitag" & "|" & $KarfreitagMT, $TList) Dim $OstermontagY, $OstermontagM, $OstermontagT $Ostermontag = _DateToDayValue ($OsternY, $OsternM, $OsternT) + 1 $Ostermontag = _DayValueToDate ($Ostermontag, $OstermontagY, $OstermontagM, $OstermontagT) $Ostermontag = $OstermontagT & "." & $OstermontagM & "." & $OstermontagY $OstermontagMT = $OstermontagM & $OstermontagT GUICtrlCreateListViewItem($Ostermontag & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Ostermon. " & "|" &$OstermontagMT, $TList) Dim $HimmelfahrtY, $HimmelfahrtM, $HimmelfahrtT $Himmelfahrt= _DateToDayValue ($OsternY, $OsternM, $OsternT) + 39 $Himmelfahrt= _DayValueToDate ($Himmelfahrt, $HimmelfahrtY, $HimmelfahrtM, $HimmelfahrtT) $Himmelfahrt = $HimmelfahrtT & "." & $HimmelfahrtM & "." & $HimmelfahrtY $HimmelfahrtMT = $HimmelfahrtM & $HimmelfahrtT GUICtrlCreateListViewItem($Himmelfahrt & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Vatertag " & "|" & $HimmelfahrtMT, $TList) Dim $PfingstsonntagY, $PfingstsonntagM, $PfingstsonntagT $Pfingstsonntag= _DateToDayValue ($OsternY, $OsternM, $OsternT) + 49 $Pfingstsonntag= _DayValueToDate ($Pfingstsonntag, $PfingstsonntagY, $PfingstsonntagM, $PfingstsonntagT) $Pfingstsonntag = $PfingstsonntagT & "." & $PfingstsonntagM & "." & $PfingstsonntagY $PfingstsonntagMT = $PfingstsonntagM & $PfingstsonntagT GUICtrlCreateListViewItem($Pfingstsonntag & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Pfingstso." & "|" & $PfingstsonntagMT, $TList) Dim $PfingstmontagY, $PfingstmontagM, $PfingstmontagT

- 60 -

Page 61: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

$Pfingstmontag = _DateToDayValue ($OsternY, $OsternM, $OsternT) + 50 $Pfingstmontag = _DayValueToDate ($Pfingstmontag, $PfingstmontagY, $PfingstmontagM, $PfingstmontagT) $Pfingstmontag = $PfingstmontagT & "." & $PfingstmontagM & "." & $PfingstmontagY $PfingstmontagMT = $PfingstmontagM & $PfingstmontagT GUICtrlCreateListViewItem($Pfingstmontag & "|" & "12:00:00" & "|" & "Feiertag" & "|" & "Keine Melodie" & "|" & "Pfingstmo." & "|" & $PfingstmontagMT, $TList) _GUICtrlListView_SortItems($TList,5) _GUICtrlListView_UnRegisterSortCallBack ($TList) Case $TSave $TerminFile=FileSaveDialog ( "Termine speichern", $MyDocsFolder, "Text (*.txt)" , 2,"termine.txt" ) Fileopen($TerminFile,2) For $iIndex = 0 to _GUICtrlListView_GetItemCount($TList)-1 FileWriteLine ($TerminFile, _GUICtrlListView_GetItemTextString($TList, $iIndex)) Next FileClose($TerminFile) Case $TLoad $TerminFile=FileOpenDialog ( "Termine öffnen", $MyDocsFolder, "Text (*.txt)" , 2,"termine.txt" ) _GUICtrlListView_DeleteAllItems($TList) $endoffile = _FileCountLines($TerminFile) Fileopen($TerminFile,0) For $I = 1 to $endoffile $line = FileReadLine($TerminFile,$I) $linesplit=StringSplit($line,"|") GUICtrlCreateListViewItem($linesplit[1] & "|" & $linesplit[2] & "|" & $linesplit[3] & "|" & $linesplit[4] & "|" & $linesplit[5] &"|" & $linesplit[6], $TList) Next FileClose($TerminFile) Case $Tsend _CommSendString("CDATxxxxxxxxxxxxxxxxxxxxxxxxxxx") Sleep(500) For $iIndex = 0 to _GUICtrlListView_GetItemCount($TList)-1 $TerminString=_GUICtrlListView_GetItemTextString($TList, $iIndex) $TerminSec=Secofday(Stringmid($TerminString,12,8)) $TerminSec=StringFormat("%5s",$TerminSec) $TerminSec=StringReplace($TerminSec," ","0") $TerminString=StringReplace($TerminString,".","",2) $TerminString=StringReplace($TerminString,":","",2) $TerminString=StringReplace($TerminString,"|","") $TerminString=StringReplace($TerminString,"Geburtstag","G") $TerminString=StringReplace($TerminString,"Feiertag","F") $TerminString=StringReplace($TerminString,"Keine Melodie","0") $TerminString=StringReplace($TerminString,"Melodie ","") $TerminString="DATE" & StringLeft($TerminString, 8) & $TerminSec & StringMid($TerminString,15,12) $TerminString=StringFormat("%-29s",$TerminString) $TerminString=$TerminString & StringFormat("%2s",string(_GUICtrlListView_GetItemCount($TList))) _CommSendString($TErminString) Sleep(1000) GUICtrlSetData($Input3,$TerminString) GUICtrlSetData($TProgress, (100*($iIndex+1))/(_GUICtrlListView_GetItemCount($TList))) Next Sleep(1000) _CommSendString("DATE000000000000000000000000000") Sleep(1000) _CommSendString("DATE000000000000000000000000000") Sleep(1000) Case $Generate ;http://www.mcselec.com/index.php?option=com_content&task=view&id=221&Itemid=57 ;http://www.xs4all.nl/~vbergen/ringtones/siemens/index_2000.html $AusgabeText=""

- 61 -

Page 62: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

GUICtrlSetData($Ausgabe, $AusgabeText="") Dim $AusgabeText Dim $Zaehler Dim $mP $Zaehler=0 Dim $C1[2][6] = [["C1","C1(1)","C1(1/2)","C1(1/4)","C1(1/8)","C1(1/16)"],[1174,523,262,131,65,33]] Dim $Cis1[2][6] = [["Cis1","Cis1(1)","Cis1(1/2)","Cis1(1/4)","Cis1(1/8)","Cis1(1/16)"],[1108,555,277,139,69,35]] Dim $D1[2][6] = [["D1","D1(1)","D(1/2)","D(1/4)","D(1/8)","D(1/16)"],[1046,587,294,147,73,37]] Dim $Dis1[2][6] = [["Dis1","Dis1(1)","Dis(1/2)","Dis(1/4)","Dis(1/8)","Dis(1/16)"],[987,622,311,156,78,39]] Dim $E1[2][6] = [["E1","E1(1)","E1(1/2)","E1(1/4)","E1(1/8)","E1(1/16)"],[932,659,330,165,82,41]] Dim $F1[2][6] = [["F1","F1(1)","F1(1/2)","F1(1/4)","F1(1/8)","F1(1/16)"],[880,698,349,175,87,44]] Dim $Fis1[2][6] = [["Fis1","Fis1(1)","Fis1(1/2)","Fis1(1/4)","Fis1(1/8)","Fis1(1/16)"],[830,740,370,185,92,46]] Dim $G1[2][6] = [["G1","G1(1)","G1(1/2)","G1(1/4)","G1(1/8)","G1(1/16)"],[784,784,392,196,98,49]] Dim $Gis1[2][6] = [["Gis1","Gis1(1)","Gis1(1/2)","Gis1(1/4)","Gis1(1/8)","Gis1(1/16)"],[740,830,415,208,104,52]] Dim $A1[2][6] = [["A1","A1(1)","A1(1/2)","A1(1/4)","A1(1/8)","A1(1/16)"],[698,880,440,220,110,55]] Dim $Ais1[2][6] = [["Ais1","Ais1(1)","Ais1(1/2)","Ais1(1/4)","Ais1(1/8)","Ais1(1/16)"],[659,932,466,233,117,58]] Dim $B1[2][6] = [["B1","B1(1)","B1(1/2)","B1(1/4)","B1(1/8)","B1(1/16)"],[622,988,494,247,124,62]] Dim $H1[2][6] = [["H1","H1(1)","H1(1/2)","H1(1/4)","H1(1/8)","H1(1/16)"],[622,988,494,247,124,62]] Dim $C2[2][6] = [["C2","C2(1)","C2(1/2)","C2(1/4)","C2(1/8)","C2(1/16)"],[587,1047,523,262,131,65]] Dim $Cis2[2][6] = [["Cis2","Cis2(1)","Cis2(1/2)","Cis2(1/4)","Cis2(1/8)","Cis2(1/16)"],[554,1109,554,277,139,69]] Dim $D2[2][6] = [["D2","D2(1)","D2(1/2)","D2(1/4)","D2(1/8)","D2(1/16)"],[523,1175,587,294,147,73]] Dim $Dis2[2][6] = [["Dis2","Dis2(1)","Dis2(1/2)","Dis2(1/4)","Dis2(1/8)","Dis2(1/16)"],[494,1244,622,311,156,78]] Dim $E2[2][6] = [["E2","E2(1)","E2(1/2)","E2(1/4)","E2(1/8)","E2(1/16)"],[466,1318,659,330,165,82]] Dim $F2[2][6] = [["F2","F2(1)","F2(1/2)","F2(1/4)","F2(1/8)","F2(1/16)"],[440,1396,698,349,175,87]] Dim $Fis2[2][6] = [["Fis2","Fis2(1)","Fis2(1/2)","Fis2(1/4)","Fis2(1/8)","Fis2(1/16)"],[415,1480,740,370,185,92]] Dim $G2[2][6] = [["G2","G2(1)","G2(1/2)","G2(1/4)","G2(1/8)","G2(1/16)"],[392,1567,784,392,196,98]] Dim $Gis2[2][6] = [["Gis2","Gis2(1)","Gis2(1/2)","Gis2(1/4)","Gis2(1/8)","Gis2(1/16)"],[370,1661,831,415,208,104]] Dim $A2[2][6] = [["A2","A2(1)","A2(1/2)","A2(1/4)","A2(1/8)","A2(1/16)"],[349,1760,880,440,220,110]] Dim $Ais2[2][6] = [["Ais2","Ais2(1)","Ais2(1/2)","Ais2(1/4)","Ais2(1/8)","Ais2(1/16)"],[330,1862,932,466,233,117]] Dim $B2[2][6] = [["B2","B2(1)","B2(1/2)","B2(1/4)","B2(1/8)","B2(1/16)"],[311,1976,988,494,247,124]] Dim $H2[2][6] = [["H2","H2(1)","H2(1/2)","H2(1/4)","H2(1/8)","H2(1/16)"],[311,1976,988,494,247,124]] Dim $C3[2][6] = [["C3","C3(1)","C3(1/2)","C3(1/4)","C3(1/8)","C3(1/16)"],[294,2090,1047,523,262,131]] Dim $Cis3[2][6] = [["Cis3","Cis3(1)","Cis3(1/2)","Cis3(1/4)","Cis3(1/8)","Cis3(1/16)"],[277,2218,1109,554,277,139]] Dim $D3[2][6] = [["D3","D3(1)","D3(1/2)","D3(1/4)","D3(1/8)","D3(1/16)"],[262,2345,1175,587,294,147]] Dim $Dis3[2][6] = [["Dis3","Dis3(1)","Dis3(1/2)","Dis3(1/4)","Dis3(1/8)","Dis3(1/16)"],[247,2487,1245,622,311,156]] Dim $E3[2][6] = [["E3","E3(1)","E3(1/2)","E3(1/4)","E3(1/8)","E3(1/16)"],[233,2637,1319,659,330,165]] Dim $F3[2][6] = [["F3","F3(1)","F3(1/2)","F3(1/4)","F3(1/8)","F3(1/16)"],[220,2793,1397,698,349,175]] Dim $Fis3[2][6] = [["Fis3","Fis3(1)","Fis3(1/2)","Fis3(1/4)","Fis3(1/8)","Fis3(1/16)"],[208,2954,1480,740,370,185]] Dim $G3[2][6] = [["G3","G3(1)","G3(1/2)","G3(1/4)","G3(1/8)","G3(1/16)"],[196,3135,1568,784,392,196]] Dim $Gis3[2][6] = [["Gis3","Gis3(1)","Gis3(1/2)","Gis3(1/4)","Gis3(1/8)","Gis3(1/16)"],[185,3321,1661,831,415,208]] Dim $A3[2][6] = [["A3","A3(1)","A3(1/2)","A3(1/4)","A3(1/8)","A3(1/16)"],

- 62 -

Page 63: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

[179,3432,1720,880,440,220]] Dim $Ais3[2][6] = [["Ais3","Ais3(1)","Ais3(1/2)","Ais3(1/4)","Ais3(1/8)","Ais3(1/16)"],[165,3724,1865,932,466,233]] Dim $B3[2][6] = [["B3","B3(1)","B3(1/2)","B3(1/4)","B3(1/8)","B3(1/16)"],[156,3938,1976,988,494,247]] Dim $H3[2][6] = [["H3","H3(1)","H3(1/2)","H3(1/4)","H3(1/8)","H3(1/16)"],[156,3938,1976,988,494,247]] Dim $P[2][6] = [["P","P(1)","P(1/2)","P(1/4)","P(1/8)","P(1/16)"],[0,2000,1000,500,250,125]] $MelodieText=GUICtrlRead($Eingabe) $MelodieText=StringReplace($MelodieText," ","x") $MelodieText=StringSplit($MelodieText,"x") For $m=1 to $MelodieText[0] $mP=$m+1 For $C= 0 to 5 If $MelodieText[$m] = $C1[0][$C] Then $AusgabeText=$AusgabeText & $C1[1][$C] & "%, " & $C1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Cis1[0][$C] Then $AusgabeText=$AusgabeText & $Cis1[1][$C] & "%, " & $Cis1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $D1[0][$C] Then $AusgabeText=$AusgabeText & $D1[1][$C] & "%, " & $D1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Dis1[0][$C] Then $AusgabeText=$AusgabeText & $Dis1[1][$C] & "%, " & $Dis1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $E1[0][$C] Then $AusgabeText=$AusgabeText & $E1[1][$C] & "%, " & $E1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $F1[0][$C] Then $AusgabeText=$AusgabeText & $F1[1][$C] & "%, " & $F1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Fis1[0][$C] Then $AusgabeText=$AusgabeText & $Fis1[1][$C] & "%, " & $Fis1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $G1[0][$C] Then $AusgabeText=$AusgabeText & $G1[1][$C] & "%, " & $G1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Gis1[0][$C] Then $AusgabeText=$AusgabeText & $Gis1[1][$C] & "%, " & $Gis1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $A1[0][$C] Then $AusgabeText=$AusgabeText & $A1[1][$C] & "%, " & $A1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Ais1[0][$C] Then $AusgabeText=$AusgabeText & $Ais1[1][$C] & "%, " & $Ais1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $B1[0][$C] Then $AusgabeText=$AusgabeText & $B1[1][$C] & "%, " & $B1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $H1[0][$C] Then $AusgabeText=$AusgabeText & $H1[1][$C] & "%, " & $H1[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $C2[0][$C] Then $AusgabeText=$AusgabeText & $C2[1][$C] & "%, " & $C2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Cis2[0][$C] Then $AusgabeText=$AusgabeText & $Cis2[1][$C] & "%, " & $Cis2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf

- 63 -

Page 64: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

If $MelodieText[$m] = $D2[0][$C] Then $AusgabeText=$AusgabeText & $D2[1][$C] & "%, " & $D2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Dis2[0][$C] Then $AusgabeText=$AusgabeText & $Dis2[1][$C] & "%, " & $Dis2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $E2[0][$C] Then $AusgabeText=$AusgabeText & $E2[1][$C] & "%, " & $E2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $F2[0][$C] Then $AusgabeText=$AusgabeText & $F2[1][$C] & "%, " & $F2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Fis2[0][$C] Then $AusgabeText=$AusgabeText & $Fis2[1][$C] & "%, " & $Fis2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $G2[0][$C] Then $AusgabeText=$AusgabeText & $G2[1][$C] & "%, " & $G2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Gis2[0][$C] Then $AusgabeText=$AusgabeText & $Gis2[1][$C] & "%, " & $Gis2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $A2[0][$C] Then $AusgabeText=$AusgabeText & $A2[1][$C] & "%, " & $A2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Ais2[0][$C] Then $AusgabeText=$AusgabeText & $Ais2[1][$C] & "%, " & $Ais2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $B2[0][$C] Then $AusgabeText=$AusgabeText & $B2[1][$C] & "%, " & $B2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $H2[0][$C] Then $AusgabeText=$AusgabeText & $H2[1][$C] & "%, " & $H2[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $C3[0][$C] Then $AusgabeText=$AusgabeText & $C3[1][$C] & "%, " & $C3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Cis3[0][$C] Then $AusgabeText=$AusgabeText & $Cis3[1][$C] & "%, " & $Cis3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $D3[0][$C] Then $AusgabeText=$AusgabeText & $D3[1][$C] & "%, " & $D3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Dis3[0][$C] Then $AusgabeText=$AusgabeText & $Dis3[1][$C] & "%, " & $Dis3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $E3[0][$C] Then $AusgabeText=$AusgabeText & $E3[1][$C] & "%, " & $E3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $F3[0][$C] Then $AusgabeText=$AusgabeText & $F3[1][$C] & "%, " & $F3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Fis3[0][$C] Then $AusgabeText=$AusgabeText & $Fis3[1][$C] & "%, " & $Fis3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $G3[0][$C] Then $AusgabeText=$AusgabeText & $G3[1][$C] & "%, " & $G3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Gis3[0][$C] Then

- 64 -

Page 65: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

$AusgabeText=$AusgabeText & $Gis3[1][$C] & "%, " & $Gis3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $A3[0][$C] Then $AusgabeText=$AusgabeText & $A3[1][$C] & "%, " & $A3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $Ais3[0][$C] Then $AusgabeText=$AusgabeText & $Ais3[1][$C] & "%, " & $Ais3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $B3[0][$C] Then $AusgabeText=$AusgabeText & $B3[1][$C] & "%, " & $B3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $H3[0][$C] Then $AusgabeText=$AusgabeText & $H3[1][$C] & "%, " & $H3[1][0] & "%, " $Zaehler=$Zaehler+1 EndIf If $MelodieText[$m] = $P[0][$C] Then $AusgabeText=$AusgabeText & $P[1][0] & "%, " & $P[1][$C] & "%, " $Zaehler=$Zaehler+1 EndIf Next Next $PrgCode = "For I = 0 To " & $Zaehler*2-1 & Chr(13) & Chr(10) & " Note = Lookup(I, " & GUICtrlRead($MelodieName) & ")" & Chr(13) & Chr(10) $PrgCode = $PrgCode & " Incr I" & Chr(13) & Chr(10) $PrgCode = $PrgCode & " If Note = 0 Then" & Chr(13) & Chr(10) & " Pause = Lookup(I ," & GUICtrlRead($MelodieName) & ")" & Chr(13) & Chr(10) $PrgCode = $PrgCode & " Waitms Pause" & Chr(13) & Chr(10) & " Else" & Chr(13) & Chr(10) $PrgCode = $PrgCode & " Laenge = Lookup(I, " & GUICtrlRead($MelodieName) & ")" & Chr(13) & Chr(10) $PrgCode = $PrgCode & " Sound Speaker , Note , Laenge " & Chr(13) & Chr(10) & " End If" & Chr(13) & Chr(10) & "Next I" & Chr(13) & Chr(10) & Chr(13) & Chr(10) $PrgCode = $PrgCode & GUICtrlRead($MelodieName) & ":" & Chr(13) & Chr(10) & "Data " $AusgabeText = StringTrimRight ($AusgabeText,2) GUICtrlSetData($Ausgabe,$PrgCode & $AusgabeText) Case $DelAll $AusgabeText="" GUICtrlSetData($Ausgabe, "") GUICtrlSetData($Eingabe, "") EndSwitch WEnd Func weekday2number (ByRef $Weekday) if $Weekday = "Montag" then $Weekdayn=1 if $Weekday = "Dienstag" then $Weekdayn=2 if $Weekday = "Mittwoch" then $Weekdayn=3 if $Weekday = "Donnerstag" then $Weekdayn=4 if $Weekday = "Freitag" then $Weekdayn=5 if $Weekday = "Samstag" then $Weekdayn=6 if $Weekday = "Sonnabend" then $Weekdayn=6 if $Weekday = "Sonntag" then $Weekdayn=7 Return $Weekdayn Endfunc Func SecOfday (ByRef $Ttime) $SecOfDay=Number(StringLeft($Ttime,2))*60*60+Number(StringMid ($Ttime,4,2))*60+Number(StringMid ($Ttime,7,2)) Return $SecOfDay EndFunc Func Ostern (Byref $Jahr) ;Ostern Wikipedia nach Lichtenberg $K = $Jahr / 100 $M = Int(15 + (3*$K + 3) / 4 - (8*$K + 13) / 25) $S = Int(2 - (3*$K + 3) / 4) $A = Mod($Jahr, 19) $D = Mod((19*$A + $M), 30)

- 65 -

Page 66: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

$R = Int(($D + $A / 11) / 29) $OG = 21 + $D - $R $SZ = 7 - Mod(Int(($Jahr + $Jahr / 4 + $S)), 7) $OE = 7 - Mod(($OG - $SZ), 7) $OS = $OG + $OE If $OS > 31 then $OS=$OS -31 $Monat="04" Else $Monat="03" EndIf $OS=StringFormat("%02s",$OS) $Osterdatum = $OS &"."& $Monat& "." & $Jahr Return $Osterdatum EndFunc ; aus IsItDark von JustinTime Func SunTimes ($day, $isdst)Dim $day, $n, $i, $w, $m, $l, $e, $e1, $a, $xv, $yv, $v, $xs, $ys, $xe, $ecl, $lonsun, $ye, $ze, $ra, $dec, $h, $r, $E1Dim $GMST0, $UT_Sun_in_south, $LHA, $hour_rise, $hour_set, $min_rise, $min_set

; Orbital elements of the Sun: $N = 0.0 $i = 0.0 $w = 282.9404 + 0.0000470935 * $day $a = 1.000000 $e = 0.016709 - 0.000000001151 * $day $M = 356.0470 + 0.9856002585 * $day $M = rev($M) $ecl = 23.4393 - 0.0000003563 * $day $L = $w + $M if ($L < 0 OR $L > 360) then $L = rev($L) Endif; position of the Sun $E1 = $M + $e*(180/$pi) * sind($M) * ( 1.0 + $e * cosd($M) ) $xv = cosd($E1) - $e $yv = sqrt(1.0 - $e * $e) * sind($E1) $v = atan2d($yv, $xv) $r = sqrt($xv * $xv + $yv * $yv) $lonsun = $v + $w if ($lonsun < 0 OR $lonsun > 360) then $lonsun = rev($lonsun) Endif $xs = $r * cosd($lonsun) $ys = $r * sind($lonsun) $xe = $xs $ye = $ys * cosd($ecl) $ze = $ys * sind($ecl) $RA = atan2d($ye, $xe) $Dec = atan2d($ze, (sqrt(($xe * $xe)+($ye * $ye)))) $h=-0.833 $GMST0 = $L + 180 if ($GMST0 < 0 OR $GMST0 > 360) then $GMST0 = rev($GMST0) Endif $UT_Sun_in_south = ( $RA - $GMST0 - $longitude ) / 15.0 if ($UT_Sun_in_south < 0) then $UT_Sun_in_south=$UT_Sun_in_south + 24 Endif $LHA= (sind($h) - (sind($latitude) * sind($Dec)))/(cosd($latitude) * cosd($Dec)) if ($LHA > -1 AND $LHA < 1) then $LHA=acosd($LHA)/15 else $SunTimes = "No sunrise;No sunset" return $suntimes

- 66 -

Page 67: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Endif $hour_rise=$UT_Sun_in_south - $LHA $hour_set=$UT_Sun_in_south + $LHA $min_rise=int(($hour_rise-int($hour_rise)) * 60) $min_set=int(($hour_set-int($hour_set)) * 60) $hour_rise=(int($hour_rise) + ($TZ + $isdst)) $hour_set=(int($hour_set) + ($TZ + $isdst)) if ($min_rise < 10) then $min_rise = StringRight("0000" & $min_rise, 2) Endif if ($min_set < 10) then $min_set = StringRight("0000" & $min_set, 2) Endif ;slightly modified the formatting of the following line format from original version. if $hour_rise < 10 then $null=0 else $null = "" EndIf $SunTimes = $null & $hour_rise & ":" & $min_rise & $hour_set & ":" & $min_set Return $SuntimesEndFunc ;Now all the Support FuncsFunc sind($qqq) $sind = sin(($qqq) * $DEGRAD) return $sindEndFuncFunc cosd($qqq) $cosd = cos(($qqq) * $DEGRAD) return $cosdEndFuncFunc tand($qqq) $tand = tan(($qqq) * $DEGRAD) return $tandEndFuncFunc atand($qqq) $atand = ($RADEG * atan($qqq)) return $atandEndFuncFunc asind($qqq) $asind = ($RADEG * asin($qqq)) return $asindEndFuncFunc acosd($qqq) $acosd = ($RADEG * acos_new($qqq)) return $acosdEndFuncFunc atan2d ($qqq, $qqq1) $atan2d = ($RADEG * atan2($qqq, $qqq1)) return $atan2dEndFuncFunc rev($qqq) Dim $x $x = ($qqq - int($qqq/360.0) * 360.0) if ($x <= 0) then $x = $x + 360 Endif $rev = $xreturn $revEndFuncFunc atan2($ys,$xs); from the Draw Arrows tip; @ http://www.devx.com/upload/free/features/VBPJ/techtips/techtips11.pdf; by —Jim Deutch, Syracuse, New York

- 67 -

Page 68: Die Geburtstagskalenderuhr - projekte.myavr.deprojekte.myavr.de/doku/projekt_pa_sebastian_dechert.pdf · Eine Echtzeituhr (DS1307, Dallas) liefert Datum und Uhrzeit. Das batteriegepufferte

Dim $theta If $xs <> 0 Then $theta = Atan($ys / $xs) If $xs < 0 Then $theta = $theta + $pi Endif Else If $ys < 0 Then $theta = 3 * $pi / 2 ;90 Else $theta = $pi / 2 ;270 Endif Endif $atan2 = $thetareturn $atan2EndFuncFunc acos_new($x) $acos_new = Atan(-$X / Sqrt(-$X * $X + 1)) + 2 * Atan(1) return $acos_newEndFunc

- 68 -