DCF77 signaal verwerken

Beste CO'ers,

heb een tijd geleden zo'n DCF77 ontvanger besteld bij conrad. Heb deze week nog vrij, dus wil hier wat tijd mee bezig zijn.

Ik heb op de scoop het signaal zichtbaar gekregen. een logische 0 komt zoals verwacht met 100ms en een logische 1 komt overeen met 200ms. Dus het ontvangst gaat nu goed(nadat ik eerst veel problemen had doordat ik de ontvanger naast me laptop had liggen).

nu wil ik het programma gaan schrijven voor de klok. Ik wil gebruik maken van de PIC16F877A. Ik gebruik de niet-inverterende uitgang van de DCF77 ontvanger en sluit deze aan op de interruptpoort van de PIC.

Het probleem is dat ik nog nooit gebruik heb gemaakt van interrupts. Ik weet dat een interrupt het hoofdprogramma onderbreekt en deze eerst uitvoert.

Voor het decoderen heb ik de volgende link gelezen:

http://www.circuitsonline.net/forum/view/38456

echter kom ik al iin het begin in de problemen:
- Wachten tot de afwezigheid van het 59e bit gedetecteerd wordt.
- Bij het eerstvolgend ontvangen bit de bitteller resetten (=bit00).

hoe detecteer ik de afwezigheid van het 59ste bit? als ik de afwezigheid gedetecteerd heb, kan ik doortellen, maar hoe detecteer in de afwezigheid?

Hugo Welther

Moderator

Het enige dat tussen jou en je doel staat is alles wat jij jezelf verteld dat je het niet kan.

ik weet niet in welke taal je programmeert maar dit is een voorbeeld in JAL, wat redelijk snel te vertalen is.
1 Seconde interrupt met Timer0
nog enkele handige links:
Uitleg over interrupt
Programma om TMR0 uit te rekenen
Klokje (zonder DCF77) (misschien handig om je op te baseren)

Zelf ben ik ook van plan om zo een klokje te maken voor mijn eindwerk (wel met een 16F628A)

Dit heb ik gisteren-avond(nacht) snel uitgedacht:

(heb nog geen gerief binnen, dus ik heb het nog niet kunnen testen)

De "Software" in (zeer) grote lijnen

code:


stel timer0 in op 1Sec


forever loop
  while dcf_in = off loop wend ; wacht tot er een signaal komt
  reset tmr0

  sec = sec + 1
  delayms 150                   ;zorg dat je in het midden van de bit zit
  bit = dcf_in 

  ;hier de rest van het programma
  ;wegschrijven naar display, datum uitrekenen, 
  ;uur uitrekenen, error, ...

end loop


interrupt tmr0:

if dcf_in = low then
  if sec < 59 then ; twee maal startbit in minder dan een minuut => fout
   sec = 0 
   error (geen ontvangst)
  else 
    ;startbit
   sec = 59
  end if
end if

wat moet er nog bijkomen,

  • Welkomstvenster
  • Wachten op signaal van de antenne (na 50 sec geen signaal => geen signaal-routine)
  • Zoeken van de Startbit (na 1 minuut geen startbit => geen signaal-routine
  • Initialiseren (bits vullen)
  • Fout afhandeling
  • Wegschrijven naar display
  • ...
Master Industriële Wetenschappen: Elektronica-ICT

dus als ik het goed begrijp, stel je de interrupt in op 1 seconde (Timer0)?

en zodoende is het dus te bepalen als er geen interrupt ontvangen wordt, dat het naar alle waarschijnlijkheid sec. 59 is

die link van picbasic had ik al gevonden ;)

[Bericht gewijzigd door Mitchell S op maandag 27 augustus 2007 12:09:44 (11%)

Turbokeu

Golden Member

Ik gebruik een teller in een vaste interruptroutine om de 4msec (Timer0 overflow).
Vanuit de interrupt routine decodeer ik de DCF77 pulsen en verhoog ik telkens deze teller.
Bij elke DCF puls (om de sec) geraakt de teller maar tot 250 (250x4msec=1000msec) en wordt deze vervolgens gereset.
Bij de 59e sec zal de teller echter overflowen bij 255 (1024msec) zodat ik weet dat ik in de 59e sec ben.

CD :)

I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"

@Turbokeu

ik snap wat u bedoelt, alleen de eerste regel niet helemaal. wat is een vaste interruptroutine? Is dat een soort teller die constant loopt en die in dit geval om de 4ms een overflow genereerd?

de interrupt is volledig onafhankelijk van het DCF77-signaal, deze is er altijd (maar hij wordt wel gelijk gezet met de de start van het dcf-signaal). (de interrupt is ook nodig om verder te werken waneer er geen signaal is)

code:


         +<-1 sec->+         +         +         +         +   ...    +         +         +         +         +         +

                     _         __        _         _         _          __        _                   __                    
DCF-sig  ___________| |_______|  |______| |_______| |_______| |_......_|  |______| |_________________|  |_________________.....


