DCF77 signal — Parallax Forums

# DCF77 signal

Posts: 323
edited 2009-10-11 19:10
Hello,

I have a dcf77 module but have a problem reading its output.

quote from wikipedia: A 0.1 second reduction denotes a binary 0, a 0.2 second reduction denotes a binary 1. As a special case, the last second of every minute is marked with no carrier power reduction.

How can i measure the pulse time with a bs2pe so i can create a new binary string. The problem is also, how to start a new string. (there is no signal in the last second )

dcf77 wiki: http://en.wikipedia.org/wiki/DCF77

regards

·

## Comments

• Posts: 381
edited 2009-10-06 18:26
You can't use COUNT, as it will not provide accurate enough timing, and the max. pulse width for PULSIN is 123.6 ms, so that won't do.

I am thinking this will be very difficult to accomplish with a Stamp, as you need precise timing within the second to measure the pulses. Maybe there are A/D converters that can help you. I am even thinking a 555 timer circuit could do.

The difficult part is to syncronize with the signal. You need to look for an unreduced second followed by a zero bit, then set of a trigger that goes for 59 seconds, then start the syncrionization again.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't worry. Be happy
• Posts: 19
edited 2009-10-06 19:43
Sync maybe not to hard, Tip: only one diference between two minuts. You must find minute bits. Also only one chnge indicate good quality of signal and valid data. After you have right time, you need only second sync pulse.

555 in monostabile mode is great idea if you right calculate time constant you have decoded output 0 and 1

Of course, one big minus in basic stamp chips is absence of interupts (i didnt find it...).

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
C-Bob

Every problem·have at least one·nice, simply and·wrong solution.
• Posts: 242
edited 2009-10-06 20:25
Lets see If I have this every second has a pulse of either 100ms = 0 or 200ms = 1 except the 59th bit which has no output, so if we look for this one second period prior to the start of bit 1 and use it for sync. so pulsin and keep looking for a 1 second period of no output.
• Posts: 242
edited 2009-10-07 01:34
here are a couple of timming programs from Tracy Allen's site that could help if pulsin does not work

' snippet measures the time P0 stays low.
xc var word
loop1: ' 1418 loops per second, 7.05E-4 seconds per loop
xc=xc+1
branch in0,[noparse][[/noparse]loop1] ' count until in0 goes high

' snippet measures the time P0 stays high.
xc var word
loop2: ' 1426 loops per second, 7.013E-4 seconds per loop
xc=xc+1
if in0 then loop2 ' count until in0 goes low
debug dec xc**45960,cr ' ** converts the count to straight milliseconds
• Posts: 323
edited 2009-10-07 10:03
Ok thx all.
After some test with rctime, pulsin and branch,i got this.

```' {\$STAMP BS2}
' {\$PBASIC 2.5}
' {\$PORT COM4}

i VAR Word
xc VAR Word

INPUT 0    ' input from dcf module

DEBUG "Searching signal...",CR
search:
xc=xc+1
BRANCH IN0,[noparse][[/noparse]search] ' count until in0 goes high
i = xc**45960
IF i>1900 THEN init
xc=0
GOTO search
init:
DEBUG "Initialize...",CR
xc=0
GOTO search
```

It seems that i found the 'empty' second.
Now it's time to get those signals [noparse]:)[/noparse]
plz correct me if i'm on the wrong way...
• Posts: 381
edited 2009-10-07 10:17
I don't understand how you will get a HIGH or LOW signal from the device. It differs in value only 25% from the normal, and lasts only a fraction of a second...

But the problem is that you need to convert the signal to a bit stream. This will add (unknown) time delays to your program, and you will get out of sync with the signal.

Suggested solution:
A) Make a 555 astable circuit that produces a pulse every second.
Make a monostable 555 circuit that is triggered from the first one and lasts 200 ms.
C) The first 555 circuit (A) triggers a transistor that sends a HIGH signal to a Stamp pin.
D) The second 555 circuit (B) triggers a transistor the enables an A/D converter for 200 ms.
E) Loop the Stamp and check the value of the A/D whenever C) is HIGH, which will give you the right value for the bit that's processed.

