RFM 01 empfängt Daten sehr verzöger

Gast #3921353
Lesenswert?

Ich beobachte bei einer Funkverbindung ein sehr seltsames Verhalten.

Der Sender (RFM02, betrieben mit der Bibliothek vom Benedikt, aber 
umgestellt auf 866 Mhz) sendet jede Sekunde 32 Byte.

Der Empfänger (RFM01, betrieben mit der Bibliothek vom Benedikt, aber 
umgestellt auf 866 Mhz) fragt permanent den FIFO ab und schaltet LED's 
an oder aus.

Das Kuriose ist, dass das funktioniert. Nur leider nicht gleich. Der 
Empfänger braucht zwischen 3 Sekunden und 3 Minuten um die Daten richtig 
zu empfangen! (Was ich daran erkenne, dass die gewünschten LEDs nach 
dieser Wartezeit angehen! Danach reagiert das System sofort! Jede 
Änderung am Sender wird unmittelbar am Empfänger wiedergegeben!) Es 
hilft auch nicht, den µC zu resetten, oder den RFM01 zu resetten. Es ist 
für mich nicht nachvollziehbar!

Kann das jemand erklären?

PS: Im Übrigen verwende ich die Module, weil ich mich eben nicht 
tiefgreifend mit HF-Technik befassen möchte! Ich hatte die Hoffnung, die 
Dinger mit dem µC anzusteuern und gut. Den Rest sollten die Module 
erledigen. Vielleicht ist das zu naiv, aber ich habe es trotzdem 
versucht!
#3921704
Lesenswert?

Ich hatte meine Ansteuerung für den RFM01/02/12 selbst geschrieben.
Wichtig ist nur des der Sender eine Präambel vor der Startbedingung 
sendet.

Startbedingung ist 0x2DD4, als Präambel eignet sich 0xAAAA oder 0x5555
A    A    A    A    2    D    D    4
1010 1010 1010 1010 0010 1101 1101 0100

Ohne Präambel kann sich der Empfänger nicht auf den Takt einschwingen 
und übersieht das Startbyte.

Und du meinst wahrscheinlich 868Mhz

Der genaue Bereich den man verwenden kann, geht von 868.0 bis 868.6Mhz
Daher am besten genau die Mitte nehmen. Dafür musst du die Formel im 
Datenblatt nachschlagen, kann dir aber sagen das man für 868.3 Mhz das 
'f' mit 1660 gesetzt werden muss, und das macht man indem man 0xA67C an 
das Modul sendet.

Das zweite ist der Frequenzhub, den kann man zwischen 15 und 240 kHz 
einstellen, Standard ist 90 und sollte man erstmal so lassen.
Es wird eine  2-FSK verwendet, dass bedeutet bei einer '0'  sendet er 
auf 868.21Mhz und bei einer Logischen '1' auf 686,39 MHz.

Außerdem muss Transferrate eingestellt werden dazu muss 'r' gesetzt 
werden. In meinem Code hatte ich das nur für zwei werte ausgerechnet:
0xC647 => Data Rate: r=71 ; cs=0 => 4,79 kbps
0xC67F => Data Rate: r=127 ; cs=0 => 2,7 kbps

Kleine Transferrate => geringere Bitfehlerwahrscheinlichkeit => größere 
Reichweite



PS. Als ich das hier am schreiben bin, ist mir eingefallen das der RFM01 
gar kein EmpfangsFIFO hat, sondern nur der RFM12. Oder war es der 
SendeFIFO im RFM02. Bin mir aber nicht sicher.
#3921812
Lesenswert?

OK, rf02_txdata sendet automatisch am Anfang  AA AA AA 2D D4

was mich jetzt stutzig macht ist:
rf02_setfreq(RF02FREQ(830.25));          // Sende/Empfangsfrequenz auf 
830,25 MHz einstellen

Das ist die unterste Grenze was das Modul unterstützt, aber die 
Antennenschaltung ist auf eine Frequenz Optimiert, bei der sie die beste 
Efferenz hat. und das wird wohl 868Mhz sein.

Des weiteren ist wie gesagt in Deutschland nur der Bereich 868.0 bis 
868.6 erlaubt. Und das auch nur mit 1% Zeitnuzung. Sendet man am Stück 
10ms muss man 990ms pause machen.

Deine 32 + 5 Bytes brauchen schon 15,42ms
(Firma: matzetronics) #3921815
Lesenswert?

Christian K. schrieb:
> das der RFM01
> gar kein EmpfangsFIFO hat

Doch klar, hat er. Und es ist wirklich sinnvoll, den vor einem Paket zu 
reinitialisieren. Nach erfolgreichem Empfang dann gleich wieder 
reinitialisieren. Dann läuft das alles recht solide. Ich lasse immer 
einen Timer als Timeout mitlaufen, wenn da innerhalb einiger Sekunden 
nichts kommt, wird einfach mal der Fifo neu gestartet.
Allerdings strahlt mein Sender auch alle paar Sekunden ein Bakensignal 
aus, der für regelmässige Updates in den Empfängern sorgt.
Gast #3921854
Lesenswert?

Christian K. schrieb:
> Ich hatte meine Ansteuerung für den RFM01/02/12 selbst geschrieben.
> Wichtig ist nur des der Sender eine Präambel vor der Startbedingung
> sendet.
>
> Startbedingung ist 0x2DD4, als Präambel eignet sich 0xAAAA oder 0x5555
> A    A    A    A    2    D    D    4
> 1010 1010 1010 1010 0010 1101 1101 0100

Das passiert bei mir in der Prozedur rf02_txdata:
1
    rf02_shiftout(0xAA);
2
    rf02_shiftout(0xAA);
3
    rf02_shiftout(0xAA);
4
    rf02_shiftout(0x2D);
5
    rf02_shiftout(0xD4);

Christian K. schrieb:
> Und du meinst wahrscheinlich 868Mhz
>
> Der genaue Bereich den man verwenden kann, geht von 868.0 bis 868.6Mhz
> Daher am besten genau die Mitte nehmen. Dafür musst du die Formel im
> Datenblatt nachschlagen, kann dir aber sagen das man für 868.3 Mhz das
> 'f' mit 1660 gesetzt werden muss, und das macht man indem man 0xA67C an
> das Modul sendet.

Dazu habe ich folgende Änderungen in der Bibliothek vorgenommen:
1
#define RF02FREQ(freq)  ((freq-860.0)/0.0025)    //früher stand hier: ((freq-430.0)/0.0025)

Mit diesem Makro in der Header-Datei wird der so genannte f-Wert 
berechnet! Des Weiteren habe ich die Prozedur rf02_setmodfreq angepasst.
1
void rf02_setmodfreq(unsigned char bandwidth)
2
{
3
  rf02_trans(0x9780|(bandwidth&7));      //früher stand hier rf02_trans(0x8F80|(bandwidth&7));
4
}
Hier habe entsprechend Datenblatt die bits b0 und b1 im Configuration 
Setting Command an 868 Mhz angepasst!

In meinem Quelltext habe ich mich für 830.25 MHz entschieden, warum weiß 
ich aber nicht mehr!
1
  rf02_init();                  // ein paar Register setzen (z.B. CLK auf 10MHz)
2
  rf02_setfreq(RF02FREQ(830.25));          // Sende/Empfangsfrequenz auf 830,25 MHz einstellen
3
  rf02_setpower(4);                // -12dBm Ausgangangsleistung
4
  rf02_setmodfreq(3);                // 120kHz Frequenzshift
5
  rf02_setbaud(19200);              // 19200 Baud

Ich sehe gerade: die 830,25 sind vollkommener Blödsinn! Die Prozedur 
korrigiert aber den Wert auf 860.24 Mhz(entspricht dem f-Wert von 96!)

Christian K. schrieb:
> Der genaue Bereich den man verwenden kann, geht von 868.0 bis 868.6Mhz
> Daher am besten genau die Mitte nehmen. Dafür musst du die Formel im
> Datenblatt nachschlagen, kann dir aber sagen das man für 868.3 Mhz das
> 'f' mit 1660 gesetzt werden muss, und das macht man indem man 0xA67C an
> das Modul sendet.

Damit komme ich nicht ganz klar: Meiner Meinung nach Ergibt 868,3 MHz 
einen f Wert von freq = (868,3 - 860) / 0,0025 = 3.320! Das ergibt nach 
meinem Verständnis 0xA000 | freq = 0xA000 | 0x0CF8 = 0xACF8 für das 
Frequency Setting Command! Oder?
Gast #3921863
Lesenswert?

Matthias Sch. schrieb:
> Ich lasse immer
> einen Timer als Timeout mitlaufen, wenn da innerhalb einiger Sekunden
> nichts kommt, wird einfach mal der Fifo neu gestartet.
> Allerdings strahlt mein Sender auch alle paar Sekunden ein Bakensignal
> aus, der für regelmässige Updates in den Empfängern sorgt.

Das würde mich interessieren, wie Du das realisierst!
(Firma: matzetronics) #3921903
Lesenswert?

ArduStemmi schrieb:
> Das würde mich interessieren, wie Du das realisierst!

Der Code ist schon ein wenig älter und sollte für den Arduino sein, wenn 
ich mich recht erinnere. Allerdings komplett in Assembler und nur für 
die Hardware des Due Milanove und nichts mit Arduino Bibliotheken.

Da das für ein Wireless DMX Empfänger ist, wunder dich nicht über die 
'DMX' Bezeichnung des Empfangsbuffers.
Die Pinbelegung steht drin. Ich benutze übrigens ziemlich genau die 
Bandmitte bei 865,12 MHz.
Angehängte Dateien:
Gast #3921913
Lesenswert?

Christian K. schrieb:
> RTFM
>
> f0 = 10 x c1 x ( c2 + F / 40000 ) [MHz]
>
> Band C1 C2
> 315  1  31
> 433  1  43
> 868  2  43
> 915  3  30
>
> 868.3 = 10 x 2 ( 43 + F / 40000)
> 43,415 = 43 + F / 40000
> 0,415 = F / 40000
> 1660 = F

