Hallo,
Van de site van Frits heb ik de code voor het uitlezen van een DCF77 module.
Dit gaat op zich goed, hoefde wijnig aan te passen
Echter mijn display, een samsung waarop 21 karakters op kunnen, 7 regels.
Echter achter de tijd (in 24uur modus) komt er een 9 achter de seconden te staan.
Ik krijg deze niet weg, iemand een tip?
ik heb al gespeeld met het aantal karakters, ook al een paar andere dingen geprobeerd, echter zonder resultaat.
Wellicht dat Frits zelf een tip heeft.....
Ook de W en de Z van winter en zomertijd krijg ik niet op het display...
Code die ik heb:
Device 18F452
XTAL = 8
@CONFIG_REQ
@__CONFIG config1h, OSCS_OFF_1 & HS_OSC_1
@__CONFIG config2l, BOR_ON_2 & BORV_20_2 & PWRT_ON_2
@__CONFIG config2h, WDT_OFF_2 & WDTPS_128_2
@__CONFIG config3h, CCP2MX_ON_3
@__CONFIG config4l, STVR_ON_4 & LVP_OFF_4 & DEBUG_OFF_4
Include "GLCD_declare.inc" ; hierin staan de pin configuratie van de GLCD
ALL_DIGITAL = TRUE
;Normale aliases (constanten)
Symbol Blokje = 88;255 ;Maximaal 255: 255 is de ASCII code voor een blokje op de LCD tijdsbalk
Symbol LCD_Char = 19 ;Minimaal 16: Aantal karakters per regel (afhankelijk van het gebruikte LCD type)
Symbol MaxVindTijd = 65 ;Minimaal 65: (Sec) Tijd om seconde 00 te vinden
Symbol OpStartTijd = 45000 ;Maximaal 65535: (mSec) 45 seconden opstart tijd voor de DCF77 module na power-on
Symbol PulsLengte = 740 ;Minimaal 500! Maximaal 750: (mSec)
Symbol PulsLengteX = PulsLengte / 10
;Logische aliases (constanten)
Symbol AAN = 0 ;Omgekeerd ON
Symbol FALSE = 0
Symbol OFF = 0
Symbol On = 1
Symbol TRUE = 1
Symbol UIT = 1 ;Omgekeerd OFF
;Poort aliases
Symbol Zomertijd = PORTC.0 ;Hoog als het zomertijd is (hulp LED bij het afregelen van de LDR)
Symbol SecondePuls = PORTA.1 ;Iedere seconde een puls van 0,5 seconde
Symbol Gong1 = PORTA.2 ;Elk heel uur komt hier een puls voor aansturing gong
Symbol Gong2 = PORTA.3 ;Elk heel en half uur komt hier een puls voor aansturing gong
Symbol Volume = PORTA.4 ;Wisselt tussen output (GND) en input (hoog-ohmig) om het volume van de gong te regelen
Symbol AM_PM = PORTC.6 ;In 24 uurs mode met +5V verbinden, voor 12 uurs AM/PM notatie deze poort met GND verbinden
Symbol LDR = PORTA.7 ;Als het donker is maakt de gong minder geluid dan overdag of met schemerlampen aan
Symbol DCF_Signaal = PORTA.0 ;Ingang voor de DCF77 module (ontvanger) signaal (bv. Conrad BN641138)
Symbol Test = PORTC.1 ;Normaal open laten, voor afregelen van LDR laag maken VOOR opstarten PIC, voor afregelen gong laag maken NA opstart PIC
; 76543210
TRISA = %11100001
;TRISB = %11111111
TRISC = %11111110
;PORTb_PULLUPS On ;Pull-up voor DCF77 ontvanger en Test toets
;WORD
Dim SignaalCheck As Word
Dim Teller As Word
;BYTE
Dim AlgemeneTeller As Byte
Dim BitAantal As Byte
Dim CursorPos As Byte ;Cursor x-positie op de LCD
Dim Dag As Byte
Dim Jaar As Byte
Dim Maand As Byte
Dim Minuut As Byte
Dim MinuutDCF As Byte ;Bevat de DCF minuut, is er een pariteitserror, dan wordt Minuut NIET gelijk gemaakt met MinuutDCF, maar alleen met 1 verhoogd
Dim OntvangByte As Byte
Dim Seconde As Byte
Dim Uur As Byte
Dim UurDCF As Byte ;Bevat het DCF uur, is er een pariteitserror, dan wordt Uur NIET gelijk gemaakt met UurDCF
Dim UurLCD As Byte ;Normaal gelijk aan Uur, alleen bij AM/PM notatie wijkt hij 's middags af
Dim WeekDag As Byte
Dim BD1 As Byte ;Byte Dummy 1
;BIT
Dim Initialiseren As Bit ;TRUE bij initialiseren
Dim OntvangBit As Bit
Dim PariteitsBit As Bit
Dim PariteitsError As Bit
Dim Signaal As Bit ;TRUE als er een signaal is (gevonden)
Dim ID1 As Bit ;Bit Dummy 1
PORTA = 0
;PORTB = 0
PORTC.1 = 0
PORTC.6 = 0
Cls
Clear
DelayMS 500 ;LCD stabilisering
Cls
Print "www.picbasic.nl"
;DelayMS 3000
DelayMS 300
Cls
Print "DCF16NLD V-2" ;Versie nummer
;DelayMS 2000
DelayMS 300
Cls
Print "LDR afregelen"
While Test = AAN ;Als Test laag is bij opstart van PIC, kan de LDR afgeregeld worden met behulp van de ZomerTijd LED
If LDR = On Then
Zomertijd = TRUE
Else
Zomertijd = FALSE
EndIf
Wend
Cls
Print "Signaal zoeken"
Initialiseren = TRUE
Low Volume ;Bij opstarten staat volume van gong op hard
GoTo HoofdLus ;Spring over de subroutines
;SUBROUTINES
OntvangBitAantal: ;Vul het ontvangstbyte met het opgegeven aantal bits in BCD mode
Clear OntvangByte
For BD1 = 0 To BitAantal - 1
GoSub OntvangEenBit
If OntvangBit = 1 Then SetBit OntvangByte, BD1
Next
OntvangByte = ((OntvangByte >> 4) * 10) + (OntvangByte & 15) ;BCD (Binary-Coded Decimal) naar byte conversie
Return
OntvangEenBit: ;Ontvang een bit en bewaar dit in OntvangBit
Clear Teller
While DCF_Signaal = AAN
DelayMS 1
Inc Teller
If Teller > 3000 Then ErrorOntvangst ;Tegen een eventuele 'hang up'
Wend
DelayMS 155 ;135 - 175msec
OntvangBit = DCF_Signaal
If Initialiseren = TRUE Then
CursorPos = (Seconde * LCD_Char) / 58 ;Bereken waar de cursor moet staan (afhankelijk van de wachttijd en LCD type)
Print At 2, CursorPos, Blokje ;Maak tijdsbalk actueel
Else
Print At 1, CursorPos, DEC2 Seconde ;Zet de seconden op het LCD
PariteitsBit = PariteitsBit + OntvangBit ;Bit, dus 0+0=0 / 0+1=1 / 1+1=0 / 1+0=1
EndIf
Inc Seconde ;Omdat we toch elke seconde in deze routine zijn, gebruiken we het ook om de seconden te tellen
SecondePuls = On ;Uitgangssignaal seconde puls
DelayMS 500
SecondePuls = OFF
DelayMS PulsLengte - 500
Return
;HOOFDPROGRAMMA
HoofdLus:
Clear AlgemeneTeller
Seconde = 00 ;Start met de eerste seconde
Signaal = FALSE
While Signaal = FALSE ;Wacht tot het DCF signaal hoog is
Clear Teller
While DCF_Signaal = UIT
Inc Teller
DelayMS 1
If Teller > OpStartTijd Then ErrorOntvangst ;Opstart tijd voor de DCF77 ontvanger bij power-on
Wend
Clear Teller
While DCF_Signaal = AAN ;Meet de tijd tussen de pulsen
Inc Teller
DelayMS 10
If Initialiseren = FALSE Then
Select Case Teller
Case 85 - PulsLengteX ;85 = (1000mSec - 155mSec) / 10
Print At 1, CursorPos, "59";xx:xx:59, zet de niet uitgezonden seconde '59' op het LCD
Case 25
SecondePuls = On
Case 75
SecondePuls = OFF
Case 250
GoTo ErrorOntvangst;Signaal is niet binnen de tijd van niveau veranderd
EndSelect
Else
If Teller > (OpStartTijd / 10) Then ErrorOntvangst ;Opstart tijd voor de DCF77 ontvanger bij power-on
EndIf
Wend
If AlgemeneTeller >= MaxVindTijd Then ErrorOntvangst ;Als er meer dan 'MaxVindTijd' seconden zijn geteld dan hebben we een probleem
Inc AlgemeneTeller
If Teller > 100 Then Signaal = TRUE ;We tellen per 10mSec, dus we hebben minstens 100x10mSec nodig om het begin te vinden
If Initialiseren = TRUE Then
CursorPos = (AlgemeneTeller * LCD_Char) / MaxVindTijd ;Bereken waar de cursor moet staan (afhankelijk van de wachttijd en LCD type)
Print At 1, 1, "Signaal gevonden"
Print At 2, CursorPos , Blokje ;Zet blokjes op het LCD tijdens wachten op het init signaal
EndIf
Wend
If Initialiseren = TRUE Then
Cls
Print "Initialiseren..."
Print At 2, 1, Rep "_" \ LCD_Char ;Teken een dunne lijn die aangeeft hoe lang de tijdsbalk wordt
Else
CursorPos = LCD_Char - 9 ;X-positie van tijd op het LCD 9
Cursor 1, CursorPos
If PariteitsError = TRUE Then ;Tijd onbetrouwbaar, de PIC zorgt nu zelf voor actualisering van de tijd
If Minuut < 59 Then
Inc Minuut
Else
Minuut = 00 ;\
If Uur < 23 Then ;-Tijd wordt gelijk gezet, ondanks pariteitserror
Inc Uur ;/
Else
Uur = 00 ;De datum verhogen heeft geen zin, die wordt bij een error nl. niet gewijzigd
EndIf
EndIf
Else ;Geen error, dus gewoon de DCF tijd neerzetten
Minuut = MinuutDCF
Uur = UurDCF ;Het uur wordt alleen geactualiseerd als er geen pariteitserror is
EndIf
If AM_PM = AAN Then ;...als AM/PM notatie is ingeschakeld dan...
Select Case Uur
Case 0 :UurLCD = 12 ;Als het 00:xx uur is dan op LCD weergeven als 12:xx
Case > 12:UurLCD = Uur - 12 ;Als het 13:xx t/m 23:xx is dan op LCD weergeven als 1:xx t/m 11:xx
End Select
Else
UurLCD = Uur
Print " " ;Wis deel van 12 uurs notatie (AM/PM) uit bij omschakeling naar 24 uurs notatie
EndIf
If UurLCD < 10 Then Print " " ;Wis de eerste nul (08:00:00 --> 8:00:00) (Nul onderdrukking)
Print Dec UurLCD, ":", DEC2 Minuut, ":00" ;Zet elke minuut de actuele tijd op het LCD
If AM_PM = AAN Then ;Als AM/PM notatie is ingeschakeld dan...
If Uur < 12 Then ;...als het voor de middag is dan...
Print " am" ;...AM achter de tijd zetten...
Else ;...anders (is het na de middag)...
Print " pm" ;...PM achter de tijd zetten
EndIf
CursorPos = LCD_Char - 3 ;Cursor positie alvast instellen voor de seconden, 2 meer naar links voor de AM/PM
Else
CursorPos = LCD_Char - 1 ;1 Cursor positie alvast instellen voor de seconden
EndIf
If Minuut = 00 Or Minuut = 30 Or Test = AAN Then GongSignaal ;Elk heel en half uur een gong signaal (en elke minuut als Test = AAN)
EndIf
If Signaal = TRUE Then ;Startbit succesvol ontvangen, start met het vullen van data
GoSub OntvangEenBit ;0: Bit 0 (gereserveerd (DCF77 protocol)
Verder: ;Als de gong klinkt, wordt bit 0 genegeerd, na de gong, wordt hier verder gegaan
For BD1 = 1 To 14 ;1...14: deze bits zijn gereserveerd (info zie www.picbasic.nl --> DCF77 info)
GoSub OntvangEenBit
Next
Clear PariteitsBit ;Als PariteitsError is geset, dan is PariteitsBit ook verminkt (geweest), even resetten
Clear PariteitsError ;Reset PariteitsError (Deze 2 resets op deze plek laten staan ivm. pariteitserror tijdens initialiseren)
GoSub OntvangEenBit ;15: Welke zend antenne is gebruikt?
; IF OntvangBit = 0 THEN... ;Signaal is verzonden door de standaard antenne, dit bit wordt niet gebruikt in dit programma
; IF OntvangBit = 1 THEN... ;Signaal is verzonden door een reserve antenne, dit bit wordt niet gebruikt in dit programma
GoSub OntvangEenBit ;16: Omschakeling naar zomer/winter volgend uur?
; IF OntvangBit = 1 THEN... ;Dit bit wordt niet gebruikt in dit programma
GoSub OntvangEenBit ;17: Zomer- of wintertijd?
If OntvangBit = 1 Then
Zomertijd = TRUE ;Zomer
Else
Zomertijd = FALSE ;Winter
EndIf
For BD1 = 18 To 19 ;18...19: Deze bits worden niet gebruikt (Time Zone bit 2 en schrikkel-seconde bit)
GoSub OntvangEenBit
Next
GoSub OntvangEenBit ;20: Startbit, normaal altijd 1, dit bit wordt niet gebruikt in dit programma
; IF OntvangBit = 0 THEN... ;Dit bit wordt niet gebruikt in dit programma
BitAantal = 7 ;21...27: Ontvang minuut (7 bits)
GoSub OntvangBitAantal
MinuutDCF = OntvangByte ;Wordt eerst in MinuutDCF opgeslagen, als blijkt dat er geen pariteitserror is, dan wordt het aan Minuut gegeven, bij een error niet
GoSub OntvangEenBit ;28: Pariteitsbit 1, minuten
If PariteitsBit = On Then PariteitsError = TRUE
BitAantal = 6 ;29...34: Ontvang uur (6 bits)
GoSub OntvangBitAantal
UurDCF = OntvangByte ;Wordt eerst in UurDCF opgeslagen, als blijkt dat er geen pariteitserror is, dan wordt het aan Uur gegeven, bij een error niet
GoSub OntvangEenBit ;35: Pariteitsbit 2, uren
If PariteitsBit = On Then PariteitsError = TRUE
BitAantal = 6 ;36...41: Ontvang dag (6 bits)
GoSub OntvangBitAantal
Dag = OntvangByte
BitAantal = 3 ;42...44: Ontvang weekdag (3 bits)
GoSub OntvangBitAantal
WeekDag = OntvangByte
BitAantal = 5 ;45...49: Ontvang maand (5 bits)
GoSub OntvangBitAantal
Maand = OntvangByte
BitAantal = 8 ;50...57: Ontvang jaar (8 bits)
GoSub OntvangBitAantal
Jaar = OntvangByte
GoSub OntvangEenBit ;58: Pariteitsbit 3, datum
If PariteitsBit = On Then PariteitsError = TRUE
If Initialiseren = TRUE Then
If PariteitsError = FALSE Then ;Als er GEEN pariteitserror is, dan zijn we...
Initialiseren = FALSE ;...klaar met initialiseren (Dus opnieuw initialiseren als er WEL een pariteitserror tijdens initialiseren was
EndIf
Cls
EndIf
If PariteitsError = FALSE Then ;Alleen datum actualiseren als er geen error in de ontvangst is
Print At 1, 1, Rep " " \ 9 ;Wis de dag op het LCD (Alleen nodig bij volledige naam van de dag)
Print At 2, 1, Rep " " \ LCD_Char ;Wis de hele tweede lijn
Cursor 1, 1
Select Case WeekDag
Case 1: Print "Ma"
Case 2: Print "Di"
Case 3: Print "Wo"
Case 4: Print "Do"
Case 5: Print "Vrijdag"
Case 6: Print "Za"
Case 7: Print "Zo"
EndSelect
Print At 2, 1, Dec Dag, " "
Select Case Maand
Case 1: Print "januari"
Case 2: Print "februari"
Case 3: Print "maart"
Case 4: Print "april"
Case 5: Print "mei"
Case 6: Print "juni"
Case 7: Print "juli"
Case 8: Print "augustus"
Case 9: Print "september"
Case 10: Print "oktober"
Case 11: Print "november"
Case 12: Print "december"
End Select
If Maand = 9 Then
Print " '", DEC2 Jaar ;September (9 karakters) past anders niet op 16 karakters LCD
Else
Print " 20", DEC2 Jaar
EndIf
EndIf
Else ;Else 'Signaal' = FALSE, geen signaal gevonden
GoTo ErrorOntvangst
EndIf
GoTo HoofdLus
GongSignaal:
If LDR = On Then ;Als het daglicht is of de schemerlampen zijn aan dan...
Low Volume ;...Volumepin laag = Volume van gong harder...
Else ;...anders (is het donker in huis)...
Input Volume ;...Volumepin hoog-ohmig (3-state) = Volume van gong zacht
EndIf
DelayMS 155
If Minuut = 00 Or Test = AAN Then Gong1 = On ;Op de hele uren (en met test) volgt een 3-tonig signaal
Gong2 = On ;Op de halve uren alleen een 2-tonig signaal
SecondePuls = On
DelayMS 500
Gong1 = OFF
Gong2 = OFF
SecondePuls = OFF
DelayMS 330 ;985 - 500 - 155
Inc Seconde
; Bij gebruik van onderstaande methode (d.m.v. tijd) het LDR syntax gedeelte uitschakelen
; IF Uur > 5 THEN ;Tussen 0:30 uur en 6:30 uur staat het volume van de gong zachter
; LOW Volume ;Volumepin laag = Volume harder
; ELSE
; INPUT Volume ;Volumepin hoog-ohmig (3-state) = Volume zacht
; ENDIF
GoTo Verder ;Ga verder met het lezen van de DCF77 bits vanaf bit 1 (We slaan de DCF77 bit 0 over)
ErrorOntvangst:
Cls
Print "Geen signaal" ;Startbit niet gevonden of geen signaal?
Repeat
Clear ;Wis alle RAM
ID1 = DCF_Signaal
While DCF_Signaal = ID1 ;Wacht op signaal verandering
Inc SignaalCheck
DelayMS 1
Wend
ID1 = ID1 ^ 1
While DCF_Signaal = ID1 ;Wacht op signaal verandering
Inc SignaalCheck
DelayMS 1
Wend
Until SignaalCheck < 990
Initialiseren = TRUE ;Na een error moet er weer worden geinitialiseerd
GoTo HoofdLus
Include "font.inc" ; hierin staat het fonttabel voor het display
;V-2 t.o.v. V-1:
;Met pariteitscheck
;PulsLengte zo lang mogelijk gemaakt
;SecondePuls duurt nu precies 0,5 sec
oorspronkelijke code staat op:
http://www.picbasic.nl/downloads/DCF16NLD_V-2.bas
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
Op 21 februari 2009 14:58:09 schreef lampje25:
Echter achter de tijd (in 24uur modus) komt er een 9 achter de seconden te staan.
Ik krijg deze niet weg, iemand een tip?
Dat is waarschijnlijk de 9 van het seconde-getal '59'.
Even zoeken waar dat ontstaat.
Misschien omdat je de constante 'LCD_Char' de waarde 19 hebt toegekend.
Jouw display heeft toch 21 karakters?
Dan zou hier dus 21 moeten staan.
(Ik heb niet zo'n display dus kan het niet testen).
Frits,
Volgens mij niet de 9 van het seconde getal
Ik heb namelijk wel de 2 cijfers van de seconden, alleen ik heb er nog een 3de cijfer achter staan.
Ik zal het nog proberen met 21 karakters als LCD_Char waarde.
Edit:
als ik 21 als waarde invul bij LCD_CHAR dan krijg ik de laatste seconde getal er niet op, deze wordt dan op de zelfde regel vooraan neergezet en bij elke volgende seconde ook nog eens 1 karater verder op het scherm..
Bij waarde van 20 bij LCD_CHAR dan komt de 9 voor de weekdag te staan, dus dit:
9ZO..........21:37:20 (stipjes moet je zien als spatie)
dus tijd komt wel goed op het scherm
[Bericht gewijzigd door lampje25 op (49%)]
Is het niet zo dat je uren notatie geen leading zero heeft? Dan is de 9 dus wel van de seconden teller. De 9 verschijnt dan bij het schakelen van 23:59:59 (=8char) naar 0:00:00 (=7char).
Nou het probleem doet zich ondermeer voor bij een tijdweergave als 21:30:21.
Bij 9:21:35 weet ik eigenlijk niet wat hij doet.