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!
ArduStemmi schrieb:> 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!
Das Problem hab ich jeden mal.
Zeig doch mal den Code, vielleicht kann man da was sehen !
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.
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
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.
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
voidrf02_setmodfreq(unsignedcharbandwidth)
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?
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!
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.
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
ArduStemmi schrieb:> Ich geh' mal davon aus, dass das die> gekürzte Formel für 433 Mhz ist. Muss ich also anpassen
So isses. Bei den 865 Mhz Modulen hast du als Basis 860Mhz und die
Rasterfrequenz ist 5kHz.
Es ist also Frx = 860+(PLLWert * 0,005)
Für 865,12 Mhz ist also PLL = 1024.
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?
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.
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.
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?
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.
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.
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!
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.