TMR0-int _____I_____I_________I_________I_________I_________I_...  ..._I_________I_________I_________I_________I_________I_...
(I=interrupt)
          +<-1 sec->+         +         +         +         +   ...    +         +         +         +         +         +         
              1         2         3         4         5                     23        24        25        26        27                   
          
          
1: opstarten, interrupt loopt al, antenne start op, 
2: DCF-signaal ontvangen, TMR0 wordt gelijk gezet met het signaal (een 0 wordt ontvangen)
3: DCF-signaal ontvangen, TMR0 wordt gelijk gezet met het signaal (een 1 wordt ontvangen)           
4: DCF-signaal ontvangen, TMR0 wordt gelijk gezet met het signaal (een 0 wordt ontvangen)           
5: DCF-signaal ontvangen, TMR0 wordt gelijk gezet met het signaal (een 0 wordt ontvangen)           
23:DCF-signaal ontvangen, TMR0 wordt gelijk gezet met het signaal (een 1 wordt ontvangen)
24:DCF-signaal ontvangen, TMR0 wordt gelijk gezet met het signaal (een 0 wordt ontvangen)
25:Er is een interrupt, maar geen DCF-signaal => startbit
26:DCF-signaal ontvangen, TMR0 wordt gelijk gezet met het signaal (een 1 wordt ontvangen)
27:Er is een interrupt, maar geen DCF-signaal, de startbit is minder dan een minuut geleden gepasseerd -> fout in ontvangst

Of dit een goede methode is weet ik niet, maar het is maar een voorstel

Master Industriële Wetenschappen: Elektronica-ICT
Turbokeu

Golden Member

Op 27 augustus 2007 12:24:58 schreef Mitchell S:
@Turbokeu
ik snap wat u bedoelt, alleen de eerste regel niet helemaal. wat is een vaste interruptroutine? Is dat een soort teller die constant loopt en die in dit geval om de 4ms een overflow genereerd?

Yes, interrupt gegenereerd door Timer0 overflow.

CD :)

[Bericht gewijzigd door Turbokeu op maandag 27 augustus 2007 12:37:16 (73%)

I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"

[topic-kaap modus]
@turbokeu
hoe laat jij je klok verder lopen indien er geen signaal is ?
[/topic-kaap modus]

ik begin te twijfelen welk dat de beste methode is, die van mij of die van turbokeu

Master Industriële Wetenschappen: Elektronica-ICT

die van turbokeu klinkt heel eenvoudig, al is jou methode ook niet veel ingewikkelder...

hieronder hoe ik mijn registers geset heb:

code:


	INTCON = 0b.1011.0000; 
		//bit 7 = GIE  = Global Interrupt Enable bit			= 1		//we're going to use an interrupt.
		//bit 6 = PEIE = Peripheral Interrupt Enable bit		= 0
		//bit 5 = T0IE = TMR0 Overflow Interrupt Enable bit		= 1
		//bit 4 = INTE = RB0/INT External Interrupt Enable bit	= 1		//we're going to use the RB0 interrupt pin.
		//bit 3 = RBIE = RB Port Change Interrupt Enable bit	= 0
		//bit 2 = T0IF = TMR0 Overflow Interrupt Flag bit		= 0
		//bit 1 = INTF = RB0/INT External Interrupt Flag bit	= 0
		//bit 0 = RBIF = RB Port Change Interrupt Flag bit		= 0

[Bericht gewijzigd door Mitchell S op maandag 27 augustus 2007 12:53:41 (79%)

Turbokeu

Golden Member

Op 27 augustus 2007 12:47:37 schreef elektro_freak:
[topic-kaap modus]
@turbokeu
hoe laat jij je klok verder lopen indien er geen signaal is ?
[/topic-kaap modus]

Mijn klok start in standalone mode om 12:00:00 en 01/01/2001 via een 24u klok/kalender-met schrikkeljaarcorrectie-routine.
Na het eerste correct ontvangen DCF77-frame (na 1 à 2 minuten) wordt de standalone klok/kalender exact op seconde 00 van de volgende minuut gesynchronizeerd met het DCF77-signaal.
Dit gebeurt elke minuut na elk correct ontvangen DCF-frame.
Indien het laatste frame incorrect is (foutief startbit, foutieve pariteit) of indien het DCF-77 signaal wegvalt wordt de standalone klokroutine niet meer gesynchronizeerd en blijft deze gewoon op het 4.096MHz kristal verderlopen.

ik begin te twijfelen welk dat de beste methode is, die van mij of die van turbokeu

Alle wegen leiden naar Rome...

Edit: Ik moet er nog bij opmerken dat mijn DCF-77 bitdecodering naast de 1-waarde van het startbit ook test op een tolerantie van + en 30% op de bitduurtijd (0=100msec of 1=200msec +/-30%). Daarbuiten is het ontvangen bit ongeldig.
Naast uren en minuten decodeer ik ook dag, maand en jaar in mijn DCF77-datadecodering.
Daarbij wordt ook nog de pariteit van de uren en minuten, en de pariteit op dag/weekdag/maand/jaar gecontroleerd.
Bij iedere pariteitsfout wordt het complete DCF77-frame gedropt.

CD :)

[Bericht gewijzigd door Turbokeu op maandag 27 augustus 2007 16:46:56 (21%)

I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"
Turbokeu

Golden Member

Op 27 augustus 2007 12:48:56 schreef Mitchell S:
hieronder hoe ik mijn registers geset heb:
INTCON = 0b.1011.0000;

Bij mij is INTCON = B'10100000', dus ik gebruik de 'interrupt on bit change' op bit RB0 niet.

CD :)

I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"

Op 27 augustus 2007 16:08:20 schreef Turbokeu:
[...]
Mijn klok start in standalone mode om 12:00:00 en 01/01/2001 via een 24u klok/kalender-met schrikkeljaarcorrectie-routine.

Zo was ik het ook van plan, maar bij mij zal het enkel een 24h klok zijn (moet het programma ook nog uitleggen op mijn GIP)
ik denk dat ik hem constant op deze routine ga laten lopen, en het DCF-signaal ga gebruiken om deze juist te zetten.
De klok zal dus niet lopen op het DCF-signaal, maar op deze routine.
Als er wel ontvangst is zal de datum en uur te zien zijn.
Als er geen ontvangst is zal er enkel het uur te zien zijn.
Pariteitscontrole ging er zeker inzitten

maar nu stop ik met mijn uitleg want anders wordt ik hier nog beschuldigd voor topic-kaping (wat volledig terecht zou zijn)

Master Industriële Wetenschappen: Elektronica-ICT
Turbokeu

Golden Member

Dit is de mooie 24u-klok/kalenderroutine van Jaakko Ala-Paavola die ik gebruik (iets aangepast gezien mijn 4.096MHz kristal):
http://users.tkk.fi/~jalapaav/Electronics/Pic/Clock
De routine is maar een paar honderd bytes groot en heeft schrikkeljaarcorrectie.

Ik gebruik een (courant) 4.096MHz kristal omdat deze frekwentie een macht van 2 is.
Met de juiste prescaler setting voor Timer0 (interrupt om de 4msec) incrementeer ik een teller (250 ticks voor 1 seconde).
Bij elk ontvangen DCF77-bit (elke seconde, dus 250 ticks) wordt deze teller gereset (overflow van de teller betekent dus dat ik in de 59e seconde van het DCF-frame zit).

CD :)