Ja, das ist die Formel aus dem Datenblatt! In Benidikt's Headerdatei 
steht aber Freq = (F - 430)/0,0025. Ich geh' mal davon aus, dass das die 
gekürzte Formel für 433 Mhz ist. Muss ich also anpassen:

für 868 MHz gilt dann also:
f0 = 10 * 2 *(43 +F/4000)
f0 = 860 + F/200
f0-860 = F/200
F = (f0 - 860) * 200 oder (f0 - 860) / 0,005
Gast #3921933
Lesenswert?

Ich habe jetzt die Frequenzen angepasst. Seitdem funktioniert das 
einwandfrei! Danke für Eure Bemühungen!

Eine Frage hätte ich jedoch noch!
1
for (;;)
2
  {  rf01_rxdata(data, 32);    // 32Bytes empfangen
3
    // hier die Daten verarbeiten
4
    
5

6
      PORTD = data[0];
7
      _delay_ms(250);
8
  
9
    }

hier wird ja bei jedem Durchlauf abgefragt, ob Daten (genau 32 Byte) da 
sind. Bleibt das Programm da stehen, wenn keine Daten da sind? Wenn ja: 
Wie kann ich das umgehen?
(Firma: matzetronics) #3921943
Lesenswert?

ArduStemmi schrieb:
> Bleibt das Programm da stehen, wenn keine Daten da sind?
Jo, wird weiter auf die kompletten 32 Bytes warten
> Wenn ja:
> Wie kann ich das umgehen?
Du könntest bspw. einen Endemarker definieren, der das Ende eines 
Paketes markiert. Wenn dieser Marker empfangen wird, betrachtet die 
Empfangsroutine die Übertragung als beendet. Auch eine bestimmte Folge 
von Bytes wäre geeignet.
#3921953
Lesenswert?

rf01_rxdata() blockiert solange bis die Startbedingung kommt.
das delay danach kannst du weglassen.


Die Lib von Benedikt ist ziemlich einfach gestickt, benutzt weder 
Interrupts noch Hardware SPI.

Benutzt man beides kann man die Kommunikation wunderbar im Hintergrund 
laufen lassen und das Hauptprogramm kann was anderes tun.
Gast #3921979
Lesenswert?

Christian K. schrieb:
> rf01_rxdata() blockiert solange bis die Startbedingung kommt.
> das delay danach kannst du weglassen.
>
> Die Lib von Benedikt ist ziemlich einfach gestickt, benutzt weder
> Interrupts noch Hardware SPI.
>
> Benutzt man beides kann man die Kommunikation wunderbar im Hintergrund
> laufen lassen und das Hauptprogramm kann was anderes tun.

Klingt gut! Gibt es dazu bereits funktionierenden Code?
Gast #3922093
Lesenswert?

Christian K. schrieb:
> ArduStemmi schrieb:
>> Gibt es dazu bereits funktionierenden Code?
>
> Ja.
> Aber mein Programm will ich nicht veröffentlichen.
>
> So schwer ist es aber nicht.
> Sieh es als Herausforderung an, es selbst zu probieren.

Würde ich gern! Eine Frage kannst Du mir aber sicher beantworten: wie 
bringe ich den Rfm02 dazu, mir zu sagen, dass er Daten hat, die 
abgefragt werden sollten? Das habe ich noch nicht begriffen! Diese 
Botschaft könnte ich als Trigger für einen Interupt zu nehmen.
Gast #3922095
Lesenswert?

ArduStemmi schrieb:
> Christian K. schrieb:
>> ArduStemmi schrieb:
>>> Gibt es dazu bereits funktionierenden Code?
>>
>> Ja.
>> Aber mein Programm will ich nicht veröffentlichen.
>>
>> So schwer ist es aber nicht.
>> Sieh es als Herausforderung an, es selbst zu probieren.
>
> Würde ich gern! Eine Frage kannst Du mir aber sicher beantworten: wie
> bringe ich den Rfm02 dazu, mir zu sagen, dass er Daten hat, die
> abgefragt werden sollten? Das habe ich noch nicht begriffen! Diese
> Botschaft könnte ich als Trigger für einen Interupt zu nehmen.

Ich meine den RFM01, den Empfänger!
#3922121
Lesenswert?

RFM01/02/12 sind von der Ansteuerung identisch.

Es reichen 5 Leitungen 4 für SPI und eine für den Interrupt.

Die Interrupt Leitung wird immer Aktiv wenn sich ein Bit im 
Statusregister ändert. Und erlöscht wenn das Statusregister ausgelesen 
wird.

Das heißt immer wenn der Interrupt aktiv wird, das Statusregister 
auslesen und nachschauen was sich geändert hat.

Beim Sender, z. B. ob der Sendepuffer bereit ist, das nächste Byte 
entgegen zu nehmen.
Beim Empfänger ob was neues im Empfangspuffer ist.

Es gibt einige Fehlerflägs auf die man reagieren könnte.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren