Forum: Mikrocontroller und Digitale Elektronik Erfahrungen mit RFM12 Datenübertragung


von mw2000 (Gast)


Lesenswert?

Hallo zusammen,

ich weiss das zum Thema RFM12 schon viele Beiträge im Forum stehen, aber 
ich habe keine Antwort auf meine Frage direkt gefunden.

Ich habe eine Datenübertragung mit RFM12 Modulen realisiert, welche sich 
16Byte Datenpakete austauschen. Der Code ist in c geschrieben und 
orientiert sich an den Beispielen in der Beschreibung von HopeRF.

Die Datenübertragung wird mit einer Prämbel gestartet und nach dem 
SyncWord werden 16Byte übertragen. Zum Abschluss wird ein Byte mit der 
CheckSumme gesendet, um sicherzustellen, dass die Daten i.O. sind.

Nun zur Frage:

Bei mir sind nur 80-85% der "valid" (Checksumme i.O.) in den restlichen 
versteckt sich kleinerer Datenmüll. Ist das ein Guter Wert oder könnt 
Ihr das besser?

Ich habe den ganzen Tag verschiedenste Test gemacht, komme aber nicht 
über diesen Wert.

Dinge die Verbesserungen brachten:
 - Datenbytes mit 0x00 durch 0xAA ersetzen

Dinge die keinen Einfluss hatten:
 - Zeitabstand mit dem die Paket folgten
 - Zeitabstand wischen den Bytes
 - Anzahl der Datenbytes verringern
 - Abstand zwischen den RFM Modulen (in der Wohnung)

Soweit erst einmal

Gruß

Matthias

von Maxx (Gast)


Lesenswert?

Ist jetzt nicht speziell zu den RFM12.

In einem solchen Fall würde ich statt des CRC eine Detektion nehmen, die 
auch Fehler korrigieren lässt. (Fehlerkorrekturcodes, wie Hamming-Codes)

Das sollte auch längere Folgen gleicher Bits vermeiden, die Probleme 
machen können, ohne dass man auf magic-number Ersetzungen zurückgreifen 
muss.

von roland (Gast)


Lesenswert?

Vielleicht verbessert das wenn die Bitwechsel öfters vorkommen.
Das mit dem 00>AA deutet das schon an.

http://de.wikipedia.org/wiki/Group_Coded_Recording

mfg Roland

von Peter R. (gelb)


Lesenswert?

Eventuell ist die Baudrate zu hoch? Mehr als 20..50kBaud hat bei mir 
noch nie gut funktioniert.

Mit 20kBaud sende ich Pakete mit 64 Byte + 2 Byte CRC und habe praktisch 
keine Probleme mit fehlerhaften Daten. (Bilddaten mit etwa 40kByte und 
entsprechend vielen Paketen im Handshake hintereinander)

Grüße, Peter

von R. W. (quakeman)


Lesenswert?

Ich betreibe die Datenübertragung in Paketen von 14 Bytes pro Paket mit 
9600 Bps und habe bei normalen Entfernungen keine Datenverluste. Ich 
benutze auch eine CRC am Ende um die Korrektheit der Daten zu 
überprüfen, welche im Normalfall auch immer stimmt.

Ciao,
     Rainer

von ka-long (Gast)


Lesenswert?

Hi,

Hab mich länger mit RFM01 und RFM02 auseinander gesetzt und ein 
ähnliches Problem gehabt.

Bei mir lag es daran, dass ich nach dem letzten Bit den Sender zu 
schnell abgeschaltet hatte. Sprich: Das letzte Bit wurde nicht 
vollständig übertragen und vom Empfänger fehlinterpretiert.
Und ja, ich hab auf das Ready2Send vom RFM gewartet.

Falls Du möglicherweise ein ähnliches Problem hast, sende mal ein Bit 
mehr oder mach nen kurzes delay rein, falls Du den Sender abschaltest.


Ich weiss nicht, ob nach 16 Byte schon ein Sync passieren kann...da 
würde die Manchester-Codierung natürlich helfen. Möglicherweise hängt 
das dann wiederum von der Baudrate ab.

Gruß ka-long

von mw2000 (Gast)


Lesenswert?

Hallo zusammen,

danke für die vielen Infos, ist alles sehr interessant und ich sehe, 
dass es noch besser als bei mir geht. Da werde ich weitersuchen...

@ roland + maxx
Dieses Problem hatte mit den vielen Nullen hatte ich schon im Blick. 
Wenn ich aber 16x 0xAA oder 0x55 sende verbessert sich die Situation 
nicht merklich. Aber interessantes Verfahren, mache ich vielleicht 
trotzdem ;)

@ peter
meine Baudrate ist auf 4kB, aber ich werde hier noch mal eine Variation 
durchführen heute abend