Then you need something to syncronize the signal (to start the 555 timer circuit) at every minute, which can be in a similar manner.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't worry. Be happy

Post Edited (dev/null) : 10/7/2009 10:25:20 AM GMT
• Posts: 323
edited 2009-10-07 10:37
dev/null said...
This will add (unknown) time delays to your program
I noticed [noparse]:)[/noparse]

I think i have to build something like dev/null said.

thx

Post Edited (Tumbler) : 10/7/2009 10:43:04 AM GMT
• Posts: 242
edited 2009-10-07 14:53
I posted somthing for you to try, if this pulsin loop value times out and has a 0 value your synced
now as far as the timing I think pulsin will work for each line and why do you need a string you need to store bits about 3.7 words worth.
there is a 50% difference in value 0 being 100mS and a 1 being 200mS so a pulsin will read these values with ease.
do a pulsin loop, read the value figure which it is a 0 or 1 store it in a bit value and return to the top of the pulsin loop.
the biggest pulse is 200mS that gives you 800mS to do your compare and store your value in a bit variable you may have too much time and could serout or debug out the bits one at a time as pulsin times out at .131mS if no pulse is seen.

' {\$STAMP BS2}
' {\$PBASIC 2.5}

sync VAR Word

Sync_Second:
DO
PULSIN 1,0,sync
LOOP WHILE sync > 100
• Posts: 242
edited 2009-10-07 15:21
This is the way Im thinking, try something like this below. now it can be cleaned up but Im trying to show the Idea.

this is close to the way you would read the value of IR remote control, work with this a little and see if you can make it work.

sync_second if sync second returns a value of 0 or 100 or less then its in the blank second and you should go to read_pulses now you may need a debug at the end of this section saying start or something, as the pulsin will end in .131mS and you have over 800mS of wait time·before the start of the first read. and then you just start reading the values as there sent, you will need to format the debug statement for your own needs try to get all values on one line. You will maybe need a counter that will stop at 58 and go back to the sync_second loop. you could even use The timing lines from Tracy Allens site instead of pulsin.· Im seeing a couple of ways to do this.

' {\$STAMP BS2}
' {\$PBASIC 2.5}

sync· VAR Word
value VAR Word

Sync_Second:
DO
PULSIN 1,0,sync
LOOP WHILE sync > 100

READ_Pulses:
DO
PULSIN 1,0,value
IF value > 300 THEN
value = 1
ELSE
value = 0
ENDIF
DEBUG value
LOOP
• Posts: 381
edited 2009-10-07 16:02
Hi

The problem with PULSIN is that the max. pulse width for the BS2pe is 123.6 ms. In your example, with BS2, it's 131.07 ms. PULSIN won't catch the 200ms signal. If PULSIN doesn't detect the signal, OR it times out because pulse width is too long, it will return 0.

I'm not sure your program logic will be adequate, even if PULSIN supported a longer pulse width.

In any case, I'm sceptic of having a Stamp measuring things which needs highly accurate timing signals. You are generally safer when adding external circuitry. The 555 timers will work "offline", so you can do some processing while they do their thing.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't worry. Be happy

Post Edited (dev/null) : 10/7/2009 4:08:10 PM GMT
• Posts: 242
edited 2009-10-07 17:00
Well I admit I did not see the bs2pe and have no timings for this chip, I still use stamp manual 1.9 maybe I should update!!! maybe not

as far as highly accurate timing signals this is not, all you need is to know if its 100mS or 2x longer, and make it a 1 or 0. So if the pulsin value is greater than lets say 105, 110, 115 or 120 mS then its a one if not its a 0 the actual value is not needed we just need to know if its longer, now 105mS may be too close but you see anything above a threshold is a one. so it could be if value >50 then value = 0 else value = 1 Or better yet look for the 0 zero value in pulsin if value = 0 then value = 1 else value = 0 you get a zero value if the pulse is longer than 123.6mS