Edit: Puntje teveel in de bovenstaande url gecorrigeerd.

I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"

Op 28 augustus 2007 05:21:04 schreef Turbokeu:
(overflow van de teller betekent dus dat ik in de 59e seconde van het DCF-frame zit).

CD :)

of dat er geen ontvangst is, of zit hier ook een iets van "binnen de minuut 2 x maal geen ontvangst => fout"

(link werkt niet)

Master Industriële Wetenschappen: Elektronica-ICT

IMHO kan je best alles verwerpen, dat enigzins verdacht ruikt.
Hier draait de klok op een tijdbasis, afgeleid van de netspanning. Regelmatig wordt de klok gelijk gezet met het DCF77-signaal, maar dat gebeurt enkel als er minstens 4 foutloze frames na mekaar gedecodeerd zijn.

Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Turbokeu

Golden Member

Op 28 augustus 2007 12:02:23 schreef elektro_freak:
[...]

of dat er geen ontvangst is, of zit hier ook een iets van "binnen de minuut 2 x maal geen ontvangst => fout"

(link werkt niet)

Link is gecorrigeerd.

Ik gebruik 4 status LEDs:
- Blauw (BEAT) = DCF77 beat (deze knippert elke seconde mee met elk ontvangen DCF77 bit, gemakkelijk om de DCF77 ontvanger te positioneren voor optimale DCF77 ontvangst).
- Groen (DCFOK) = Last received DCF77 frame is correct.
- Geel (NODCF) = No DCDF77 reception or missing 59th second bit.
- Rood (DCFNOK) = Bad DCF77 frame (missing DCF77 startbit (bit20), or parity error on bit P1, P2 or P3).

Deze status LEDs worden aangestuurd volgens de waarde van 4 flag bits die real time ge-update worden in de verschillende subroutines.

Bij correcte opeenvolgende DCF77 ontvangst blijft de groene LED continu aan.

De gele LED gaat elke minuut aan van sec 59 tot sec 00, of continu aan bij totaal geen DCF77 ontvangst. In feite gaat deze LED aan van het ogenblik dat er méér dan één seconde geen DCF bit meer ontvangen wordt.

De rode LED gaat aan bij foutief of ontbrekend startbit en/of foutieve pariteit in het current DCF77 frame. Deze rode LED blijft dan aan tot het eerstvolgende correcte DCF77 frame.

CD :)

Edit: update van een paar zinnen.

I love watching conspiracy theorists use the airtight logic of the argument from incredulity: "Well I don't understand how it works so it can't be real!!!"