- fchao-Sinus-Wechselrichter AliExpress         
Seite 1 von 4 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 35

Thema: DCF77 Funksignal auslesen

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64

    DCF77 Funksignal auslesen

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,

    ich hab mir jetzt mal den DCF-Empfängerbusatz von Conrad zugelegt und versuche nun, mit dessen Hilfe zunächst einmal nur die einzelnen Bits des DCF-Signals einzulesen und über die serielle Schnittstelle auszugeben. Ich glaube ich mache beim einlesen nur ein paar Fehler oder aber ich habe den Wikipedia Artikel zum DCF-Signal etwas falsch interpretiert.
    Hier erstmal mein Code:

    Code:
    #include <avr/io.h>
    
    #define BAUD 9600UL
    
    #include "../classes/rs232/UART/UART.h"
    #include "../classes/time/time.h"
    
    int main(void)
    {
    uint8_t i=0;
    uint8_t c=0;
    char dcf[60];
    dcf[0]='\0';
    
    DDRC&=~(1<<PC0);		//EINGANG PC0
    PORTC|=(1<<PC0);		//PULLUP aktivieren
    
    uart_init();
    
    while(1)
    {
    	if(i<=59)
    	{
    
    		while(!(PINC & (1<<PC0)))	//wenn Signal (LOW) kommt
    		{
    		 wait_msec(1);
    		 c++;
    		}
    
    		if(c<=100)					//100msec == 0
    		{
    		dcf[i]='0';
    		}
    		
    		if(c<=200 && c>100)					//200msec == 1
    		{
    		dcf[i]='1';
    		}
    		c=0;
    
    	i++;
    	}
    	else
    	{
    	dcf[i]='\0';
    	send(dcf);
    	i=0;
    	}
    }
    
    return 0;
    }
    Wikipedia habe ich so verstanden, dass wenn 100millisekunden ein LOW-Signal kommt, eine binärische 0 gesendet wird und ab 200millisekunden eine 1. Mein Problem ist nur, dass wenn ich das ganze laufen lasse fast immer die erste Stelle eine 1 ist und alle anderen Stellen eine 0. Was genau mache ich falsch? Kann mir bitte jemand sagen, wie man sowas am Besten machen könnte.

    Gruß
    cesupa

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Versuch mal folgendes:

    Einfach 10ms warten und dann einen Wert hochzählen abhängig vom Portzustand.

    Ist der Wert ~10 ist es eine 0, bei ~20 ist es eine 1. Um zu sehen, ob überhaupt ein vernünfitiges Signal ankommt, kannst du in der Warteschleife (oder alle 10ms) den Port-Zustand an einen anderen Port ausgeben, an dem zB eine LED hängt.

    Einen etwas komplizierteren DCF-Decoder findest du auf meiner HP wenn das was hilft.
    Disclaimer: none. Sue me.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    okay, ich hab jetzt mal ne LED in die while-Schleife gehangen, die blinkt auch wie es eigentlich sein sollte, aber dennoch erhalte ich die gleichen Werte. Komischerweise wird das Wertepaket viel zu schnell hintereinander ausgegeben.

    Gruß
    cesupa

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    lso was ich überhaupt net verstehe ist
    Code:
    while(!(PINC & (1<<PC0)))   //wenn Signal (LOW) kommt
    Disclaimer: none. Sue me.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    Naja, hab ich eigentlich schon erwähnt, dass ich eigentlich noch ein Anfänger bin? Ich hab das halt mit Wiki so verstanden, dass mein DCF-Empfänger von Conrad 100ms kein Signal schickt, wenn eine binäre 0 empfangen wurde und bei 200ms eine 1. Da dachte ich mir halt, dass das Ding nur dann ein Signal schickt, also HIGH, wenn 100ms oder eben 200ms um sind. Ich merke aber gerade, dass das wohl irgendwie nicht hinhauen kann wenn man das in einer Schleife überprüft, da ja in diesen 10ms Wartezeit bereits ein HIGH Signal kommen kann, welches nicht beachtet wir. Ich hab mir die Variable c auch mal ausgeben lassen und festgestellt, dass ein Großteil der c-Werte ständig eine 0 ist. Also anscheinend fehlt mir noch ein wenig grundlegendes Verständnis. Kannst du mir sagen, wie das mit DCF läuft und wie man die Werte am besten registriert?

    Gruß
    cesupa

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    Ich hab den Code auch nochmal ein wenig geändert, außerdem hab ich noch vergessen zu sagen, dass ich den invertierten DCF-Ausgang benutze.

    Code:
    #include <avr/io.h>
    
    #define BAUD 9600UL
    
    #include "../classes/rs232/UART/UART.h"
    #include "../classes/time/time.h"
    
    int main(void)
    {
    uint8_t i=0;
    uint8_t c=0;
    char dcf[60];
    char buf[256];
    buf[0]='\0';
    dcf[0]='\0';
    
    DDRC&=~(1<<PC0);		//EINGANG PC0
    DDRD|=(1<<PD5) | (1<<PD6);
    PORTC|=(1<<PC0);		//PULLUP aktivieren
    
    uart_init();
    
    i=0;
    c=0;
    while(1)
    {
    	if(i<=59)
    	{
    		while((PINC & (1<<PC0)))
    		{
    		PORTD|=(1<<PD5);
    		PORTD&=~(1<<PD6);
    		_delay_ms(10);
    		c++;
    		}
    	
    		PORTD&=~(1<<PD5);
    		PORTD|=(1<<PD6);
    	
    	
    if(c>=8 && c<=23)
    {
    	if(c<=10)					//100msec == 0
    		{
    		dcf[i]='0';
    		}
    		
    		if(c>10)					//200msec == 1
    		{
    		dcf[i]='1';
    		}
    
    
    		c=0;
    
    	i++;
    }
    	}
    	else
    	{
    	dcf[i]='\0';
    	send(dcf);
    	send("\r\n");
    	i=0;
    	}
    }
    
    return 0;
    }
    Mit dem Code erhalte ich nach ca. 3-4 Minuten recht anschauliche Werte. Zumindest, wurden einige Teile, wie zum Beispiel die Minuten korrekt interpretiert.

    Gruß
    cesupa

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    Hallo SprinterSB,

    ich hab mir jetzt mal deinen Code ein wenig angeschaut und hab gesehen, dass du das DCF-Signal alle 10ms einliest. Aber mir ist noch nicht ganz so klar was du mit dem Signal danach machst? Ich hab das Signal jetzt auch mal aus einer ISR heraus alle 10ms eingelesen und mir über RS232 ausgeben lassen. Dabei kam folgendes raus:

    Code:
    101001011010110101110010110101101001000101101011010010001111
    
    010110100011010110101001010110101111010110101100010110101111
    
    010110100011010110101001010110101111010110101100010110101111
    
    111001011010110101010010101101011000101101010110001111010110
    
    100010010110101101000110101011010010101101011010010110101101
    Wie man sieht, sind die doch eigentlich recht unterschiedlich. Eine Uhrzeit konnte ich aus den Bits auch noch nicht (vollständig) auslesen. Muss ich diese Bitfolgen noch irgendwie bearbeiten, um die korrekten Bits zu erhalten???

    Gruß
    cesupa

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803

    DCF Decodierung

    Hallo cesupa,

    willkommen bei den DCF-Decodierern!

    Deine Ausgabe der Bits, die du empfangen hast, ist eher ein Zufallsprodukt, weil du nicht den Anfang eines Minutentelegramms hast.

    Wichtig ist es, das ENDE des Bitstreams zu erkennen. Das geht nicht über das Detektieren der Impulse (100/200ms), sondern der Pausen (900/800ms). Ich würde also das Prog umschreiben, so dass es die Pausen erkennt.

    Das Ende der Minute (und des DCF-Telegramms) ist dann erreicht, wenn du eine Pause von 1800 oder 1900ms erkannt hast. Danach stellst du deinen Bitzähler auf 0 (= Zeilenanfang) und das neue Telegramm beginnt. Das ist auch der Zeitpunkt, wo dein fertiger Decoder später die Uhr stellt.

    Wenn du so weit bist, melde dich doch wieder mit einigen empfangenen Bitstreams. Jeder muss automatisch (ohne eine begrenzende Schleife!) genau 59 Bit Länge haben.

    Gruß Dirk

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    Okay, danke, sowas kann man z.B. nicht bei Wikipedia oder sonst wo lesen Also Danke Dirk, ichwerds gleich mal versuchen.

    Gruß
    cesupa

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    01.07.2005
    Beiträge
    64
    So, hab mir jetzt mal schnell eine Routine überlegt mit der man das ganze lösen könnte, nur leider funktioniert die nicht so wie sie sollte, dass heißt ich bekomme nur Nullen ausgegeben. Hier die Routine, die aller 0,01ms bearbeitet wird:

    Code:
    t++;							//Timer++ (0,01ms)
    
    if(!(PINC & (1<<PC0)))			//Kein Impuls==Pause
    {
    
    if(t<=80000)					//Wenn kleiner gleich 800ms
    {
    dcf='0';
    }
    
    if(t>=90000)					//Wenn größer gleich 900ms
    {
    dcf='1';
    }
    
    }
    else							//Impuls==timer zurücksetzen
    {
    if(dcf=='0' || dcf=='1')		//Wenn Zeichen empfangen
    r='2';							//Signal geben zum Senden über RS232
    t=0;							//Timer zurücksetzen
    }
    Wie sieht eine Pause eigentlich aus bei einem DCF-Empfänger. Hier im Code hab ich eine Pause jetzt so interpretiert, dass eben gar nichts gesendet wird, also 0V am Eingangspin anliegen. Bei einem Impuls jedoch, also größer als 0V wird das empfangene Zeichen an den PC übergeben und der Timer resetted. Mach ich da schon irgendwas falsch oder wieso erhalte ich nur Nullen?

    Gruß
    cesupa

Seite 1 von 4 123 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen