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.
Ich hab noch mal nachgeschaut, der RFM02 hat kein Sendepuffer der RFM12 schon, das war der unterschied denn ich noch im Kopf hatte.
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?
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!
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
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?
Und er sendet jetzt nur noch auf Knopfdruck, womit auch das Problem Zeitnutzung gelöst ist!
Nach dem Erkennen der Startbedingung werden 32 Bytes eingelesen. Hört der Sender vorher auf, kommt danach halt nur zufälliges rauschen an.
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.
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.