Problem mit Alarm bei Selbstbau-Uhr
Hallo!
Im Rahmen eines größeren Bastelprojekts (Langzeitbetrieb einer Kamera mit PC über Jahre) habe ich ständig Probleme mit der (eingebauten) Wochenzeitschaltuhr.
Diese ist ja leider nicht mit DCF77 ausgerüstet (hab ich noch nie gesehen) und darum muß ich ständig auf der Lauer sein.
Jeden Monat einmal die Zeit korrigieren und jedes Halbjahr die Umstellung Sommer/Winterzeit. Und bei Stromausfall korrigieren.
Das wurde mir jetzt zuviel und deshalb muß jetzt eine "richtige" Uhr her.
Das Programm für die Uhr selbst ist schon fertig und läuft tadellos. Ich habe sie - als Anfänger - aus verschiedenen Codeschnipseln
und etwas eigenem dazu zusammengesetzt. Ein I2C-RTC-Modul steuert die BASCOM-Softclock und wird von einem ELV-DFC77-Modul
genau gehalten.
Ohne Schaltausgang nützt sie mir allerdings garnichts, denn die Uhr soll ja täglich einmal den PC aufwecken, nach 5 Minuten ein
Programm starten und den PC wieder schlafen legen.
Also hab ich versucht, das mal selbst zu entwickeln. Der jetzige Stand ist:
Die Umschaltung Stellen - Alarm EIN funktioniert.
Beim Stellen kann ich auch Stunde und Minute erhöhen.
Beim Zurückschalten auf Alarm Ein geht aber die Anzeige wieder auf Null.
Das sagt mir: die Zahlen im LCD bleiben nicht erhalten. Warum? Keine Ahnung...
Hier noch der Code:
Code:
Locate 4 , 1 : Lcd "Alarm"
'--------------- Taster - Schleife --------------------------------
Do
If Ta_stellen = 0 Then
Waitms 10
While Ta_stellen = 0
NOP ' Debouncing
Nop
Wend
Goto Set_alarm
End If
Locate 4 , 13 : Lcd " Ein "
Loop
'-------------- Stellen - Schleife ------------------------------------------
Set_alarm:
Do
If Ta_min = 0 Then
Al_min = Al_min + 1 'Minute stellen
If Al_min = 60 Then Al_min = 0
Waitms 200
End If
If Ta_std = 0 Then
Al_std = Al_std + 1 'Stunde stellen
If Al_std = 24 Then Al_std = 0
Waitms 200
End If
'-----------------------------------------------------------------------------------------
If Ta_stellen = 0 Then Exit Do
'-----------------------------------------------------------------------------------------
Locate 4 , 13 : Lcd "Stellen"
Locate 4 , 7 : Lcd Al_std ; ":" ; Al_min
Loop
Return
End
Wie schon ober geschrieben, ist das nur ein Teil einer ganzen Uhrsteuerung.
Es sollte möglichst keinen Timer oder Interrupt brauchen.
Das muß doch gehen!
Den Rest, also den Uhrzeit-Vergleich und den Ausgang zum Pc kann ich wieder selbst.
Vielleicht ist es nur eine Kleinigkeit, die ich mangels Erfahrung übersehe.
Joachim
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für die schnelle Rückmeldung!
Dieser "Codeschnipsel" ist eigentlich schon das ganze Programm bzw. Teilprogramm für den Alarm.
Vom Uhrenprogramm wird nur die aktuelle Zeitinformation übernommen (_hour, _min) und mit der eingestellten Zeit verglichen.
Das ist das Ganze:
Code:
$regfile = "m8def.dat"
$crystal = 9830400
$hwstack = 60
$swstack = 32
$framesize = 64
$include "INIT_LCD20x4.bas" 'LCD an Port D
Pinb = &B11000000 'B 0,1 = Enc; 2,3,4,5 = Taster
Portb = &B00111111
Dim Al_min As Byte , Al_std As Byte
Enc_a Alias Pinb.0
Enc_b Alias Pinb.1
Ta_std Alias Pinb.2
Ta_min Alias Pinb.3
Ta_stellen Alias Pinb.4
Ta_enc Alias Pinb.5
Locate 4 , 1 : Lcd "Alarm"
'--------------- Taster - Schleife --------------------------------
Do
If Ta_stellen = 0 Then
Waitms 10
While Ta_stellen = 0
NOP ' Debouncing
Nop
Wend
Goto Set_alarm
End If
Locate 4 , 13 : Lcd " Ein "
Loop
'-------------- Stellen - Schleife ------------------------------------------
Set_alarm:
Do
If Ta_min = 0 Then
Al_min = Al_min + 1 'Minute stellen
If Al_min = 60 Then Al_min = 0
Waitms 200
End If
If Ta_std = 0 Then
Al_std = Al_std + 1 'Stunde stellen
If Al_std = 24 Then Al_std = 0
Waitms 200
End If
'-----------------------------------------------------------------------------------------
If Ta_stellen = 0 Then Exit Do
'-----------------------------------------------------------------------------------------
Locate 4 , 13 : Lcd "Stellen"
Locate 4 , 7 : Lcd Al_std ; ":" ; Al_min
Loop
'Return
End
'(
'-------------- LCD rechtsbündige Anzeige ------------------------------------
Locate 4 , 7 ' Anzeige Al_Std
If Al_Std < 10 Then Lcd " " ; Al_Std Else Lcd Al_Std ; " "
Locate 4 , 9 ' Anzeige Al_Min
If Al_Min < 10 Then Lcd ":0" ; Al_Min Else Lcd ":" ; Al_Min
Waitms 50
')
Ich hab den RETURN mal rausgenommen, dann bleibt er wie vorhersehbar bei "Stellen" stehen.
Die Frage ist für mich also: Wie komme ich aus der Stellroutine, ohne den Inhalt von Al_std und Al_min
zu verlieren?
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo!
Ich hänge mich jetzt mal an meinen Thread selbst dran, weil ich noch eine Frage zur selben Sache habe.
Erstmal kann ich mitteilen, daß dank eurer Hilfe die Uhr nun soweit läuft.
Zum Einstellen der Alarmzeit bin ich aber von den Tastern abgegangen, weil mid das doch zu aufwendig war, die werden
ja nur ein-zweimal im Jahr gebraucht.
Dazu kommt noch der Nachteil, das ich damit nur vorwärts stellen könnte.
Also hab ich mir bei ebay diese Drehencoder besorgt:
Anhang 26726
Die gabs 15 Stück für 8 €, haben einen versenkbaren Drehknopf und einen Kontakt beim rausdrücken. Nach vielen Versuchen fand
ich auch einen Programmschnipsel, der für diese Type sehr gut läuft:
Code:
$regfile = "m8def.dat"
$crystal = 9830400
$hwstack = 40
$swstack = 16
$framesize = 32
$include "D:\PROG\INIT_LCD20x4.bas"
Deflcdchar 1 , 2 , 6 , 14 , 31 , 14 , 6 , 2 , 32 'Pfeil nach links
Portc = &B111 'Pullup
Enc_a Alias Pinc.1
Enc_b Alias Pinc.0
Ta_alarm Alias Pinc.2
Dim Al_min As Integer 'INT wegen Wert kleiner Null !
Dim Al_std As Integer
Dim Zw As Byte 'Zustandswechsel z.B.: &b0011_0010
Config Timer0 = Timer , Prescale = 1024 '= ~10MHz= ~0,1µs * 1024= 0,1ms
On Timer0 Enc_int 'Interrupt
Timer0 = 246 'Timerstartwert:10; ~0,1ms * 10= 1ms
Enable Timer0
Enable Interrupts
Locate 1 , 2 : Lcd "Encoder mit Timer0"
Locate 4 , 1 : Lcd "Alarmzeit: " '11 Zeichen
If Ta_alarm = 0 Then
Do
Locate 4 , 12
If Al_std < 10 Then Lcd " " ; Al_std Else Lcd Al_std ' ; " "
Locate 4 , 14
If Al_min < 10 Then Lcd ":0" ; Al_min Else Lcd ":" ; Al_min ; " "
Locate 4 , 17 : Lcd " " ; Chr(1) ; " "
If Al_min < 0 Then
Al_min = 59
Al_std = Al_std - 1
End If
If Al_std < 0 Then Al_std = 23
If Al_min > 59 Then
Al_min = 0
Al_std = Al_std + 1
End If
If Al_std > 23 Then Al_std = 0
'-------Ab hier die Alarmzeit mit GOSUB in RTC speichern !-------------
If Ta_alarm = 1 Then Exit Do
Loop
End If
Enc_int:
Timer0 = 246 'Timerstartwert
Zw.0 = Enc_a 'Zustandswechsel
Zw.1 = Enc_b
Select Case Zw
Case &H0_2 : Incr Al_min
Case &H0_1 : Decr Al_min
End Select
Zw.4 = Zw.0
Zw.5 = Zw.1
Return
Damit stelle ich die Minuten, die Stunden folgen selbst. Vorwärts und rückwärts. Das kenne ich so von meinem Herd, ist ganz praktisch.
Aber jetzt kommt die Frage!
Bei Übereinstimmung von Uhrzeit und Alarmzeit will ich ja ein Signal bekommen, und zwar in der Zeit einstellbar im Bereich eine
bis ca. 5 Sekunden. Das kann ich ja nicht in die Main-Schleife einbauen, weil die würde ja dann stehenbleiben!
Bei einer SUB passiert dasselbe, bis zum RETURN bleibt alles stehen.
Wie kann ich zu diesem "Unterprogramm" springen, ohne den normalen Ablauf zu unterbrechen?
Also zur gegebenen Zeit die 5 Sekunden nebenher ablaufen lassen, ohne weitere Aktionen.
Das kann ich nicht rausfinden, trotz intensiver Hilfesuche.
Vielleicht kann mir da jemand auf die Sprünge helfen! Ich hänge hier noch das ganze Uhrenprogramm dran, das könnte
Ja hilfreich sein:
Code:
$regfile = "m8def.dat"
$crystal = 9830400
$hwstack = 64
$swstack = 32
$framesize = 64
$include "D:\PROG\INIT_LCD20x4.bas" 'LCD an Port D
'------------------------------------------ 'für RTC ------------------------------------------------------------
$lib "I2C_TWI.lbx"
Config Sda = Portc.4
Config Scl = Portc.5
Config Twi = 100000
I2cinit
Dim Ds_weekday As Byte , Ds_day As Byte , Ds_month As Byte , Ds_year As Byte
Dim Ds_sec As Byte , Ds_min As Byte , Ds_hour As Byte
'-------------------------------------------------- 'für DCF ---------------------------------------------------
Config Dcf77 = Pinc.3 , Timer = 1
Config Date = Dmy , Separator = .
Config Pinb.3 = Output 'DCF - Status - LED
Config Pinb.4 = Output ' DCF - Blink - LED
'---------------------------------------für ENC ---------------------------------------------------------------
Portc = &B111 ' Pullups
Enc_a Alias Pinc.1
Enc_b Alias Pinc.0
Ta_alarm Alias Pinc.2 'Taste Alarmzeit stellen EIN - AUS
Deflcdchar 1 , 2 , 6 , 14 , 31 , 14 , 6 , 2 , 32 'Pfeil nach links
Dim Al_min As Integer , Al_std As Integer 'nötig wegen <Null !
Dim V_al_min As Byte , V_al_std As Byte 'für Anzeige
Dim Zw As Byte 'Zustandswechsel z.B.: &b0011_0010
Config Timer0 = Timer , Prescale = 1024 '= ~10MHz= ~0,1µs * 1024= 0,1ms
On Timer0 Enc_int 'Interrupt
Timer0 = 246 'Timerstartwert:10; ~0,1ms * 10= 1ms
Enable Timer0
Stop Timer0
Enable Interrupts
'---------------------------------------- für Ausgang --------------------------------------------------------
Config Pinb.0 = Input 'Schalter Alarm EIN - AUS
Portb.0 = 1 'Pullup
Config Pinb.1 = Output 'grüne LED für Ausgang EIN
'--------------------------MAIN - SCHLEIFE----------------------------------------------------------------
Do
If Pinc.3 = 1 Then Portb.4 = 1 Else Portb.4 = 0 ' LED für DCF-Impuls
If Dcf_status.7 = 1 Then Portb.3 = 1 Else Portb.3 = 0 'LED für DCF-Status
Gosub Show_clock ' Anzeige vom RCT - Speicher holen
Gosub Show_alarm ' Anzeige vom RCT - Speicher holen
If Ta_alarm = 0 Then Gosub Al_stellen
Loop
'------------------------------------------------------------------------------------------------------------------
Al_stellen:
Do
Start Timer0
Locate 3 , 12
If Al_std < 10 Then Lcd "0" ; Al_std Else Lcd Al_std ' ; " "
Locate 3 , 14
If Al_min < 10 Then Lcd ":0" ; Al_min Else Lcd ":" ; Al_min ; " "
Locate 3 , 17 : Lcd " " ; Chr(1) ; " "
If Al_min < 0 Then
Al_min = 59
Al_std = Al_std - 1
End If
If Al_std < 0 Then Al_std = 23
If Al_min > 59 Then
Al_min = 0
Al_std = Al_std + 1
End If
If Al_std > 23 Then Al_std = 0
Gosub Alarm_speichern
If Ta_alarm = 1 Then
Stop Timer0
Exit Do
End If
Loop
'----------TIMER 0 Interrupt für ENC -------------------------------------------------
Enc_int:
Timer0 = 246 'Timerstartwert für 1ms
Zw.0 = Enc_a 'Zustandswechsel
Zw.1 = Enc_b
Select Case Zw
Case &H0_2 : Incr Al_min 'bei jedem zweiten Tick
Case &H0_1 : Decr Al_min 'dito
End Select
Zw.4 = Zw.0
Zw.5 = Zw.1
Return
'----------RTC Uhrzeit und Datum auslesen und anzeigen----------------------
Show_clock:
I2cstart
I2cwbyte 208
I2cwbyte 0
I2cstop
I2cstart
I2cwbyte 209
I2crbyte Ds_sec , Ack
I2crbyte Ds_min , Ack
I2crbyte Ds_hour , Ack
I2crbyte Ds_weekday , Ack
I2crbyte Ds_day , Ack
I2crbyte Ds_month , Ack
I2crbyte Ds_year , Nack
I2cstop
Gosub Rtc_stellen
'------------------ANZEIGE-----------------------------------------------------
Locate 1 , 1 : Lcd "Uhrzeit: " ; Bcd(ds_hour) ; ":" ; Bcd(ds_min) ; ":" ; Bcd(ds_sec)
Locate 2 , 1 : Lcd "Datum: " ; Lookupstr(ds_weekday , Wochentag) ; ", "
Locate 2 , 12 : Lcd Bcd(ds_day) ; "." ; Bcd(ds_month) ; "." ; Bcd(ds_year)
'------------------ANZEIGE-----------------------------------------------------
Return
'-------------RTC Alarmzeit auslesen und anzeigen--------------------------
Show_alarm:
I2cstart
I2cwbyte 208
I2cwbyte 10
I2cstart
I2cwbyte 209
I2crbyte V_al_std , Ack
I2crbyte V_al_min , Nack
I2cstop
Locate 3 , 1 : Lcd "Alarmzeit: " ; Bcd(v_al_std) ; ":" ; Bcd(v_al_min) ; " "
If Pinb.0 = 0 Then
Locate 3 , 18 : Lcd "Aus"
Else
Locate 3 , 18 : Lcd "Ein"
End If
Return
'----------------- Uhrzeit in RTC speichern
Rtc_speichern:
Ds_sec = Makebcd(ds_sec)
Ds_min = Makebcd(ds_min)
Ds_hour = Makebcd(ds_hour)
Ds_day = Makebcd(ds_day)
Ds_month = Makebcd(ds_month)
Ds_year = Makebcd(ds_year)
Ds_weekday = Makebcd(ds_weekday)
I2cstart
I2cwbyte 208
I2cwbyte 0
I2cwbyte Ds_sec
I2cwbyte Ds_min
I2cwbyte Ds_hour
I2cwbyte Ds_weekday
I2cwbyte Ds_day
I2cwbyte Ds_month
I2cwbyte Ds_year
I2cstop
Return
'-------------------Alarmzeit in RTC speichern
Alarm_speichern:
V_al_min = Makebcd(al_min)
V_al_std = Makebcd(al_std)
I2cstart
I2cwbyte 208
I2cwbyte 10
I2cwbyte V_al_std
I2cwbyte V_al_min
I2cstop
Return
'----------------- RTC nach DCF77 stellen
Rtc_stellen:
If Dcf_status.7 = 1 And Ds_sec <> _sec Then
Ds_hour = _hour
Ds_min = _min
Ds_sec = _sec
Ds_weekday = _weekday
Ds_day = _day
Ds_month = _month
Ds_year = _year
Gosub Rtc_speichern
End If
Return
'-----------------AUSGANG - BAUSTELLE ! ---------------------------------------------
If Ta_alarm = 1 And Pinb.0 = 1 Then Gosub Ausgang
Ausgang:
If V_al_std = Ds_hour And V_al_min = Ds_min Then Portb.1 = 1
Wait 5
Portb = 1
Wochentag:
Data " " , "Mo" , "Di" , "Mi" , "Do" , "Fr" , "Sa" , "So"
Joachim
Liste der Anhänge anzeigen (Anzahl: 2)
Bezüglich der Nachstellung hab ich eigentlich keine Probleme. Du hast ja NTP, da ist das etwas einfacher, aber es geht auch so.
Die RTC wird ja maximal jede Minute aktualisiert (wenn das DCF77-Statusbit einen kompletten Satz Daten empfangen hat).
Und da der Speicher der RTC SRAM ist, gibt es eigentlich kein Problem.
Aber das Problem des Alarmausgangs habe ich inzwischen gelöst. Mit Deiner Methode kam ich nicht zurecht, es wollte nicht laufen.
Nun ist der Ausgang in einer Sub, die von der Hauptschleife abgerufen wird:
Code:
Do ' MAIN - SCHLEIFE
Locate 1 , 16
If Dcf_pin = 1 Then Lcd "+" Else Lcd " " 'DCF-Impuls
Locate 1 , 6
If Dcf_status.7 = 1 Then Lcd "*" Else Lcd " " 'DCF-Status
Gosub Show_clock ' Anzeige vom RCT - Speicher holen
Gosub Show_alarm ' Anzeige vom RCT - Speicher holen
Gosub Hbl_pwm 'Hintergrundbeleuchtung
If Ta_alarm = 1 And Sw_alarm = 1 Then A = 1 Else A = 0
If V_al_std = Ds_hour And V_al_min = Ds_min Then B = 1 Else B = 0
If A = 1 And B = 1 Then C = 1 Else C = 0
If C = 1 And Ds_sec = 5 Then Gosub Ausgang
If Ta_alarm = 0 Then Gosub Al_stellen
Loop
Ausgang: ' AUSGANG
Al_out = 1
Sound Buzz , 200 , 150 'Buzzer Länge, Tonhöhe
Wait 1 'Alarm - EIN - Zeit
Al_out = 0
Return
Die Anzeige bleibt zwar für die Alarmzeit (1 bis 2 Sekunden) stehen, aber die Uhr läuft weiter.
Da nun alles zur Zufriedenheit lief und der Mega8 nichtmal halb ausgelastet ist, habe ich als kleines Schmankerl noch eine
Steuerung der Hintergrundbeleuchtung über das Umgebungslicht draufgesetzt.
Zunächst wollte ich das kontinuierlich regeln, habe aber davon Abstand genommen, weil ich ein flackern der Helligkeit einfach nicht
wegbekam. So habe ich den ADC- Ausgang auf 5 Bit runtergesetzt und schalte damit nur noch Hell oder Dunkel. Das reicht mir völlig
aus. Die Steuerung macht der Timer 2 mit PWM, dahinter ist noch ein Transistor, weil die HBL ca. 40mA braucht. Der Code dafür ist
recht einfach:
Code:
Hbl_pwm: 'Hintergrundbeleuchtung
Ldr = Getadc(2)
Shift Ldr , Right , 5 'Auflösung 5 Bit
If Ldr < 8 Then Pwm_ = 50
If Ldr > 15 Then Pwm_ = 255
Compare2 = Pwm_
Return
und ist auch als Sub in der Hauptschleife. Das ganze sieht nun so aus:
Code:
'Ausgänge = B.1 = Alarm , B.2 = Buzzer , B.3 = HBL(PWM)
'C.4 und C.5 = TWI/I2C , Port D 2 bis D.7 für LCD
'Eingänge = , D.0 = Schalter Alarm Ein , D.1 = Taster Alarm stellen
'C.0 und C1 = ENC , C.2 = LDR für HBL , B.0 = DCF77
$regfile = "m8def.dat"
$crystal = 2000000
$hwstack = 64
$swstack = 32
$framesize = 64
$include "D:\PROG\INIT_LCD16x2.bas" 'LCD an Port D
$lib "I2C_TWI.lbx"
Config Sda = Portc.4
Config Scl = Portc.5
Config Twi = 100000
Ddrb = &B11001110
Portc = &B11 ' Pullups
Portd = &B11 'Pullups
Enc_a Alias Pinc.1
Enc_b Alias Pinc.0
Dcf_pin Alias Pinb.0
Al_out Alias Portb.1
Buzz Alias Portb.2
Hbl_out Alias Portb.3 'Beleuchtung Ausgang (PWM)
Sw_alarm Alias Pind.0 'Schalter Alarm EIN - AUS
Ta_alarm Alias Pind.1 'Taste Alarmzeit stellen EIN - AUS
Dim Al_zeit As Byte , A As Byte , B As Byte , C As Byte , Zw As Byte
Dim Ds_day As Byte , Ds_month As Byte , Ds_year As Byte
Dim Ds_sec As Byte , Ds_min As Byte , Ds_hour As Byte
Dim Al_min As Integer , Al_std As Integer , V_al_min As Byte , V_al_std As Byte
Dim Ldr As Word , Pwm_ As Byte 'LDR = Fotowiderstand
Al_min = 30 : Al_std = 20 'Startwert
Deflcdchar 1 , 2 , 6 , 14 , 31 , 14 , 6 , 2 , 32 'Pfeil nach links
'*********** TIMER 1 für DCF77****************
Config Dcf77 = Pinb.0 , Timer = 1
Config Date = Dmy , Separator = .
'*********** TIMER 0 für Drehencoder*********
Config Timer0 = Timer , Prescale = 64 '= ~2Mhz = ~0,5µs * 64 = ~ 32µs
Timer0 = 225 'Startwert = 31 x ~ 32µs = ~1ms
On Timer0 Enc_int
Enable Timer0
'*********** TIMER 2 und ADC 2 für Hintergrundbeleuchtung*********
Config Timer2 = Pwm , Prescale = 64 , Compare Pwm = Clear Up
Enable Timer2
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Enable Interrupts
Do ' MAIN - SCHLEIFE
Locate 1 , 16
If Dcf_pin = 1 Then Lcd "+" Else Lcd " " 'DCF-Impuls
Locate 1 , 6
If Dcf_status.7 = 1 Then Lcd "*" Else Lcd " " 'DCF-Status
Gosub Show_clock ' Anzeige vom RCT - Speicher holen
Gosub Show_alarm ' Anzeige vom RCT - Speicher holen
Gosub Hbl_pwm 'Hintergrundbeleuchtung
If Ta_alarm = 1 And Sw_alarm = 1 Then A = 1 Else A = 0
If V_al_std = Ds_hour And V_al_min = Ds_min Then B = 1 Else B = 0
If A = 1 And B = 1 Then C = 1 Else C = 0
If C = 1 And Ds_sec = 5 Then Gosub Ausgang
If Ta_alarm = 0 Then Gosub Al_stellen
Loop
Ausgang: ' AUSGANG
Al_out = 1
Sound Buzz , 200 , 150 'Buzzer Länge, Tonhöhe
Wait 1 'Alarm - EIN - Zeit
Al_out = 0
Return
Al_stellen: ' STELLEN
Do
Locate 2 , 8
If Al_std < 10 Then Lcd "0" ; Al_std Else Lcd Al_std
Locate 2 , 10
If Al_min < 10 Then Lcd ":0" ; Al_min Else Lcd ":" ; Al_min ; " "
Locate 2 , 14 : Lcd " " ; Chr(1) ; " "
If Al_min < 0 Then
Al_min = 59
Al_std = Al_std - 1
End If
If Al_std < 0 Then Al_std = 23
If Al_min > 59 Then
Al_min = 0
Al_std = Al_std + 1
End If
If Al_std > 23 Then Al_std = 0
Gosub Alarm_speichern
If Ta_alarm = 1 Then Exit Do
Loop
Enc_int: 'TIMER 0 Interrupt für Drehencoder
Timer0 = 225 'Timer Startwert
Zw.0 = Enc_a 'Zustandswechsel
Zw.1 = Enc_b
Select Case Zw
Case &H0_2 : Incr Al_min 'bei jedem zweiten Tick
Case &H0_1 : Decr Al_min
End Select
Zw.4 = Zw.0
Zw.5 = Zw.1
Return
Show_clock: ' RTC Uhrzeit und Datum auslesen und anzeigen
I2cstart
I2cwbyte 208
I2cwbyte 0
I2cstart
I2cwbyte 209
I2crbyte Ds_sec , Ack
I2crbyte Ds_min , Ack
I2crbyte Ds_hour , Ack
I2crbyte Ds_day , Ack
I2crbyte Ds_month , Ack
I2crbyte Ds_year , Nack
I2cstop
Gosub Rtc_stellen
Locate 1 , 1 : Lcd "Zeit:"
Locate 1 , 8 : Lcd Bcd(ds_hour) ; ":" ; Bcd(ds_min) ; ":" ; Bcd(ds_sec)
Return
Show_alarm: ' RTC Alarmzeit auslesen und anzeigen
I2cstart
I2cwbyte 208
I2cwbyte 10
I2cstart
I2cwbyte 209
I2crbyte V_al_std , Ack
I2crbyte V_al_min , Nack
I2cstop
Locate 2 , 1 : Lcd "Alarm: " ; Bcd(v_al_std) ; ":" ; Bcd(v_al_min)
Locate 2 , 14
If Sw_alarm = 0 Then Lcd "Aus" Else Lcd "Ein"
Return
Rtc_speichern: ' Uhrzeit in RTC speichern
Ds_sec = Makebcd(ds_sec)
Ds_min = Makebcd(ds_min)
Ds_hour = Makebcd(ds_hour)
Ds_day = Makebcd(ds_day)
Ds_month = Makebcd(ds_month)
Ds_year = Makebcd(ds_year)
I2cstart
I2cwbyte 208
I2cwbyte 0
I2cwbyte Ds_sec
I2cwbyte Ds_min
I2cwbyte Ds_hour
I2cwbyte Ds_day
I2cwbyte Ds_month
I2cwbyte Ds_year
I2cstop
Return
Alarm_speichern: ' Alarmzeit in RTC speichern
V_al_min = Makebcd(al_min)
V_al_std = Makebcd(al_std)
I2cstart
I2cwbyte 208
I2cwbyte 10
I2cwbyte V_al_std
I2cwbyte V_al_min
I2cstop
Return
Rtc_stellen: ' RTC nach DCF77 stellen
If Dcf_status.7 = 1 And Ds_sec <> _sec Then
Ds_sec = _sec
Ds_hour = _hour
Ds_min = _min
Ds_day = _day
Ds_month = _month
Ds_year = _year
Gosub Rtc_speichern
End If
Reset Dcf_status.7
Return
Hbl_pwm: 'Hintergrundbeleuchtung
Ldr = Getadc(2)
Shift Ldr , Right , 5 'Auflösung 5 Bit
If Ldr < 8 Then Pwm_ = 50
If Ldr > 15 Then Pwm_ = 255
Compare2 = Pwm_
Return
Hier noch ein Foto der gesamten Technik, aufgebaut mit myAVR-Light Board:
Anhang 26782
Links der Fotowiderstand mit Vorwiderständen, unten die ELV-DCF77 und rechts der Drehencoder und der Schalter für die
Alarmzeiteinstellung.
Einen Schaltplan hab ich auch gemacht, er zeigt mir gleich die mechanische Anordnung der Teile. Das LCD kommt über die Platine
zu liegen:
Anhang 26783
Dieses ganze Projekt hätte ich mir sparen können, wenn es eine einfachere Lösung für das eigentliche Problem gäbe, nämlich:
Eine Möglichkeit festzustellen, ob am PC ein USB- Gerät aktiv ist oder nicht. Denn meine Robot- Kamera schaltet ja bei Dunkelheit
aus bzw. um auf USB- Ausgang. Ich habe aber nicht herausgefunden, wie man das am PC auswerten könnte.
Der bräuchte dann nur noch die gemachten Fotos runterzuladen, mit Datum zu versehen, abzuspeichern und die SD-Karte
der Kamera zu löschen. Das macht er jetzt auch schon, seit über sechs Jahren, es fehlen nur drei Tage wegen Stromausfall
bzw. Computerversagen. Nur die Schaltuhr mußte ich ständig beobachten.
Aber das hat jetzt ein Ende.
Allerdings war die Entwicklung auch sehr interessant und lehrreich, das ist für die nächsten Projekte bestimmt von Nutzen!
Eine Uhr kann man immer gebrauchen ;)
Joachim