@ ka-long
diese Problem umgehe ich gerade, indem ich nach dem CRC-byte noch 2 
weitere Bytes sende (brachte auch eine Verringerung der Fehler) aber ich 
werde noch einmal mit einem extra langem Delay vor der Abschaltung 
testen

Ich werde mal versuchen die Pakete in ein Terminal umzuleiten zum 
mitloggen. Vielleicht werden dann (Un)Regelmässigkeiten sichtbar.

Gruß, und vielen Dank soweit

Matthias

von mw2000 (Gast)


Lesenswert?

Hallo zusammen,

ich habe nun wie angekündigt weitere Tests durchgeführt mit folgender 
überraschenden Erkenntnis.
Auch meine Schaltung kann zu 100% korrekte Pakete übertragen.

Meine Schaltung beinhaltet neben dem RFM-Modul einen USB Anschluss 
(alles in einem PIC18F2550). Diese beiden Module (Hardware oder 
Software) beeinflussen sich negativ. Wenn ich erst 50 Pakete empfange 
und sie danach über USB auslese ist alles i.O.
Wenn ich aber permanent  (alle 200ms) per USB anstehende Paket abfrage, 
kommt es zu beschädigten RFM-Paketen.

Ich glaube es ist ein Timing Problem. Wie lange kann denn ein Paket im 
RFM bleiben, bis es abgeholt werden muss ?

Macht Ihr die Paketabfrage über einen Interrupt in der MCU (nIRQ - Pin 
vom RFM)

Gruß,

Matthias

von Gastino G. (gastino)


Lesenswert?

mw2000 schrieb:
> Ich glaube es ist ein Timing Problem. Wie lange kann denn ein Paket im
> RFM bleiben, bis es abgeholt werden muss ?

Der Empfangspuffer ist ein FIFO (16 Bit) und wird mit den nächsten 1 
Byte langen Paketen wieder überschrieben. Das Paket kann also 
theoretisch bis zum Beginn des übernächsten Paketes drinbleiben.

> Macht Ihr die Paketabfrage über einen Interrupt in der MCU (nIRQ - Pin
> vom RFM)

Ja.

von ka-long (Gast)


Lesenswert?

Hi nochmal,

Deine Konfiguration wird so arbeiten:

Wenn der Empfänger ein SYNC WORD bekommen hat und nicht resettet wurde 
schiebt er lustig bei gütigem VDI Bits ins 16-bit FIFO mit Deiner 
eingestellten Baudrate.

Falls Du also als Paket 16 Bytes meinst ist die Antwort: Gar nicht, 
passt nämlich nicht ins FIFO.

Gruß ka-long

von mw2000 (Gast)


Lesenswert?

Hallo zusammen,

mir dämmert da, dass ich noch ein Konzeptproblem habe daher hier nochmal 
meine jetzige Vorgehensweise im Detail.

Hier meine Sendefunktion (wobei das senden über SPI erfolgt, nicht FSK)
1
void RFM_WritePacket(UCHAR8 * uchrDatapacket){
2
  
3
    UINT16 uintChkSum = 0;  
4
    UCHAR8 tmp;
5
    UCHAR8 cnt = RFM_PACKET_LEN;
6
    
7
    //~~~~~~~~~~~~~~~~~~~~~~~~~
8
    // Synchro (Word) Sequence
9
    //~~~~~~~~~~~~~~~~~~~~~~~~~
10
    WriteFSKbyte(0xAA);
11
    WriteFSKbyte(0xAA);
12
    WriteFSKbyte(0xAA);
13
    WriteFSKbyte(0x2D);
14
    WriteFSKbyte(0xD4);
15
    
16
    //Datentransfer
17
    while(cnt--){
18
      tmp = *uchrDatapacket++;
19
      WriteFSKbyte(tmp);
20
      uintChkSum+=tmp;
21
      }  
22
    
23
    //Checksumme senden
24
    uintChkSum&=0x0FF;
25
    WriteFSKbyte((UCHAR8)uintChkSum);
26
    
27
    //Abschlussbyte.... (um Syncronisation zu halten)
28
    WriteFSKbyte(0xAA);
29
30
  }


nun meine Empfangsfunktion:
1
  //**********************************************************
2
  // Auslesen der gesamten FIFO
3
  //**********************************************************