Ok I admit, I just HATE 555's and will try anything before using one, in fact I don't think I have ever used one! I will even use a cd4060 with resinator for IR instead of 555 so its out and now you can see my resistance to this, ( I read 555 and started shaking)

Now these are possibilities and things I would try first, along with Tracy Allen's timer loop, rather than building another circuit first.
• Posts: 323
edited 2009-10-07 17:26
ok Larray, i will try your pulsin example tomorrow.

thx
• Posts: 381
edited 2009-10-07 21:43
I see Larry, that might actually work. Have a go at it Tumbler. If it works, it's easier than building 555 circuits, allltough circuits like that are pretty simple.

I'd rather leave out PULSIN and just do:
(I am assuming you get HIGH and LOW signals from your device Tumbler):

```' {\$STAMP BS2pe}
' {\$PBASIC 2.5}

TheBit       VAR Bit
BitCounter   VAR Byte
Counter      VAR Byte
Hours        VAR Byte

' Wait for minute start sequence (a HIGH signal for 950 ms will do)
Init:
DO WHILE IN0 = 1
Counter = Counter + 1
PAUSE 10
IF Counter >= 95 THEN GOTO Main
LOOP
Counter =  0
GOTO Init ' Try again

' Get the bits
Main:

FOR BitCounter = 0 to 59

'  Check one bit
' -----------------------------------------------------------------
DO WHILE IN0 = 1 : LOOP        ' Wait for the signal to go low
TheBit = 0                     ' Default zero
PAUSE 150                    ' Pause 150 ms
IF IN0 = 0 THEN TheBit = 1     ' If signal is still low, it's a bit 1

' -----------------------------------------------------------------
' I have my bit and can do something with it
' DO SOMETHING
SELECT CASE BitCounter
CASE 29 : Hours.bit0 = TheBit
CASE 30 : Hours.bit1 = TheBit
CASE 31 : Hours.bit2 = TheBit
CASE 32 : Hours.bit3 = TheBit
CASE 33 : Hours.bit4 = TheBit
CASE 34 : Hours.bit5 = TheBit
ENDSELECT
' Make sure it doesn't take longer than about 750 ms, or this won't work
' -----------------------------------------------------------------

PAUSE 100                       ' Make sure the signal has gone HIGH again

NEXT

GOTO Main

```

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't worry. Be happy

Post Edited (dev/null) : 10/8/2009 8:16:22 AM GMT
• Posts: 323
edited 2009-10-08 08:16
The init is not working properly, a timing isue i guess.
I replaced it with my init routine.
Now it receives 0's and 1's, but also a timing prob or maybe some noise in the signal (wich i can't measure)

Yes dev/null, i get High's and Low's [noparse]:)[/noparse]
• Posts: 381
edited 2009-10-08 11:45
An oscilloscope is very useful when working with signals!

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't worry. Be happy
• Posts: 242
edited 2009-10-11 17:49
Ok gotta know
Did you ever find out what time it was??
• Posts: 323
edited 2009-10-11 19:10
When i take at the clock:· 21:11 (right now)
• Posts: 3

Voici un simple décodage du signal DCF77.5 Khz avec un BS2p24 tout simplement

Explications :

1) Le signal reçu et mis en forme avec un circuit CMOS de type Trigger de schmitt
2) On attends le flanc montant du signal reçu (à tous moment) à l'aide d'une variable

' {\$STAMP BS2p}
' {\$PBASIC 2.5}

' Prog_001 RoueDCF.bpx (BS2p24)

' Début programme
' Analyse sur l'entrée de P0, le signal si il est montant, début d'une seconde
' La boucle1 tourne sur elle même pour trouver un flanc montant induquand un 0 ou un 1
' Troisième programme, compte la durée d'une seconde reçues de 1 à nx
' Prépare les octets à envoyer au MAX7219

' P0 = input signal DCF77.5 Khz

' H15 L0 '1=Output, 0=Input
DIRS = %0000000000000000

' Réservation des variables

dubit VAR Word ' valeur recue en durée pour identifier '0' ou '1'
espace VAR Word ' valeur recue en durée entre 0/1 (id 59)
recbit VAR Bit ' valeur 0 ou 1
minutes VAR Byte ' 0-59 secondes = 6 adresses recues
i VAR Nib ' 0-7 [0-15]
indbit VAR Byte ' 0 - 59
t VAR Byte(8) ' tableau de 8 octets (puissance 1,2,4,8,16,32,64,128)
e VAR Byte(8) ' tableau de 8 octets
sortie VAR Byte ' octet de sortie à écrire dans le MAX7219 (Registres)
Registre VAR Nib ' 0-7
Y VAR Byte

' Tableau t(i) de puissance de 2
t(0) = 1
t(1) = 2
t(2) = 4
t(3) = 8
t(4) = 16
t(5) = 32
t(6) = 64
t(7) = 128

' Début programme
dubit = 0 ' Initialise le compteur de durée pulse '0' ou '1' à zéro

' Première boucle
Boucle1:
espace = espace + 1
IF IN0 = 1 THEN ana1 ' sort au signal montant du premier '0' ou '1' recu
GOTO boucle1

' Deuxième boucle, durée pulse reçue
ana1:
IF IN0 = 1 THEN
dubit = dubit + 1 ' durée totale du '0' ou du '1' reçu
GOTO ana1
ENDIF

'minutes = minutes + 1 ' incrémente de une adresse par seconde recue
IF dubit < 400 THEN
Recbit = 0
ENDIF

IF dubit > 401 AND dubit < 800 THEN
recbit = 1
ENDIF

minutes = minutes + 1

IF espace > 4500 THEN ' id synchro 59 ème minutes
recbit = 0
minutes = 59
i = 0
Registre = 0
ENDIF

'................................................................

' Bit reçu '0' ou '1' à additionner dans un octet
IF recbit = 0 THEN ' Bit reçu
e(i) = 0 ' Si reçu '0' = valeur '0'
ELSE
'READ i, Y

'DEBUG "i= ",DEC i, " Y= ",DEC Y,CR

e(i) = t(i) ' Si reçu '1' = valeur du tableau selon passage avec 'i'
'e(i) = 2^i ' Si reçu '1' = valeur du tableau selon passage avec 'i'
ENDIF

' Sommation des sorties de puissances de 2 (bin)
sortie = e(7)+e(6)+e(5)+e(4)+e(3)+e(2)+e(1)+e(0)

IF i > 7 THEN
i = 0 ' Pointeur du tableau de réception pour former l'octet
Registre = Registre + 1 ' Numéro du Registre 0 - 7 Y dans le MAX7219
ENDIF

IF minutes > 59 THEN minutes = 0

DEBUG DEC recbit," ",DEC2 minutes," ",BIN8 sortie,
" i= ",DEC i," t(i)= ",DEC t(i)," R= ",DEC registre," e(i)= ",DEC e(i),CR

'Remettre le compteur à zéro
dubit = 0
espace = 0
i = i + 1

GOTO boucle1 ' Recommencer au début d'une seconde

END

• Posts: 3

Voici un simple décodage du signal DCF77.5 Khz avec un BS2p24 tout simplement

Explications :

1) Le signal reçu et mis en forme avec un circuit CMOS de type Trigger de schmitt.

2) On attends le flanc montant du signal reçu (à tous moment) à l'aide d'une variable 'espace' (voir la boucle1)

3) On crée une deuxième boucle avec (dubit) = durée du bit reçu

4) Si la durée de boucle avec la variable dubit est plus petite que 400 points, c'est que l'on a reçu une valeur data '0'.

``` Si la durée de boucle avec la variable dubit est plus grande que 400 points (max 800 points), c'est que l'on a reçu une valeur data '1'.
```

5) A ce moment du programme, on dispose de la seconde (signaux reçu '0' ou '1'), on peut enregistrer ces valeurs data dans un tableau de variables, j'utilise la RAM ScratchPad interne au BS2p24.

6) Avec la variable 'espace' on décode l’absence de la porteuse qui correspond à la 59ème seconde.

