Hallo zusammen, das Funkmodul RFM70 verfügt ja bereits über eine Antenne auf der Platine. Leider ist die Reichweite dieser Antenne nicht besonders gut. So vom Datenblatt ist der Anschluss einer externen Antenne wohl auch nicht vorgesehen. Könnte man nun einfach eine 2,4Ghz Rundstrahlantenne über ein Kabel an die Platine löten? Oder würde das nicht funktionieren? Hat das schon mal jemand versucht? Für Ideen oder Tipps bin ich sehr dankbar. Viele Grüße Daniel
:
Verschoben durch Moderator
Daniel schrieb: > Leider ist die Reichweite dieser Antenne nicht besonders gut. Definiere "nicht besonders gut". 2.4GHz hat generell Probleme im bebautem Raum.
Ich komme so auf ca. ~15 Meter Reichweite, dabei geht das Signal auch durch 2 Steinwände. Im freien liegt die Reichweite bei ~30 Metern. Leider schwanken die Module stark in ihren elektrischen Eigenschaften. Teilweise schaffen manchen Module nur eine Reichweite von wenigen Metern (Freiluft). Ist das RFM70 nicht abgekündigt und durch das RFM73 ersetzt wurden? Weiß einer ob diese Kompatibel zueinander sind? MfG Lux
Ich meine schonmal gelesen zu haben, das man da einfach eine W-Lan Antenne anlöten können soll (war hier im Forum).
Ich habe festgestellt, dass durch Variation Wertes des Reg4 in Bank1 die Leistung teilweise erheblich verbessert werden kann (z.B. von 0xD99E860B auf 0x099E860B). Leider ist nirgends dokumentiert was genau dieser Wert bewirkt. Aber bit 20 hat hat irgendwas mit der RF_PWR zu tun. Wenn du richtig Power haben willst, solltest du dir mal das RFM70P ansehen. Das hat einen LA und PA auf 20dBm. Damit kommt man dann auch gut durch Wände. Freifeld sind mit 2 dBi Antennte etwa 500-600m drin. Auch ein Footprint für ein SMA-Anschluss ist vorhanden. Gibts auch bei Octamex
Hallo zusammen, danke für eure Antworten. Ich plane aktuell eine neue Version meines RFM70 Boards (http://projects.web4clans.com/?p=201) zu den Änderung sollte u.a. ein Antennenanschluss gehören. Mir gefällt dabei nur nicht, dass man die Verbindung manuell mit einem Draht überbrücken müsste. Die Reichweite betrug bei mir im Freien ca. 10m, im Haus ging es nicht mal durch eine Etage. Leider ist das 2.4Ghz Band ja auch sehr überlaufen, daher überlege ich aktuell, ob es überhaupt Sinn macht mit dem RFM70 Modul noch ein neues Layout zu machen. Könnt ihr sonst noch gute und vorallem kleine Module empfehlen, die eine Reichweite von min. 100m im Freien haben, besser natürlich mehr und kosten sollten sie auch noch nicht mehr als 10€ / Modul. Von der Frequenz her bin ich für alles offen, ich benutze die Module hauptsächlich für Haussteuerungsaufgaben, da sind die Nachrichten nicht so groß. Die beiden oben genannten RFM73 und RFM70P nehme ich mal raus. Bei dem RFM73 sehe ich nicht wirklich Vorteile gegenüber dem RFM70. Das RFM70P sieht ganz spannend aus, ist wohl auch pinkompatibel. Gruß Daniel
Hallo Daniel, dein Board ist ziemlich ungünstig für das RFM70 und die schlechte Leistung, die du erzielst, wundert mich auch nicht wirklich. Deine Antenne liegt genau über einer Kupferfläche. In deinem Schaltplan gibt es auch noch ein paar Dinge die man verbessern könnte (Kondensatoren). Ich würde erst einmal diese Dinge bereinigen, dann das RFM70 nochmal testen bevor du mit 100mW durch den Äther brüllst... MFG Bernd
Falls das Thema hier noch aktuell ist: Ich habe in meiner Anwendung 2 RFM70P laufen, und trotz einstellung auf voller Sendeleistung hab ich ne Reichweite von lächerlichen ~5 Metern (Freies Sichtfeld zwischen den beiden Modulen). Änderung der Frequenzen/Sendeleistung/etc brachten keine änderung bzw verschlechterung. Hab ich da ein faules Modul erwischt oder gibts bei dem Modul was das ich grundlegend falsch machen könnte?
Verwende die Module als Fernsteuerung für meinen Quadrocopter. In der Fernsteuerung befindet sich das Modul direkt unter dem Sony schriftzug, aufm heli sieht mans ja. hier die initialisierung der register:
1 | #include "meinRFM70P.h" |
2 | |
3 | |
4 | //************ Bank0
|
5 | uint8_t bank0Init[][2]= |
6 | {
|
7 | // address data
|
8 | { (0x20|0x00), 0x0B }, //Alle Int's am IRQ Pin active low ausgeben, CRC an, CRC Encoding 1 byte, Power Up, Transmitter |
9 | { (0x20|0x01), 0x3F }, //Auto Acknowledge auf alle pipes aktivieren |
10 | { (0x20|0x02), 0x3F }, //alle Datenpipes aktivieren |
11 | { (0x20|0x03), 0x03 }, //RX/TX 5 byte lange Adresse für Empfänger/Sender |
12 | { (0x20|0x04), 0x27 }, //Auto Retransmition delay 500us, Auto Retransmision aus |
13 | { (0x20|0x05), 0x3F }, //kanal = 18 |
14 | { (0x20|0x06), 0x37 }, //Air Data Rate 2Mbps, Transmit Power 5dBm, LNA gain -20dB |
15 | { (0x20|0x07), 0x00 }, // Statusregister |
16 | { (0x20|0x08), 0x00 }, //Read only Transmit Observe Register, zählt Packet loss und retransmits |
17 | { (0x20|0x09), 0x00 }, //Read only Carrier Detect (?) |
18 | { (0x20|0x0C), 0xC3 }, //LSB Addr pipe 2 |
19 | { (0x20|0x0D), 0xC4 }, //LSB Addr pipe 3 |
20 | { (0x20|0x0E), 0xC5 }, //LSB Addr pipe 4 |
21 | { (0x20|0x0F), 0xC6 }, //LSB Addr pipe 5 |
22 | { (0x20|0x11), 0x32 }, // 32 bytes RX Payload in pipe0 ------>? |
23 | { (0x20|0x12), 0x32 }, // 32 bytes RX Payload in pipe1 ------>? |
24 | { (0x20|0x13), 0x32 }, // 32 bytes RX Payload in pipe2 ------>? |
25 | { (0x20|0x14), 0x32 }, // 32 bytes RX Payload in pipe3 ------>? |
26 | { (0x20|0x15), 0x32 }, // 32 bytes RX Payload in pipe4 ------>? |
27 | { (0x20|0x16), 0x32 }, // 32 bytes RX Payload in pipe5 ------>? |
28 | { (0x20|0x17), 0x11 }, // FIFO Flag Register, ansich Read Only |
29 | { (0x20|0x1C), 0x3F }, // Dynamic Payload length für alle pipes aktiviert |
30 | { (0x20|0x1D), 0x07 } //Enables Dynamic Payload Length,Enables Payload with ACK |
31 | };
|
32 | |
33 | //**************32 bit Register 0A,0B,10 Bank0 Initialisierungsbefehle
|
34 | |
35 | uint8_t bank0R0A0B10Init[][6]= |
36 | {
|
37 | {(0x20|0x0A), 0xE7, 0xE7, 0xE7, 0xE7, 0xE7}, //Empfangsadresse pipe0 |
38 | {(0x20|0x0B), 0xC2, 0xC2, 0xC2, 0xC2, 0xC2}, //Empfangsadresse pipe1 |
39 | {(0x20|0x10), 0xE7, 0xE7, 0xE7, 0xE7, 0xE7} //Sendeadresse, Nur für Sendemodus verwendet |
40 | };
|
41 | //**************** Bank1 Addresse 0-5, MSBByte->LSBByte, Addresse 6;7;8 ist reserved oder Read Only
|
42 | uint8_t bank1Init[][5]= { |
43 | // address data
|
44 | { (0x20|0x00), 0x40, 0x4B, 0x01, 0xE2 }, //ok |
45 | { (0x20|0x01), 0xC0, 0x4B, 0x00, 0x00 }, //ok |
46 | { (0x20|0x02), 0xD0, 0xFC, 0x8C, 0x02 }, //ok |
47 | { (0x20|0x03), 0x99, 0x00, 0x39, 0x41 }, //ok |
48 | { (0x20|0x04), 0xD9, 0x9E, 0x86, 0x0B }, //High Power Mode als Sender |
49 | { (0x20|0x05), 0x24, 0x06, 0x7F, 0xA6 }, //ok |
50 | |
51 | };
|
52 | //************ Bank1 register 0C-0D Initialisierungsbefehle, LSBByte-MSBByte, 09;0A;0B sind reserved
|
53 | uint8_t bank1R090BInit[][5] = { |
54 | {(0x20|0x0C), 0x00, 0x12, 0x73, 0x00}, //ok |
55 | {(0x20|0x0D), 0x36, 0xB4, 0x08, 0x00}, //ok |
56 | };
|
57 | |
58 | //************ Bank1 register 0E Initialisierungsbefehle, LSBByte->MSBByte
|
59 | uint8_t bank1R0EInit[]= |
60 | {
|
61 | // address Data...
|
62 | (0x20|0x0E), 0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF |
63 | };
|
So wird in die register geschrieben:
1 | void rfm_Init_Bank0() //Bank0 mit Standartwerten Initialisieren |
2 | { //funktion begin |
3 | uint8_t zeile = 0, spalte = 0 , dummy = 0; |
4 | |
5 | //##### Schleife zum übertragen von Datenarray bank0Init ###########
|
6 | for(zeile=0;zeile<=22;zeile++) //Zeilenzählerschleife |
7 | { //outer Loop begin |
8 | SPI_START; //RFM70P Selektieren |
9 | for(spalte=0;spalte<=1;spalte++) //Spaltenzählerschleife |
10 | { //inner Loop begin |
11 | SPDR = bank0Init[zeile][spalte];//Datenregister mit dem aktuellen Befehl/Daten laden |
12 | SPI_COMPLETE; //warten bis SPI Übertragung komplett |
13 | dummy = SPDR; //Datenregister auslesen um INTFlag zu löschen |
14 | |
15 | } //inner Loop end |
16 | SPI_STOP; //RFM70P deselektieren |
17 | } //outer Loop end |
18 | |
19 | //##### Schleife zum übertragen von Datenarray bank0R0A0B10Init ###########
|
20 | for(zeile=0;zeile<=2;zeile++) //Zeilenzählerschleife |
21 | { //outer Loop begin |
22 | SPI_START; //RFM70P Selektieren |
23 | for(spalte=0;spalte<=5;spalte++) //Spaltenzählerschleife |
24 | { //inner Loop begin |
25 | SPDR = bank0R0A0B10Init[zeile][spalte]; //Datenregister mit dem aktuellen Befehl/Daten laden |
26 | SPI_COMPLETE; //warten bis SPI Übertragung komplett |
27 | dummy = SPDR; //Datenregister auslesen um INTFlag zu löschen |
28 | |
29 | } //inner Loop end |
30 | SPI_STOP; //RFM70P deselektieren |
31 | } //outer Loop end |
32 | } //funktion end |
33 | |
34 | |
35 | |
36 | void rfm_Init_Bank1() //Bank1 mit Standartwerten Initialisieren |
37 | {
|
38 | uint8_t zeile = 0, spalte = 0 , dummy = 0; |
39 | |
40 | //##### Schleife zum übertragen von Datenarray bank1Init ###########
|
41 | for(zeile=0;zeile<=5;zeile++) //Zeilenzählerschleife |
42 | { //outer Loop begin |
43 | SPI_START; //RFM70P Selektieren |
44 | for(spalte=0;spalte<=4;spalte++) //Spaltenzählerschleife |
45 | { //inner Loop begin |
46 | SPDR = bank1Init[zeile][spalte];//Datenregister mit dem aktuellen Befehl/Daten laden |
47 | SPI_COMPLETE; //warten bis SPI Übertragung komplett |
48 | dummy = SPDR; //Datenregister auslesen um INTFlag zu löschen |
49 | |
50 | } //inner Loop end |
51 | SPI_STOP; //RFM70P deselektieren |
52 | } //outer Loop end |
53 | |
54 | |
55 | //##### Schleife zum übertragen von Datenarray bank1R090BInit ###########
|
56 | for(zeile=0;zeile<=1;zeile++) //Zeilenzählerschleife |
57 | { //outer Loop begin |
58 | SPI_START; //RFM70P Selektieren |
59 | for(spalte=0;spalte<=4;spalte++) //Spaltenzählerschleife |
60 | { //inner Loop begin |
61 | SPDR = bank1R090BInit[zeile][spalte];//Datenregister mit dem aktuellen Befehl/Daten laden |
62 | SPI_COMPLETE; //warten bis SPI Übertragung komplett |
63 | dummy = SPDR; //Datenregister auslesen um INTFlag zu löschen |
64 | |
65 | } //inner Loop end |
66 | SPI_STOP; //RFM70P deselektieren |
67 | } //outer Loop end |
68 | |
69 | //##### Schleife zum übertragen von eindimensionalem Datenarray bank1R0EInit ###########
|
70 | SPI_START; //RFM70P Selektieren |
71 | for(spalte=0;spalte<=11;spalte++) //Spaltenzählerschleife |
72 | { //inner Loop begin |
73 | SPDR = bank1R0EInit[spalte];//Datenregister mit dem aktuellen Befehl/Daten laden |
74 | SPI_COMPLETE; //warten bis SPI Übertragung komplett |
75 | dummy = SPDR; //Datenregister auslesen um INTFlag zu löschen |
76 | |
77 | } //inner Loop end |
78 | SPI_STOP; |
79 | return; |
80 | }
|
meine headerdatei
1 | //Port und Pinbelegung
|
2 | #define DDR_SPI DDRB
|
3 | #define PORT_SPI PORTB
|
4 | #define CE PB3
|
5 | #define CSN PB4
|
6 | #define SCK PB7
|
7 | #define MISO PB6
|
8 | #define MOSI PB5
|
9 | #define IRQ PD6
|
10 | |
11 | |
12 | //SPI Befehle
|
13 | |
14 | #define R_REGISTER 0x00 //Register lesen
|
15 | #define W_REGISTER 0x20 //Register schreiben
|
16 | #define R_RX_PAYLOAD 0x61 //Empfangene Datenpakete lesen (1-32 bytes)
|
17 | #define W_TX_PAYLOAD 0xA0 //zu Sendende Datenpakete schreiben(1-32 bytes)
|
18 | #define FLUSH_TX 0xE1 //Sendepuffer leeren (Sendemodus)
|
19 | #define FLUSH_RX 0xE2 //Empfangspuffer leeren (Empfangsmodus)
|
20 | #define REUSE_TX_PL 0xE3 //Letzete Datenpakete nochmal Senden (solange CE high ist..)
|
21 | #define ACTIVATE 0x50 //ACTIVATE gefolgt von 0x73 aktiviert R_RX_PL_WID,W_ACK_PAYLOAD,W_TX_PAYLOAD_NOACK
|
22 | #define R_RX_PL_WID 0x60 //Länge des Empfangenen Datenpaketes im Empfangspuffer auslesen
|
23 | #define W_ACK_PAYLOAD 0xA8 //
|
24 | #define W_TX_PAYLOAD_NOACK 0xB0 //AUTOACK im Sendemodus für das nächste Paket abschalten
|
25 | #define RFM_NOP 0xFF //No Operation
|
26 | |
27 | //Makros und Nützliches
|
28 | #define SPI_COMPLETE while(!(SPSR & 0b10000000)){asm("NOP");} //NOP Schleife solange SPI INT nicht gesetzt
|
29 | #define SPI_START PORT_SPI &= ~(1<<CSN) //Übertragung beginnen
|
30 | #define SPI_STOP PORT_SPI |= (1<<CSN) //Übertragung beenden
|
31 | |
32 | //in Struktur verpackter Array damit Funktionen ihn zurückgeben können
|
33 | struct retData { |
34 | int data[32]; |
35 | };
|
36 | |
37 | |
38 | uint8_t rfm_Read_Reg(uint8_t READ_ADRESS); //8 Bit Register lesen |
39 | uint8_t rfm_Get_Chip_ID(void); //Chip ID auslesen |
40 | |
41 | struct retData rfm_Read_Reg_long(uint8_t READ_ADRESS, uint8_t length); //Register > 8 Bit lesen |
42 | struct retData rfm_Get_Payload(); //Empfangenes Datenpaket aus Empfangsregister Lesen |
43 | |
44 | void rfm_init_SPI(void); |
45 | void rfm_Write_Reg(uint8_t WRITE_ADRESS , uint8_t length , uint8_t data[32]); //Register schreiben, länge 8 Bit *length |
46 | void rfm_Set_Bank(int8_t bank); //aktive Registerbank einstellen |
47 | void rfm_Set_Mode(uint8_t mode); //0 = Sender, 1 = Empfänger |
48 | void rfm_Flush_TX(); //Sendespeicher leeren |
49 | void rfm_Flush_RX(); //Empfangsspeicher leeren |
50 | void rfm_Init_Bank0(); //Bank0 mit Standartwerten Initialisieren |
51 | void rfm_Init_Bank1(); //Bank1 mit Standartwerten Initialisieren |
52 | void rfm_Activate_73(void); //Aktivieren(Toggle) der Register R_RX_PL_WID;W_ACK_PAYLOAD;W_TX_PAYLOAD_NOACK |
53 | void rfm_Send_Payload(uint8_t Payload[32]); //Datenpaket ins Senderegister Schreiben |
Kommentare hinter den zeilen sind nicht immer korrekt da ich bei änderungen nicht immer sofort mitkommentiert hab
Warum LNA low gain? Sicher das du das empfangene signal wieder abschwächen willst?
Vermutlich produziert dein Rest der Schaltung soviel Müll, dass das RFM70 gar keine Chance hat was zu empfangen...
dass bei Bank 1 Register 0...8 der Byteorder verdreht ist hast du scheinbar nicht beachtet!?
Die Reichweite ändert sich nicht auch wenn ich den Rest der Schaltung von der Spannungsversorgung nehme. TREN bzw PAEN wird vom uC über einen Transistor auf 3,3v gezogen (je nach betriebsart.) Die Byteorder für Bank1 0-8 scheint in meinenem Array wirklich falschrum zu sein. Werds heut abend mal ändern und bescheidgeben danke euch :)
Hab die Bytefolge geändert und das scheints gewesen zu sein (richtiger test steht noch aus aber die Reichweite hat sich verbessert). Vielen dank für die Hilfe besonders Timmo :) Eine Verständnissfrage bleibt noch: Auf Seite 13 im Datenblatt steht wörtlich <Command word> MSB Bit to LSB Bit (one byte) <- das is klar <Data bytes: LSB Byte to MSB Byte, MSB Bit in each byte first> for all registers at bank0 an registers 9 to registers 14 in bank1 <Data bytes: MSB byte to LSB byte, MSB bit in each byte first> for register 0 to register 8 at bank1 Dann steht auf Seite 15: Note: The SPI timing is for bank0 an registers 9 to 14 at bank1.For registers 0 to 8 at bank1, the byte order is inversed that the MSB byte is R/W before LSB byte. Widersprechen sich diese Aussagen oder lese ich das falsch?
Nee das passt schon, ist nur etwas merkwürdig ausgedrückt. Darum passiert wohl auch sooft der Fehler. Im Beispielcode von HopeRF ist das schon richtig gemacht, darum verstehe ich nicht warum das alle immer falsch ".übernehmen".
Um endgültige sicherheit zu haben :) : Bank0 komplett und Bank1 9bis14 : LSBByte ----> MSBByte, Register 0x0E (14) laut datenblatt mit 0xFFFFFEF7CF208104082041 gefüttert werden. also sende ich über SPI 41;20;08;04;81;20;CF;F7;FE;FF;FF Für Bank1 Reg0 bis 8 dann: MSBByte-->LSBByte um register4 wie im Dateblatt gefordert mit 0xD99E860B zu beschreiben sende ich im SPI D9;9E;86;0B sorry das ich so auf der Frage herumreite, will nur wirklich sicher sein das ich das richtig mache um net ewig auf Fehlersuche zu sein
Ja, so wie es auch im Beispielcode beschrieben ist... Willst du dir den einfach nicht angucken oder wie?
Die Dokumentationen von HopeRF sind einfach sehr missverständlich formuliert (zb auch bei der Speicheradressierung des HDPM01). wo is die Schande wenn ich da lieber nochmal nachfrage bevor ich mich tagelang mit Fehlersuche rumärgere?
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.