4
  UCHAR8  RFM_ReadPacket(UCHAR8 * uchrDatapacket){
5
    
6
    UCHAR8 t=0;
7
    UCHAR8 i=0;
8
    UCHAR8 retVal = 0;
9
    UINT16 chkSum;  
10
    UCHAR8 chkSumRead=0;
11
    
12
    // der Buffer fuer Empfangene Bytes der FiFo
13
    UCHAR8 RF_RXBUFFER[RFM_PACKET_LEN + 2];
14
    // Zaehler fuer FiFo Bytes
15
    UCHAR8 buffCnt;  
16
    
17
    // Solange wie Bytes in der FIFO anstehen
18
    while(!nIRQ){
19
20
      #ifdef _DEBUG_RFM
21
        //Oszi Triggerung
22
        DEBUG_PIN=1;
23
      #endif
24
      
25
      //============================
26
      //Auslesen eines Bytes der FIFO
27
      //============================
28
      RF_RXBUFFER[buffCnt++]=RFM_ReadFiFoByte();
29
      
30
      #ifdef _DEBUG_RFM
31
        DEBUG_PIN=0;
32
      #endif
33
    
34
      Nop();
35
    
36
      //Ist das Ende des Datenpacketes erreicht???
37
      if(buffCnt==RFM_PACKET_LEN + 1){
38
        
39
        //============================
40
        // Berechnung der FiFo Reset
41
        //============================
42
        FiFo_Reset();
43
        // REset Counter
44
        buffCnt=0;
45
  
46
        //============================
47
        // Berechnung der Checksumme
48
        //============================
49
        chkSum=0;
50
        for(t=0;t<(RFM_PACKET_LEN);t++)
51
          chkSum+=RF_RXBUFFER[t];   
52
        chkSum &= 0xFF;
53
        
54
        //Kontrolle der Checksumme
55
        chkSumRead = RF_RXBUFFER[RFM_PACKET_LEN];
56
        if((UCHAR8)chkSum!=chkSumRead){
57
          //Checksumme Fehlerhaft
58
          retVal = 2;
59
          }  
60
        else{
61
          //Checksumme iO      
62
          retVal = 1;
63
          }
64
        }  
65
      }
66
      
67
      //Nachbereitung der Daten falls welche empfangen wurden
68
      if (retVal > 0){
69
        //Behandlung fehlerhafter Daten
70
        if (retVal == 2){
71
          for(b=0;b<RFM_PACKET_LEN;b++)
72
            *uchrDatapacket++ = 0;         
73
          }
74
        //Behandlung i.O. Daten
75
        if (retVal == 1){  
76
          for (i=0;i<RFM_PACKET_LEN;i++)
77
            *uchrDatapacket++ = RF_RXBUFFER[i];
78
          }
79
      }  
80
      //Rueckgabewert 
81
      return retVal;
82
  }

und hier die Verwendung im Hauptprogramm des Empfängers:
1
 while(1){
2
3
     //USB Bearbeitung
4
    . . . .
5
6
7
    //Empfangen eines RFM-PACKET
8
    RFM_LED = 0;    
9
    chkRF = RFM_ReadPacket(&rxPac.rawData);
10
    if(chkRF>0){
11
      iRfmCntAll++;
12
      if(chkRF==1){
13
        //Packet korrekt empfangen
14
        RFM_LED = 1;
15
        iRfmCntValid++;
16
        //das empfangene Paket weiterverarbeiten -> an USB geben
17
        ProcessRFM_RxPaket(&rxPac);  //(60 Zyklen dauer)
18
        }
19
    }

Nun das Problem so wie ich es jetzt sehe. (Bitte korrigiert mich bevor 
ich alles falsch umbaue)

Mein PIC sitzt in der while schleife fest und die Abarbeitung des RFM12 
erfolgt nicht über Interrupt. Mein Sender sendet  10 Byte-pakete a 16 
Byte mit 10ms delay zwischen den Bytepaketen und keinem Delay zwischen 
den einzelnen Bytes eines Paketes.

Wenn ich die USB Funktionen deaktiviere schafft es der PIC immer die 
FIFO rechtzeitig zu leeren und produziert fehlerfreie  Pakete. Wenn die 
USB-Funktion aktiviert ist, kann es sein das die FIFO sich an einem Sync 
Word Startet und die Abarbeitung nicht anläuft , weil noch die USB 
Funktion bearbeitet wird. Jetzt verliere ich Bytes...

Wenn ich nun die Funktion  chkRF = RFM_ReadPacket(&rxPac.rawData) in 
eine Interruptfunktion einbette, getriggert an nIRQ, dann müsste es ja 
klappen,  da mein Empfangsfunktion ja für die 16 Bytes in der  Schleife 
bleibt und erst dann die FIFO resetet.

Hab ich's richtig zusammengebracht?

Danke soweit erst einmal

Gruß

mw2000

von mw2000 (Gast)


Lesenswert?

Hallo zusammen,

ich wollte mich nach den nun fast 2 Wochen noch einmal zu Wort melden.

Ich habe meinen Treiber auf Interrupt basierte Steuerung umgestellt und 
siehe da. Es läuft jetzt schon seit Tagen mit 0.00% Fehlerrate (bei 4.8 
kB). Unglaublich aber das ist echt der Wahnsinn...

Nun werde ich mal die Übertragungsraten hochschrauben.

Also noch mal Danke an alle

Gruß

mw2000

PS: Der Beispielcode im RF-Manual taugt nur fuer Testzwecke wo die CPU 
zu 100% das Modul überwacht. (Sie mein alter Treiber)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.