- LiFePO4 Speicher Test         
Seite 4 von 4 ErsteErste ... 234
Ergebnis 31 bis 35 von 35

Thema: DCF77 Funksignal auslesen

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

    LiFePo4 Akku selber bauen - Video
    Hey super, ich habs hingekriegt. Das Problem lag einfach daran, dass ich die Bits vor der eigentlichen Zeit vernachlässigt hab, dadurch hab ich die Daten 20Bits zu früh in meine struct eingelesen.
    Danke euch allen für eure große Hilfe

    Schöne Grüße
    cesupa

  2. #32
    Neuer Benutzer Öfters hier
    Registriert seit
    04.10.2007
    Alter
    40
    Beiträge
    17
    Hallo,

    bin auch noch Anfänger und versuche gerade das DCF Signal zu verarbeiten. Ich Frage den Portzustand über einen Interrupt alle 20ms ab. Das erkennen der Pausen 800/900/1800/1900 klappt soweit auch sehr gut. Bekomme immer Werte +- 20 ms per RS232 am PC angezeigt.

    Wie ich jetzt die Pausenlänge den 0/1en zuordnen soll usw. versteh ich jetzt aber net. Hab schon bissl was probiert aber nichts hat geklappt. Per if im Hauptprogramm mit <= und >= Abfragen hat das nicht geklappt. Wäre sehr nett wenn ihr mir da einen Tipp geben könntet und euch mal das Programm bis jetzt anschaut.

    Lässt sich bestimmt einiges noch verbessern aber bin schonmal ganz glücklich das die richtigen Pausen erkannt werden ^^

    Code:
    #include "avr/io.h"
    #include "function.h"
    #include <avr/interrupt.h>
    
    volatile uint16_t dcf_time = 0;
    uint8_t dcf_before = 1;
    uint8_t dcf_flag = 0;
    char dcf_t[4];
    
    
    int main (void) 
    {
    
    	//Port Konfiguration DCF77 Empfänger
    
    	dcf_ddr &= ~(1<<dcf_bit);		//PinX als Eingang definieren
    	dcf_port |= (1<<dcf_bit);		//Pullup Widerstand für diesen Pin aktivieren
    	
    
    
    	//Debug Konfiguration, LED1, LED2
    
    
    	DDRC |= (1<<0) | (1<<1);		//Bit0 PortC Ausgang
    	PORTC |= (1<<0) | (1<<1);		//Led an PortC aus	
    
    	//Timer 1 starten, Globale Interrups aktivieren
    	init_timer();
    	//USART initialisieren
    	init_USART();
    
    
    	/*###############################################
    	#												#
    	#	Hauptprogramm								#
    	#												#
    	################################################*/
    
    	while(1)
    	{
    	
    		
    		//##################### DEBUG ### LED1 zeigt DCF77 Signal#####################
    		if (dcf_pin & (1<<dcf_bit))
       		PORTC |= (1<<0);							// Ausführen wenn HIGH
    		else
       		PORTC &= ~(1<<0);							// Ausführen wenn LOW
    		//############################################################################
    		
    	}
       return 0;
    }
    
    
    
    
    
    //Portzustand DCF77 einlesen und in dcf_flag schreiben
    int get_dcf_bit()
    {
    	if (dcf_pin & (1<<dcf_bit))
    	{
    		dcf_flag = 1;
    
    	}else{
    		dcf_flag = 0;
    
    	}
    	return(dcf_flag);
    	
    }
    	
    SIGNAL (SIG_OUTPUT_COMPARE1A)
    {	
    	PORTC ^= (1<<1);		//DEBUG Zeige Frequenz vom Timer-Interrupt an LED2
    	get_dcf_bit();			//Pegel vom DCF Signal einlesen und in dcf_flag speichern
    	
    	if(dcf_flag == 1)		//Wenn DCF Signal HIGH > Zeit messen
    	{
    		if(dcf_flag == dcf_before)		//Führe aus, wenn sich Pegel nicht geändert hat
    		{		
    			dcf_time += 20;				//Zeit +20ms
    		}else{							//Führe aus bei Pegeländerung
    			itoa(dcf_time, dcf_t, 10);	
    			sendUSART(dcf_t);
    			sendUSART(" \r\n");
    			dcf_time = 0;				//Zeitvariable zurücksetzen
    		}
    	}
    
    	dcf_before = dcf_flag;				//Alten Pegel in der Variable dcf_before speichern
    }
    Hier mal ein Ausschnitt vom PC und den Zeiten
    Code:
    800 
    920 
    800 
    880 
    900 
    900 
    800 
    900 
    780 
    900 
    800 
    880 
    900 
    880 
    900 
    880 
    800 
    880 
    800 
    800 
    900 
    900 
    900 
    920 
    880 
    800 
    900 
    900 
    900 
    900 
    1900 
    900 
    800 
    800 
    880 
    880
    lg
    Wasserkäfer

  3. #33
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hallo Wasserkäfer,

    das sieht doch schon gut aus! Du kannst 0-Bits (880..920) und 1-Bits (780..800) gut erkennen und auch das Minutenbit (1900), das auch ein 0-Bit ist.
    Wenn du die mit einer größer/kleiner-Bedingung testest (Grenze z.B. 850: Wenn größer, dann 0-Bit. Wenn kleiner, dann 1-Bit). Für das Protokollende kannst du genauso testen mit der Grenze 1850.

    Die Bits (0/1) schiebst du dann in eine Variable, deren Wert du immer dann auswerten must, wenn ein Minuten/Stunden... Wert erreicht ist. Man erkennt das durch einen DCF-Bitzähler, der bei jedem Bit inkrementiert wird und nach dem Minutenbit auf 0 gesetzt wird.

    Viel Erfolg. P.S.: In der ISR sollte es keine USART Aufrufe geben, die dauern zu lange.

    Gruß Dirk

  4. #34
    Neuer Benutzer Öfters hier
    Registriert seit
    04.10.2007
    Alter
    40
    Beiträge
    17
    Vielen Dank Dirk

    Mittlerweile emfpange ich das DCF Signal und es klappt auch über die RS232 ausgabe. Die USART Aufrufe stehen nur aus Debugzweck noch in der ISR. Im späteren Programm fällt das natürlich weg.

    Da ich mir jetzt mehrere Strings schon per USART anzeigen hab lassen sind gleich zwei weitere Fragen aufgetaucht :P

    1. Wie kann ich sicherstellen, das der µC nur korrekt Empfangen Daten verarbeitet? Mir sind da mal 2 Möglichkeiten eingefallen: Über die Parity Bits wo ich aber noch nicht weis wie man die Quersumme bildet ^^ oder erkennen ob die Zeiten innerhalb der normalen Grenzen liegen 800/900 ms etc. Liegt schlechter Empfang vor ist die Zeit meist wesentlich kürzer/länger was mir so aufgefallen ist.

    2. Wie wandel ich den String in meine Minuten/Stunden usw. um?
    Dachte mir ein Unterprogramm, dass z.B Bit 21 - 27 nach 0 oder 1 abfrägt und dann jeweils 1,2,4,8,10,20,40 addiert.

    Momentan speicher ich die kompletten 59 Bits aber eigentlich kann ich mir die ersten 19 Bits doch sparen. Mit den Informationen kann ich ja nichts anfangen.

    Mein momentanes Programm und ein paar Empfangene Signale:

    Code:
    #include "avr/io.h"
    #include "function.h"
    #include <avr/interrupt.h>
    
    volatile uint16_t dcf_time = 0;
    uint8_t dcf_before = 1;
    uint8_t dcf_flag = 0;
    uint8_t dcf_ctr = 0;
    uint8_t dcf_end;
    char dcf_t[4];
    char dcf[60];
    
    
    int main (void)
    {
    
       //Port Konfiguration DCF77 Empfänger
    
       dcf_ddr &= ~(1<<dcf_bit);      //PinX als Eingang definieren
       dcf_port |= (1<<dcf_bit);      //Pullup Widerstand für diesen Pin aktivieren
       
    
    
       //Debug Konfiguration, LED1, LED2
    
    
       DDRC |= (1<<0) | (1<<1);      //Bit0 PortC Ausgang
       PORTC |= (1<<0) | (1<<1);      //Led an PortC aus   
    
       //Timer 1 starten, Globale Interrups aktivieren
       init_timer();
       //USART initialisieren
       init_USART();
    
       /*###############################################
       #                                 			   #
       #   Hauptprogramm                 		       #
       #                                 			   #
       ################################################*/
    
       while(1)
       {
       
          
          //##################### DEBUG ### LED1 zeigt DCF77 Signal#####################
          if (dcf_pin & (1<<dcf_bit))
             PORTC |= (1<<0);                     // Ausführen wenn HIGH
          else
             PORTC &= ~(1<<0);                     // Ausführen wenn LOW
          //############################################################################
    
          
       }
       return 0;
    }
    
    
    
    
    
    //Portzustand DCF77 einlesen und in dcf_flag schreiben
    int get_dcf_bit()
    {
       if (dcf_pin & (1<<dcf_bit))
       {
          dcf_flag = 1;
    
       }else{
          dcf_flag = 0;
    
       }
       return(dcf_flag);
       
    }
       
    SIGNAL (SIG_OUTPUT_COMPARE1A)
    {   
       PORTC ^= (1<<1);      //DEBUG Zeige Frequenz vom Timer-Interrupt an LED2
       get_dcf_bit();         //Pegel vom DCF Signal einlesen und in dcf_flag speichern
       
       if(dcf_flag == 1)      //Wenn DCF Signal HIGH > Zeit messen
       {
          if(dcf_flag == dcf_before)      //Führe aus, wenn sich Pegel nicht geändert hat
          {      
             dcf_time += 20;            //Zeit +20ms
          }else{                     //Führe aus bei Pegeländerung
    
    	  	if(dcf_time < 850)		//Erkenne Pause von 800 ms = logisch 1
    		{	
    			dcf[dcf_ctr] = '1';
    			dcf_ctr++;
    		}
    		if(dcf_time > 850 && dcf_time < 1000)		//Erkenne Pause von 900 ms = logisch 0
    		{
    			dcf[dcf_ctr] = '0';
    			dcf_ctr++;
    		}
    
    
    		if(dcf_time > 1000 && dcf_time < 1850)		//Erkenne Pause von 1800 ms = logisch 1, Ende der Übertragung
    		{
    			dcf[dcf_ctr] = '1';
    			sendUSART(dcf);
    			sendUSART("\r\n");
    			dcf_ctr = 0;
    		}
    		if(dcf_time > 1850)			//Erkenne Pause von 1900 ms = logisch 0, Ende der Übertragung
    		{
    			dcf[dcf_ctr] = '0';
    			sendUSART(dcf);
    			sendUSART("\r\n");
    			dcf_ctr = 0;
    		}
    		
    
            dcf_time = 0;            //Zeitvariable zurücksetzen
          }
       }
       dcf_before = dcf_flag;            //Alten Pegel in der Variable dcf_before speichern
    }
    Code:
    00011011101101100100110010000111010010010010001100000100000
    00000011000000100100100001001111010010010010001100000100000
    10101000010101100100110001000111010010010010001100000100000
    00010111010011000100101001000111010010010010001100000100000
    00101001000001100100111001001111010010010010001100000100000
    01000011011011100100100101000111010010010010001100000100000
    10000011000111100100110101001111010010010010001100000100000
    00010011011000100100101101001111010010010010001100000100000
    11001001010100000100111101000111010010010010001100000100000
    Vielen Dank schonmal

  5. #35
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    Hallo Wasserkäfer,

    hast du dir 'mal meine C-Version für den RP6 angesehen?
    In der Lib (RP6BaseDCFLib) kann man gut sehen, wie ich das gemacht habe, z.B. auch mit der Parity.
    https://www.roboternetz.de/phpBB2/viewtopic.php?t=34240

    Gruß Dirk

Seite 4 von 4 ErsteErste ... 234

Berechtigungen

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

LiFePO4 Speicher Test