DCF77 signal
Tumbler
Posts: 323
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
·
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
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
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.
' 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
After some test with rctime, pulsin and branch,i got this.
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...
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
I think i have to build something like dev/null said.
thx
Post Edited (Tumbler) : 10/7/2009 10:43:04 AM GMT
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
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
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
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.
thx
I'd rather leave out PULSIN and just do:
(I am assuming you get HIGH and LOW signals from your device Tumbler):
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't worry. Be happy
Post Edited (dev/null) : 10/8/2009 8:16:22 AM GMT
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]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Don't worry. Be happy
Did you ever find out what time it was??
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
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'.
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.
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)