-
1. Data: 2019-05-09 08:04:43
Temat: Przykładowe ramki DCF77
Od: Atlantis <m...@w...pl>
Szukam, ale jakoś znaleźć nie mogę...
Potrzebuję przykładów poprawnych ramek DCF77, wraz z informacją na temat
tego, jaki czas jest w nich zakodowany. Chodzi mi po prostu o ciąg bitów.
Pracuję obecnie nad własną biblioteką do obsługi modułów DCF77
(częściowo opierając się na kodzie Arduino). Niby działa, jednak od
czasu do czasu pojawiają się problemu i dekodowany czas różni się od
poprawnego. Chciałem teraz zrobić krok w tył i sprawdzić poprawność
działania poszczególnych funkcji, kompilując je na PC, karmiąc
spreparowanymi danymi i obserwując wynik.
Niby protokół jest opisany, jednak chcę mieć pewność, że i podczas
preparowania ramki nie popełnię błędu...
-
2. Data: 2019-05-09 08:09:24
Temat: Re: Przykładowe ramki DCF77
Od: Mateusz Viste <m...@n...pamietam>
On Thu, 09 May 2019 08:04:43 +0200, Atlantis wrote:
> Niby działa, jednak od czasu do czasu pojawiają się problemu i
> dekodowany czas różni się od poprawnego. Chciałem teraz zrobić krok w
> tył i sprawdzić poprawność działania poszczególnych funkcji (...)
To pewnie dla ciebie oczywistość, ale podczas transmisji mogą występować
błędy... Zaufanie do pojedynczej ramki powinno być mocno ograniczone, a
czas ustawiony tylko wówczas, kiedy ciąg kilku ramek konsekwentnie
wskazuje bardzo zbliżony czas.
Mateusz
-
3. Data: 2019-05-09 10:48:58
Temat: Re: Przykładowe ramki DCF77
Od: Piotr Gałka <p...@c...pl>
W dniu 2019-05-09 o 08:04, Atlantis pisze:
> Pracuję obecnie nad własną biblioteką do obsługi modułów DCF77
> (częściowo opierając się na kodzie Arduino). Niby działa, jednak od
> czasu do czasu pojawiają się problemu i dekodowany czas różni się od
> poprawnego.
Może Ci się przyda.
Dawno, dawno temu (lata 95..97) zrobiłem odbiornik DCF podłączony pod
COM komputera (zasilanie też z COM). Odbiornik wystawiał sygnał z DCF na
którejś z linii RS232 i z tej linii go czytałem.
Trochę się naszukałem w starych plikach, ale znalazłem. Poniżej źródła.
Zauważyłem, że odwołuję się do doneinfo.h. Poszukałem co to takiego -
jakaś forma linijki pokazującej postęp procesu - nie ma związku z samym DCF.
Nie chce mi się wczytywać w szczegóły. Na pierwszy rzut oka widzę, że:
- RS232 obsługuję po adresach - tak się robiło pod DOS
- do odmierzania czasu używam wysyłania w koło czegoś po RS232
Przy ^C^V program pocztowy pozawijał niektóre linijki.
============================= plik DCF77.H ============================
// dcf77.h
// DCF77 class - odbior sygnalu DCF77 przez port RS232
#ifndef __DCF77_H
#define __DCF77_H
#ifndef __DONEINFO_H
#include "doneinfo.h"
#endif
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
class DCF77
{
DWORD blo; // bufory na zbierane bity
WORD bhi;
int addr; // adres portu
enum {DLL=0, // Divisor Latch Low byte
DLH = 1, // Divisor Latch High byte
IER = 1, // Interrupt Enable Register - zezw. na przerwania
IIR = 2, // Interrupt Identification Register
LCR = 3, // Line Control Register - tryb transmisji
MCR = 4, // Modem Control Register - set innych linii
LSR = 5, // Line Status Register - stan transmisji
MSR = 6}; // Modem Status Register - stan innych linii
int parity(WORD w); // sprawdzenie parzystosci slowa
public:
DCF77(int com); // konstruktor
int read(DoneInfo *d=0); // odbior DCF77 ret:n imp (<0-bledy)
int gettime(struct time *t); // odczytany czas ret:0-ok,1-err
int getdate(struct date* d); // odczytana data ret:0-ok,1-err
};
#endif // __DCF77_H
============================ plik DCF77.CPP ============================
// dcf77.cpp
// DCF77 class - odbior sygnalu DCF77 przez port RS232
#include <dos.h>
#include <conio.h>
#include "dcf77.h"
DCF77::DCF77(int com):blo(0),bhi(0)
{
static int adrt[4]={0x3F8,0x2F8,0x3E8,0x2E8}; // adresy COM-ow
int div=48; // predkosc 2400
int lcr=3; // format 8N1
int mcr=1; // DTR=1
addr=adrt[com];
outportb(addr+LCR,0x80); // Divisor Latch Access
outportb(addr,div&0xFF); // Divisor Latch low byte
outportb(addr+DLH,div>>8); // high byte
outportb(addr+LCR,lcr); // Line Control Register
outportb(addr+MCR,mcr); // Modem Control Register
outportb(addr+IER,0); // Interrupt Enable Register
inportb(addr); // wyczyszczenie bufora
outportb(addr,0); // zapelnienie bufora nadawczego
outportb(addr,0);
}
int DCF77::parity(WORD w)
{
w^=w>>8;w^=w>>4;w^=w>>2;w^=w>>1;
return w&1;
}
// zwraca:
// nb = liczba odebranych impulsow, powinno byc co najmniej 39 impulsow
// -1 = brak impulsow przez 5 sekund
// -2 = nie podlaczony odbiornik - szum zamiast impulsow
// -3 = brak konca
// -4 = klawisz
int DCF77::read(DoneInfo *d) // odbior DCF77
{
int b,b0=0x10,b1=0x10; // 0x10 -> dodatnie zbocze bedzie prawdziwe
int valid=0; // na poczatku pracy
int dn=0; // licznik petli w sekundzie DCF77
int lock=0; // blokowanie analizy linii wejsciowej
int down=0; // bylo ujemne zbocze
int nb=0; // licznik odebranych bitow
int ns=0; // licznik zmian stanu w czasie blokowania
// w jednej sekundzie miesci sie 240 nadan 2400B:8N1
static const
lockT=234, // blokada dla calego okresu (0.975s)
lockt=18, // blokada dla impulsu (0.075s)
lim2s=420, // czas dla znacznika konca (1.75s)
lim01=31, // prog rozroznienia 0/1 (0.13s)
lim5s=1200; // czas dla braku impulsow (5s)
bhi=0; // zeruje bufory wynikowe
blo=0;
if(d)d->limit(60); // po 59 impulsie czeka jeszcze 2s
while(1){
if(inportb(addr+LSR)&0x20){
outportb(addr,0); // teraz mamy troche czasu bez naruszania dn
if(down){ // bylo ujemne zbocze - przetwarzanie i info
blo>>=1;
if(bhi&1L)blo|=0x80000000L; // przeniesienie bitu
bhi>>=1;
if(dn>lim01)bhi|=0x8000; // wpisanie aktualnego bitu
nb++; // liczba odebranych bitow
if(d)d->done(nb); // to moze zajac czas (dlatego down)
down=0; // obsluzone
}
dn++; // licznik wyslanych przez RS232 bajtow w impulsie DCF
if(dn>lim5s)return -1; // brak impulsow
if(nb>60)return -3; // za duzo impulsow
if(kbhit()){getch();return -4;} // nacisniety klawisz
}
b=inportb(addr+MSR)&0x10; // sprawdzenie linii wejsciowej
if(dn>lock){ // tylko gdy nie ma blokady
if(b!=b0){ // zmiana stanu
b0=b; // nowy stan
if(valid){ // juz bylo pierwsze dodatnie zbocze
if(b){ // dodatnie zbocze
if(dn>lim2s)return nb; // koniec minuty (dn>1.75s)
lock=lockt; // blokada do 0.075s
}
else{ // ujemne zbocze
down=1; // flaga ujemnego zbocza
lock=lockT; // blokada do 0.975 s
}
}
if(b){valid=1;dn=0;}// juz bylo dodatnie zbocze i licznik od 0
b1=b;
ns=0;
}
}
if(b!=b1){ // nieoczekiwana zmiana stanu
b1=b;
if(++ns>9)return -2; // szum - nie podlaczony odbiornik
}
}
}
int DCF77::gettime(struct time *t) // odczytany czas ret:0-ok,1-err
{
int h,l;
if((blo&0x200)==0 || // nie ma bitu startu
parity(WORD((blo>>10)&0xFF)) || // parzystosc minut
parity(WORD((blo>>18)&0x7F)) )return 1; // parzystosc godzin
h=int((blo>>14)&7);l=int((blo>>10)&0xF);t->ti_min=h*
10+l;
if(h>5 || l>9)return 1; // zle wartosci dla minut
h=int((blo>>22)&3);l=int((blo>>18)&0xF);t->ti_hour=h
*10+l;
if(h>2 || l>9 || t->ti_hour>23)return 1; // zle wartosci dla godzin
t->ti_sec=0;
t->ti_hund=0;
return 0;
}
int DCF77::getdate(struct date* d) // odczytana data ret:0-ok,1-err
{
int h,l,y;
if((blo&0x200)==0 || // nie ma bitu startu
parity(WORD(blo>>25))^parity(bhi) )return 1;// parzystosc daty
h=int((blo>>29)&3);l=int((blo>>25)&0xF);d->da_day=h*
10+l;
if(l>9 || d->da_day>31)return 1; // zle wartosci dnia
h=(bhi>>6)&1;l=(bhi>>2)&0xF;d->da_mon=h*10+l;
if(l>9 || d->da_mon>12)return 1; // zle wartosci miesiaca
h=(bhi>>11)&0xF;l=(bhi>>7)&0xF;y=h*10+l;
if(h>9 || l>9)return 1;
d->da_year=(y<98)?2000+y:1900+y; // prawidlowo do 2097 roku
return 0;
}
-
4. Data: 2019-05-09 10:53:31
Temat: Re: Przykładowe ramki DCF77
Od: Piotr Gałka <p...@c...pl>
W dniu 2019-05-09 o 10:48, Piotr Gałka pisze:
> Przy ^C^V program pocztowy pozawijał niektóre linijki.
Ciekawe.
Przed wysłaniem były pozawijane. Jak po wysłaniu zajrzałem to nie są
pozawijane.
Nigdy nie zadałem sobie trudu rozejrzenia się w ustawieniach Thunderbirda.
P.G.
-
5. Data: 2019-05-09 12:36:38
Temat: Re: Przykładowe ramki DCF77
Od: Atlantis <m...@w...pl>
On 09.05.2019 08:09, Mateusz Viste wrote:
> To pewnie dla ciebie oczywistość, ale podczas transmisji mogą występować
> błędy... Zaufanie do pojedynczej ramki powinno być mocno ograniczone, a
> czas ustawiony tylko wówczas, kiedy ciąg kilku ramek konsekwentnie
> wskazuje bardzo zbliżony czas.
Tak. Biblioteka na której się opieram zawiera kilka "sanity checks".
Problem polega na tym, że błędy nie są wynikiem problemy nie są efektem
przekłamania w transmisji, ale jakiegoś błędu w kodzie. Przez to są one
powtarzalne i występują w kolejnych ramkach, prowadząc do zaakceptowania
błędnego czasu.
Próbuję ustalić w którym miejscu się tak dzieje. A ponieważ zmęczyło
mnie debugowanie na "żywym" układzie, w środku nocy, gdy propagacja się
podnosi, chcę to zrobić w sposób opisany powyżej. ;)
-
6. Data: 2019-05-09 12:40:22
Temat: Re: Przykładowe ramki DCF77
Od: Cezar <c...@t...pl.nospam>
On 09/05/2019 07:04, Atlantis wrote:
> Szukam, ale jakoś znaleźć nie mogę...
> Potrzebuję przykładów poprawnych ramek DCF77, wraz z informacją na temat
> tego, jaki czas jest w nich zakodowany. Chodzi mi po prostu o ciąg bitów.
> Pracuję obecnie nad własną biblioteką do obsługi modułów DCF77
> (częściowo opierając się na kodzie Arduino). Niby działa, jednak od
> czasu do czasu pojawiają się problemu i dekodowany czas różni się od
> poprawnego. Chciałem teraz zrobić krok w tył i sprawdzić poprawność
> działania poszczególnych funkcji, kompilując je na PC, karmiąc
> spreparowanymi danymi i obserwując wynik.
>
> Niby protokół jest opisany, jednak chcę mieć pewność, że i podczas
> preparowania ramki nie popełnię błędu...
>
tutaj masz cos co generuje DCF na GPIO (razem z szumem)
https://github.com/twam/dcf77gen
W tym repo masz bardzo duzo informacji jak walczyc z zakłóceniami:
https://github.com/udoklein/dcf77
-
7. Data: 2019-05-09 12:49:35
Temat: Re: Przykładowe ramki DCF77
Od: Cezar <c...@t...pl.nospam>
On 09/05/2019 07:04, Atlantis wrote:
> Szukam, ale jakoś znaleźć nie mogę...
> Potrzebuję przykładów poprawnych ramek DCF77, wraz z informacją na temat
> tego, jaki czas jest w nich zakodowany. Chodzi mi po prostu o ciąg bitów.
> Pracuję obecnie nad własną biblioteką do obsługi modułów DCF77
> (częściowo opierając się na kodzie Arduino). Niby działa, jednak od
> czasu do czasu pojawiają się problemu i dekodowany czas różni się od
> poprawnego. Chciałem teraz zrobić krok w tył i sprawdzić poprawność
> działania poszczególnych funkcji, kompilując je na PC, karmiąc
> spreparowanymi danymi i obserwując wynik.
>
> Niby protokół jest opisany, jednak chcę mieć pewność, że i podczas
> preparowania ramki nie popełnię błędu...
>
tutaj mozesz zobaczyć ramki na żywo, bit po bicie:
https://www.dcf77logs.de/live
-
8. Data: 2019-05-11 00:27:17
Temat: Re: Przykładowe ramki DCF77
Od: Atlantis <m...@w...pl>
On 09.05.2019 12:49, Cezar wrote:
> tutaj mozesz zobaczyć ramki na żywo, bit po bicie:
>
> https://www.dcf77logs.de/live
Dzięki. Właśnie tego potrzebowałem. ;)
-
9. Data: 2019-06-06 12:14:35
Temat: Re: Przykładowe ramki DCF77
Od: robot <a...@o...pl>
W dniu 2019-05-09 o 10:53, Piotr Gałka pisze:
> W dniu 2019-05-09 o 10:48, Piotr Gałka pisze:
>
>> Przy ^C^V program pocztowy pozawijał niektóre linijki.
>
> Ciekawe.
> Przed wysłaniem były pozawijane. Jak po wysłaniu zajrzałem to nie są pozawijane.
>
> Nigdy nie zadałem sobie trudu rozejrzenia się w ustawieniach Thunderbirda.
> P.G.
Już dawno to zauważyłem.
To widocznie standardowe zachowanie thunderbirda.