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
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.
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
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
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
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
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
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
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.