```  IF espace > 4500 THEN nous donne la synchronisation 59ème seconde, en même temps, une adresse de synchronisation au moment de sa détection ce qui nous permet d'écrire les data reçu aux bonnes adresses pour un décodage correcte.
```

7) il n'y a plus qu'à recommencer l'opération compète de la trame suivante et de passer les 700 à 800 ms qui reste pour le décodage des infos hms, jma et plus.

Au plaisir de vous lire pour une discution avec vous.

' {\$STAMP BS2p}
' {\$PBASIC 2.5}

' Prog_001 RoueDCF.bpx (BS2p24)

' P0 = input signal DCF77.5 Khz

' H15 L0 '1=Output, 0=Input
DIRS = %0000000000000000

' Réservation des variables

dubit VAR Word ' valeur recue en durée pour identifier '0' ou '1'
espace VAR Word ' valeur recue en durée entre 0/1 (id 59)
recbit VAR Bit ' valeur 0 ou 1
minutes VAR Byte ' 0-59 secondes = 6 adresses recues
i VAR Nib ' 0-7 [0-15]
indbit VAR Byte ' 0 - 59
t VAR Byte(8) ' tableau de 8 octets (puissance 1,2,4,8,16,32,64,128)
e VAR Byte(8) ' tableau de 8 octets
sortie VAR Byte ' octet de sortie à écrire dans le MAX7219 (Registres)
Registre VAR Nib ' 0-7
Y VAR Byte

' Tableau t(i) de puissance de 2
t(0) = 1
t(1) = 2
t(2) = 4
t(3) = 8
t(4) = 16
t(5) = 32
t(6) = 64
t(7) = 128

' Début programme
dubit = 0 ' Initialise le compteur de durée pulse '0' ou '1' à zéro

' Première boucle
Boucle1:
espace = espace + 1
IF IN0 = 1 THEN ana1 ' Sort au signal montant du premier '0' ou '1' recu
GOTO boucle1

' Deuxième boucle, durée pulse reçue
ana1:
IF IN0 = 1 THEN
dubit = dubit + 1 ' durée totale du '0' ou du '1' reçu
GOTO ana1
ENDIF

'minutes = minutes + 1 ' incrémente de une adresse par seconde recue
IF dubit < 400 THEN
Recbit = 0
ENDIF

IF dubit > 401 AND dubit < 800 THEN
recbit = 1
ENDIF

minutes = minutes + 1

IF espace > 4500 THEN ' id synchro 59 ème minutes
recbit = 0
minutes = 59
i = 0
Registre = 0
ENDIF

'................................................................

' Bit reçu '0' ou '1' à additionner dans un octet
IF recbit = 0 THEN ' Bit reçu
e(i) = 0 ' Si reçu '0' = valeur '0'
ELSE
'READ i, Y

'DEBUG "i= ",DEC i, " Y= ",DEC Y,CR

e(i) = t(i) ' Si reçu '1' = valeur du tableau selon passage avec 'i'
'e(i) = 2^i ' Si reçu '1' = valeur du tableau selon passage avec 'i'
ENDIF

' Sommation des sorties de puissances de 2 (bin)
sortie = e(7)+e(6)+e(5)+e(4)+e(3)+e(2)+e(1)+e(0)

IF i > 7 THEN
i = 0 ' Pointeur du tableau de réception pour former l'octet
Registre = Registre + 1 ' Numéro du Registre 0 - 7 Y dans le MAX7219
ENDIF

IF minutes > 59 THEN minutes = 0

DEBUG DEC recbit," ",DEC2 minutes," ",BIN8 sortie,
" i= ",DEC i," t(i)= ",DEC t(i)," R= ",DEC registre," e(i)= ",DEC e(i),CR

'Remettre le compteur à zéro
dubit = 0
espace = 0
i = i + 1

GOTO boucle1 ' Recommencer au début d'une seconde

Alain Pilloud / Suisse ( pilloud.alain.123456789@gmail.com)

Sign In or Register to comment.