Moin, ich sitz schon seit einer geraumen Zeit an meinen ATMega32 Board (10MHz Quarz) und dem RFM12 herum und bekomm das trotz etlicher Recherchen im Forum nicht zum laufen. Das Programm baut auf das Beispiel von Pollin auf. Ich hab dabei nur bei dem Übertragen von den Registereinstellungen lediglich ein paar Delays eingebaut (Hatte ich mal im Forum geslesen). Ich hab dabei nen Sender der alle 10sek nur ein Byte überträgt (Nach Synchronisation et.) und den Empfänger, der auf Tastendruck was empfangen soll und anschließend den Statusregister an einem Display anzeigt. Hier meine Fragen: 1.) Wenn ich das Statusregister auslese bekomm ich zwei Widersprüchliche Aussagen vom Empfänger: x2 -> Der RX-FIFO ist übergelaufen und x6 -> Der FIFO-Puffer ist leer/EMpty Gelegendlich kommt auch der LowBat Status, obwohl ich die Schwellspannung des LowBattery Detector auf der Mind.Spannung gesetzt hab und die 5V Betriebsspannung stabil sind. Weis da jemand vielleicht einen Rat? 2.) Wenn ich ein 868MHz Modul hab, muss ich da nur das Configuration Setting Command Register ändern? MfG Matthias
Mein IRQ-Ausgang ist auch ständig auf HI gesetzt und beim Auslesen des FIFO kommt immer nur 0x00 heraus. Wär nett wenn da jemand Rat weiss
hmm genau das gleiche problem habe ich bei meinen rfm12 auch. könntet ihr mal eure initialisierung des moduls posten? nutzt ihr hardware oder software spi?
1.) Also die Initialisierung für beide ist: //Configuration Setting RF12_WRT_CMD(0x80EF); //EL,EF,868band,12.0pF //Frequency Setting RF12_WRT_CMD(0xA000+1500);//868MHz //Data Rate RF12_WRT_CMD(0xC60B); //32kbps //Data Filter RF12_WRT_CMD(0xC2AC); //AL,!ml,DIG,DQD4 //FIFO/Reset Mode RF12_WRT_CMD(0xCA81); //FIFO8,SYNC,!ff,DR //Automatic Frequency Control RF12_WRT_CMD(0xC483); //@PWR,NO RSTRIC,!st,!fi,OE,EN //Wake Up Timer RF12_WRT_CMD(0xE000); //NOT USE //Low Duty Cycle RF12_WRT_CMD(0xC800);/ //NOT USE RF12_WRT_CMD(0xC0E0); 2.) Dann nochmal für den Sender: RF12_WRT_CMD(0x8239); //!er,!ebb,ET,ES,EX,!eb,!ew,DC //TX Configuration Control RF12_WRT_CMD(0x9855); //!mp,9810=30kHz,MAX OUT //RX Control RF12_WRT_CMD(0x95C8); //VDI,FAST,134kHz,-20dBm,-103dBm 3.) Dann nochmal für den Empfänger: //Powermanagement RF12_WRT_CMD(0x82D9);//!er,!ebb,ET,ES,EX,!eb,!ew,DC //TX Configuration Control RF12_WRT_CMD(0x9850);//!mp,9810=30kHz,MAX OUT //RX Control RF12_WRT_CMD(0x95C8); 4.) Bei Senden mach ich folgendes: RF12_SEND(0xAA); //PREAMBLE RF12_SEND(0xAA); //PREAMBLE RF12_SEND(0xAA); //PREAMBLE RF12_SEND(0x2D); //SYNC HI BYTE RF12_SEND(0xD4); //SYNC LOW BYTE while(PINB&(1<<2));//wait for previously TX over { RF12_WRT_CMD(0xB800+Byte); //B8xx: Daten (0xAA) senden } RF12_SEND(0xAA); //DUMMY BYTE RF12_SEND(0xAA); //DUMMY BYTE RF12_SEND(0xAA); //DUMMY BYTE 5.) Und Empfangen geht bei mir so: RF12_WRT_CMD(0x82C8); RF12_WRT_CMD(0xCA81); RF12_WRT_CMD(0xCA83); RF12_WRT_CMD(0x0000); FIFO_data=RF12_WRT_CMD(0xB000); //B0xx: FIFO Daten auslesen
Und hier noch ne Frage (und damit mein Threat nicht ganz nach unten verrutscht ;-) ) Sind die Präamble vor dem Senden wirklich notwendig oder konnte man da auch ein Delay einfügen?
Meine Initialisierung sieht ähnlich aber nicht genauso aus. Ich benutze die 433MHz Module, aber das sollte sich eigentlich nur auf die Frequenzeinstellung auswirken. Mit meinen selbstgeschriebenen Sende- und Empfangsroutinen funktionieren die Module sehr stabil und zuverlässig. Ich benutze SDO zum Prüfen ob das RFM12 Modul bereit ist da ich mit dem IRQ des Moduls bisher schlechte Erfahrungen gemacht habe. Bei der Senderoutine übergebe ich die Anzahl der zu übertragenden Bytes und ein Array mit den Nutzdaten. Bei der Empfangsroutine ist es genauso, nur daß in dem übergebenen Array anschließend die empfangenen Daten drinstehen. Diese Methoden sind nicht mehr die Endgültigen die ich momentan benutze, aber für Testzwecke haben sie sehr gut funktioniert. Sie sind zwar für einen LPC935 (8051er), aber da es C Code ist sollte man schon die Zusammenhänge sehen können. :)
1 | // RFM12 initialisieren
|
2 | // Grundfrequenz = 434,00MHz
|
3 | // Eine 1 wird mit positivem Hub gesendet (bei mp=0, FSK=1) -> Tx-Freq = 434,00MHz + 45kHz =434,045MHz
|
4 | // Eine 0 wird mit negativem Hub gesendet (bei mp=0, FSK=1) -> Tx-Freq = 434,00MHz - 45kHz =433,955MHz
|
5 | void init_rfm12() { |
6 | v_Write_rfm12(0x0000); // Status auslesen da die Module ansonsten manchmal etwas spinnen |
7 | v_Write_rfm12(0x80D7); // el , ef , 11.5pf, 433 MHz band |
8 | v_Write_rfm12(0x82C9); // er , ebb , !et , !es , ex , !eb , !ew , dc |
9 | |
10 | // Frequenz einstellen
|
11 | set_freq_rfm12(434000); // 434,00 MHz / 868,00 MHz |
12 | |
13 | v_Write_rfm12(0xC647); // 4.8kbps |
14 | v_Write_rfm12(0x94C4); // Vdi , Fast , 67 kHz Bandbreite, 0db , -79dbm |
15 | v_Write_rfm12(0xC2AC); // al , !ml , Dig , Dqd4 |
16 | v_Write_rfm12(0xCA81); // Fifo8 , Sync , !ff , dr |
17 | v_Write_rfm12(0xC493); // @pwr , +15/-16 f(res) , !st , !fi , oe , en |
18 | v_Write_rfm12(0x9827); // 45 kHz Frequenzhub, tx-power -21 dB, !mp |
19 | v_Write_rfm12(0xE000); |
20 | v_Write_rfm12(0xC800); |
21 | v_Write_rfm12(0xC000); // 1 MHz , 2.2V |
22 | }
|
23 | |
24 | // Einen 16Bit Wert senden
|
25 | void v_Write_rfm12(unsigned int uiDaten) { |
26 | // Slave aktivieren
|
27 | NSEL = 0; |
28 | |
29 | // Erstes Datenbyte senden
|
30 | SPDAT = uiDaten >> 8; |
31 | |
32 | // Warten bis Byte gesendet
|
33 | while ((SPSTAT & 0x80) == 0); |
34 | // Flags zurücksetzen
|
35 | SPSTAT = 0xFF; |
36 | |
37 | // Zweites Daten Byte senden
|
38 | SPDAT = uiDaten & 0xFF; |
39 | |
40 | // Warten bis Byte gesendet
|
41 | while ((SPSTAT & 0x80) == 0); |
42 | // Flags zurücksetzen
|
43 | SPSTAT = 0xFF; |
44 | |
45 | NSEL = 1; |
46 | }
|
47 | |
48 | // Einen 16Bit Wert senden und gleichzeitig 16 Bit empfangen
|
49 | unsigned int ui_RW_rfm12(unsigned int uiDaten) { |
50 | unsigned int temp; |
51 | |
52 | // Slave aktivieren
|
53 | NSEL = 0; |
54 | |
55 | // Erstes Datenbyte senden
|
56 | SPDAT = uiDaten >> 8; |
57 | |
58 | // Warten bis Byte gesendet
|
59 | while ((SPSTAT & 0x80) == 0); |
60 | // empfangenes High-Byte laden
|
61 | temp = SPDAT; |
62 | |
63 | // Flags zurücksetzen
|
64 | SPSTAT = 0xFF; |
65 | |
66 | // Zweites Daten Byte senden
|
67 | SPDAT = uiDaten & 0xFF; |
68 | |
69 | // High-Byte an richtige Position bringen
|
70 | temp = temp * 256; |
71 | |
72 | // Warten bis Byte gesendet
|
73 | while ((SPSTAT & 0x80) == 0); |
74 | // empfangenes Low-Byte laden
|
75 | temp += SPDAT; |
76 | |
77 | // Flags zurücksetzen
|
78 | SPSTAT = 0xFF; |
79 | |
80 | NSEL = 1; |
81 | |
82 | return temp; |
83 | }
|
84 | |
85 | // Warten bis RFM12 bereit
|
86 | void wait_rfm12() { |
87 | NSEL = 0; // SPI Slave aktivieren |
88 | while (SDO == 0); // Warten bis SDO = 1 |
89 | }
|
90 | |
91 | // Grundfrequenz des Moduls einstellen
|
92 | // Frequenz in 5kHz Schritten einstellbar. Frequenz in kHz angeben
|
93 | void set_freq_rfm12(unsigned long ulFreq) { |
94 | unsigned int temp; |
95 | |
96 | if (ulFreq < 800000) |
97 | temp = (int) ((2*ulFreq - 860000) / 5); |
98 | else
|
99 | temp = (int) ((ulFreq - 860000) / 5); |
100 | |
101 | // Wert für Register berechnen und prüfen ob im gültigen Bereich
|
102 | if (temp < 96) |
103 | temp = 96; |
104 | else if (temp > 3903) |
105 | temp = 3903; |
106 | |
107 | // Wert in passendes Register schreiben
|
108 | temp += 0xA000; |
109 | v_Write_rfm12(temp); |
110 | }
|
111 | |
112 | // Vor jeder Übertragung von zu sendenden Daten an das Modul muss auf SDO=1
|
113 | // gewartet werden um sicherzustellen, daß die vorherige Übertragung
|
114 | // abgeschlossen ist.
|
115 | // Die zu senden Daten werden mit dem Befehl 0xB800 kombiniert und über SPI
|
116 | // übertragen, soll z.B. das Nutzdaten-Byte 0x35 gesendet werden, so wird an das
|
117 | // Modul 0xB835 über SPI übertragen, sobald SDO=1 ist.
|
118 | void v_Send_rfm12(unsigned char ucPaketLaenge, unsigned char data * data pucTX_Daten) { |
119 | unsigned char i, temp; |
120 | |
121 | v_Write_rfm12(0x8239); // Power Management Command: er=0, ebb=0, et=1, es=1, ex=1, eb=0, ew=0, dc=1 |
122 | |
123 | // Preambel senden
|
124 | wait_rfm12(); |
125 | v_Write_rfm12(0xB8AA); // TX Data = 10101010 = 0xAA |
126 | wait_rfm12(); |
127 | v_Write_rfm12(0xB8AA); // TX Data = 10101010 = 0xAA |
128 | wait_rfm12(); |
129 | v_Write_rfm12(0xB8AA); // TX Data = 10101010 = 0xAA |
130 | |
131 | // Synchronisationsmuster senden
|
132 | wait_rfm12(); |
133 | v_Write_rfm12(0xB82D); // HI Byte für Frame-Erkennung an Modul übertragen |
134 | wait_rfm12(); |
135 | v_Write_rfm12(0xB8D4); // LOW Byte für Frame-Erkennung an Modul übertragen |
136 | |
137 | // Daten senden
|
138 | for (i = 0; i < ucPaketLaenge; i++) { |
139 | wait_rfm12(); |
140 | temp = *(pucTX_Daten + i); |
141 | v_Write_rfm12(0xB800 + temp); // Eigentliche Nutzdaten |
142 | }
|
143 | |
144 | // Zwei Dummybytes senden, damit der Sender nicht zu früh aufhört am Ende der Nutzdaten
|
145 | // Auf Empfängerseite müssen diese beiden Bytes dann rausgefiltert werden
|
146 | wait_rfm12(); |
147 | v_Write_rfm12(0xB8AA); // TX Data = 10101010 = 0xAA |
148 | wait_rfm12(); |
149 | v_Write_rfm12(0xB8AA); // TX Data = 10101010 = 0xAA |
150 | |
151 | wait_rfm12(); |
152 | v_Write_rfm12(0x8209); // Power Management Command: er=0, ebb=0, et=0, es=0, ex=1, eb=0, ew=0, dc=1 |
153 | }
|
154 | |
155 | // n Datenbytes empfangen
|
156 | void v_Receive_rfm12(unsigned char ucPaketlaenge, unsigned char data * data pucRX_Daten) { |
157 | unsigned int uiTemp; |
158 | unsigned char i; |
159 | |
160 | v_Write_rfm12(0x82C9); // Power Management Command: er=1, ebb=1, et=0, es=0, ex=1, eb=0, ew=0, dc=1 |
161 | v_Write_rfm12(0xCA83); // FIFO and Reset Mode Command: FIFO Level=8, al=0, ff=1, dr=1 |
162 | |
163 | |
164 | // 0xB000 an RFM12 senden und zweites Byte gleichzeitig empfangen
|
165 | for (i = 0; i < ucPaketlaenge; i++) { |
166 | NSEL = 0; |
167 | while(SDO == 0); |
168 | uiTemp = ui_RW_rfm12(0xB000); |
169 | *(pucRX_Daten + i) = uiTemp & 0xFF; |
170 | }
|
171 | |
172 | v_Write_rfm12(0x8209); // Power Management Command: er=0, ebb=0, et=0, es=0, ex=1, eb=0, ew=0, dc=1 |
173 | }
|
Vielleicht hilft es dir ja etwas weiter beim experimentieren. :) Ciao, Rainer
Hallo, die 3x 0xAA sind nötig, damit die Empfängerregelung und AFC sich einstellen können und die Bittakt-PLL einrastet. Das können auch mehr 0xAA sein, 3 reichen aber. Das Sync-Word gibt dann den FiFO frei und die nächsten Bits werden da reingeschoben. Nach dem Empfang der gesendeten Anzahl Bytes muß der Fifo aus- und wieder eingeschaltet werden, damit auf das nächste Sync beim nächsten Datenpaket gewartet wird. Macht man das nicht, wird alles was kommt, in den FiFo geschoben. Rauschen, Fernthermometer, Funkamateure und was sich da noch so alles rumtreibt. Nach dem Senden des Datenpaketes müssen keine weitern Bytes (auch keine 0xAA) gesendet werden. Es muß nur gewartet werden, bis der Sender das letzte Byte fertig gesendet hat, bevor man dem RFM was Neues zu tun gibt. Sonst wird das letzte Nyte eben unvollständig gesendet. Vielleicht findest Du ja bei mir was: http://www.avr.roehres-home.de Gruß aus Berlin Michael
Danke für die Antworten, ich werd das Beispiel von Rainer heut Abend noch ausprobieren. MfG Matthias
Laut Datenblatt (RF12.pdf S.24) gibt mir der FR12 immer bescheid ob der SPI bereit ist um ein neues Bit aufzunehmen. Wenn ich mir den Schreibevorgang des FIFOs am Logicanalyser angucke, sehe ich das nach dem Übertragen der ersten beiden Bytes (0x8238 und 0xB8AA -> Erste Preamble) SDO permanent auf Low geht, ist das evt mein Problem?
Matthias S. schrieb: > Laut Datenblatt (RF12.pdf S.24) gibt mir der FR12 immer bescheid ob der > SPI bereit ist um ein neues Bit aufzunehmen. Das ist korrekt. Dort ist ja ein schönes Beispiel dargestellt anhand dessen man die Arbeitsweise von SDO erkennen kann. > Wenn ich mir den Schreibevorgang des FIFOs am Logicanalyser angucke, > sehe ich das nach dem Übertragen der ersten beiden Bytes (0x8238 und > 0xB8AA -> Erste Preamble) SDO permanent auf Low geht, ist das evt mein > Problem? Wieso Problem? SDO=1 bedeutet, daß du weitere Daten reinschreiben kannst. Erst bei SDO=0 musst du warten bis es wieder 1 wird. Nachdem der RFM12 dein Byte vermutlich gerade am funken ist, musst du warten, bis er wieder bereit ist das nächste Byte zu empfangen. Da die Übertragungsrate des SPI aber normalerweise um einiges größer ist als die Übertragungsrate per Funk, sieht es in dem kleinen Abschnitt des LA natürlich aus, als wäre SDO immer 0. In deinem Beispiel betreibst du den RFM12 ja mit 32kBps. Das wären bei 8 Bits dann genau 8/32000 Sekunden pro Byte oder 250µs. Also kannst du davon ausgehen, daß SDO erst nach ~250µs wieder auf 1 geht nachdem es auf 0 gegangen ist. Also würde ich sagen es ist doch alles im grünen Bereich bei dir. :) Du musst natürlich vor jedem zu sendenen TX-Byte prüfen, ob der RFM12 bereit ist neue Daten anzunehmen (SDO=1). Du solltest, wenn du schon solch schöne Spielzeuge wie einen Agilent LA zur Verfügung hast, mal mehrere Bytes senden und das Ganze dann auch über den gesamten Zeitraum aufzeichnen. Dann sollte man das Verhalten etwas besser erkennen und verstehen können. :) Ciao, Rainer
Das könnte hinkommen. Ich hab jetzt einen Funkscanner an das Oszilloskop angeschlossen. Wenn ich mehrere Bytes übertragen will seh ich an dem Funkscanner (Kopfhörerausgang) wie nur das letzte Byte von insges. 8Bytes übertragen wird. (Ich hab extra die Baudrate stark heruntergesetzt) Ich stell mal die Bilder rein (Alles bei sehr langsamen 2kbps) Bild 1: Signal 0xAA Bild 2: Signal 0xFF Bild 3: Signal 0xAA im zusammenspiel zum SPI Ich werd mal in meinen Programm das SDO berücksichtigen (so wie Rainer es sagt) und die Baudrate wieder hochdrehen. Mal gucken was dann kommt. MfG und Danke Matthias
Wenn du SDO nicht berücksichtigst, also nicht wartest, bis die Daten gesendet wurden, dann überschreibst du mit den neuen Daten die noch zu sendenden Daten. Das Ergebnis ist auf jeden Fall nicht das was gewünscht ist und er sendet auch nicht mehr alle Bytes.
Hallo, wenn man nicht nIRQ sondern das FIFO-Statusit abfragt, gibt es noch eine Falle: SDI muß L sein wenn nSEL auf L geht, damit der RFM das FFIT/RGIT-Bit auf SDO legt. SDI L bei der H/L-Flanke leitet ein Status-Read ein und nur dann ist SDO als Status gültig. Also immer schön komplette Zyklen machen, SDI auf L, nSEL aktiv, SDO testen auf H, wenn ja -> Kommando + Byte raus/rein, nSEL auf H usw. Gruß aus Berlin Michael
Moin Der Sender müsste laut Funkscanner richtig laufen und am RSSI Pin vom Empfänger kann ich nun auch das Signal messen. Aber trotzdem ist der FIFO des Ampfänger immer noch leer. Komischerweise liefert mir das Statusregister des Senders folgende Aussagen: - RSSI/ATS (ATS = )(RSSI = Die Signalstärke ist über dem eingestelltem Limit) => unabhängig davon wie Stark ich den Sender einstelle - OFFS_6 (sign of offset) - OFFS_2 - OFFS_0 => Frequenzoffset (eigendlich normal) Leider empfange ich immer noch nichts (Obwohl der Empfänger nun offen wie ein Scheunentor sein müsste und ich nun das SDO beidseitig berücksitige) Könnte das an dem Sender liegen (RSSI/ATS)? Grüsse aus Emden Matthias
Hallo, auf dem Funkscanner kannst Du erkennen, daß der Sender rictig sendet oder daß er überhaupt was sendet? Wenn Dein Timing für den Sneder nicht stimmt und Du z.B. ein Byte reinschreibst, bevor der RFM das vorige fertig gesendet hat, dann kommen weder 0xAA noch das Syncword beim Empfänger heil an und der Fifo starte nie. Ich habe jetzt hier nicht alles geschaut, waren Deine Senderoutinen irgendwo dabei? Zur Not kann ich hier auch einen Tiny mit einem RFM12 auf das Steckbrett stecken und mit Deinen Routinen mal was senden, was mein Sensorempfänger empfangen kann. PS: Sendeleistung und Antenne sind erstmal sowas von egal, ich empfange den Sensor aus dem Keller hier im ersten Stock auch ganz ohne Antenne am Empfänger noch stabil. Gruß aus Berlin Michael
Moin, leider konnte ich gestern nicht mehr Antworten da mir was dazwischengekommen ist. Ich hab jetzt eine Zip-Datei erstellt mit meinem Hauptprogramm (Funkmodul.c) und den Routinen für das Funkmodul (RFM.c + .h) Ich hab da auch ein Oszillogram eingefügt (Print09) bei dem ich mir nicht sicher bin ob der Schreibvorgang ins FIFO richtig ist. So wie ich das sehe wird bei dem letzten Bit das SDO auf Low geschaltet. Trotzdem kann ich aber mit dem Funkscanner die gesendeten Daten bei einer niedrigen Baudrate erkennen (Print11). Wäre nett wenn du dir das nochmal ansehen könntest. MfG Matthias
Zu dem Prgramm: LED Grün soll leuchten wenn der Wert 0xCC übertragen und erfolgreich verglichen wurde.
Hallo, ich weiß nicht, ob ich heute dazu komme, das Wetter hier sieht nicht nach Bastelzimmer aus. ;-)) Das SDO auf L könnte ja stimmen (FIFO ist ja jetzt zum Senden bereit. In soclhen Details sind auch die diversen Datenblattunterlagen teilweise sehr unklar. Der Fifo-Init beim Empfang stimmt so nicht wirklich. RFM12_send_cmd(0x82C8); // Empfänger ein und dann RFM12_send_cmd(0xCA81); // set FIFO mode RFM12_send_cmd(0xCA83); // enable FIFO Die Folge muß so sein, erst den Level setzen und dann einschalten. Siehe auch Datenblatt und Codebeispiel von HopeRF (auch wenn das mehr Fehler als Funktionen enthält. ;) Ich versuche mich mal durch Deine Einstellungen zu kramen, ob mir da noch was auffällt. Gruß aus Berlin Michael
Ich seh grad das ich in der Recieve Funktion das Warten auf SDO_Hi noch nicht richtig ist. Ich werd das überarbeiten
So, jetzt wird permanent der Befehl 0xB000 geschickt (Solang SDO==0) unsigned int RF12_RECEIVE(void) { unsigned int FIFO_data; RF12_WRT_CMD(0x0000); LOW_SEL(); while(~PINB&(1<<6)) { FIFO_data=RF12_WRT_CMD(0xB000); //B0xx: FIFO Daten auslesen } } In der Funktion RF12_WRT_CMD hab ich zudem das letzte HI_SEL() entfernt. MfG Matthias PS: Lasst euch durch mich aber nicht das schöne Wetter vermiesen
Weis jemand wie das Signal am Kondensator des RSSI aussehen muss? Ich seh nur an der Flanke das was ankommt, sieht aber nur nach Rauschen aus. Zum Oszillogramm: Oberer Verlauf Empfänger (Pin RSSI) Unterer Verlauf Sender (Aufgenommen mit Funkscanner) MfG Matthias
So wie es ausseiht bekomm ich am Empfänger nun auch ein richtiges Signal. Blos komischerweise bekomm ich keine Daten. Den FIFO les ich wie folgt aus: 1.) Empfänger starten RF12_WRT_CMD(0x82C8); short_delay(); 2.) FIFO Mode einstellen RF12_WRT_CMD(0xCA81); short_delay(); 3.) FIFO aktivieren RF12_WRT_CMD(0xCA83); 4.) SDI auf false 5.) Chipselect auf false 6.) Warte auf SDO Hi und lese aus 7.) Chipselect auf Hi Hab ich es soweit richtig verstanden wie man den FIFO ausliest oder muss man vorher noch das Stautusregister auslesen (was man ja eigendlich nur beim senden machen muss)? Und wie ist der Ablfauf bei Punkt 6. mit dem SDO? Ist er die ersten acht Bits permanent auf true und gibt dann die Daten aus? MfG Matthias Zum Oszillogramm: Oberer Verlauf: Empfänger (Pin RSSI) Unterer Verlauf: Sender (Aufgenommen mit Funkscanner)
Schau dir doch einfach mal meine v_Receive_rfm12 Methode an. Die funktioniert bei mir sehr zuverlässig. Das ich MOSI (oder SDI) nicht auf 0 setze liegt dadran, daß es standardmäßig auf 0 liegt bei meinem Controller.
Also Statusregister auslesen musst du weder beim empfangen noch senden. Das einzige was du brauchst ist das Prüfen auf SDO, was dem ersten Bit (FFIT/RGIT) des Statusregisters entspricht. Also man könnte sagen du prüfst auf das erste Status-Bit, aber nicht auf das gesamte Statusregister. Du prüfst auf SDO als Pin und nicht per SPI. Sobald SDO=1 startest du die Abfrage per SPI indem du 0xB000 schreibst und von den empfangenen 16Bit die letzten 8Bit sind dann deine Daten. In meinem Code siehst du anhand "while(SDO == 0);", daß ich direkt den Pin SDO prüfe, was nichts mit SPI zu tun hat.
Hallo, da mein Eigenbau-Logic-Analyzer ja noch am RFM12 hängt hier mal der Empfangszyklus. Ähnlich auf meiner Homepage http://www.avr.roehres-home.de/logikanalyzer/s_index.html Dei Software ist auch auf meiner Homepage im Archiv mit drin, bei den Sensoren der USB-Empfänger. Gruß aus Berlin Michael
@Rainer: Mein Programm hat nun denselben Ablauf wie deins, bleibt aber leider in der while(SDO==0){} Schleife hängen. Die Schleife ist für mich auch logisch, überschreibe den Wert solange bis SDO was ausgibt und gebe diesen Wert anschließend zurück.
Hallo, Matthias S. schrieb: > Mein Programm hat nun denselben Ablauf wie deins, bleibt aber leider in > der while(SDO==0){} Schleife hängen. > > Die Schleife ist für mich auch logisch, überschreibe den Wert solange > bis SDO was ausgibt und gebe diesen Wert anschließend zurück. ich habe jetzt keine Gelegenheit, mir das zu SDO gehörige #define oder macro zu suchen. Da SDO ja ein Bit eiens Ports ist, muß ja was in der Art while((Portx & (1<<SDO)) == 0); dahinterstecken. PS: einer der Gründe, weshalb ich auch in C die "Normal-" Schreibweise bevorzuge, erspart mir an solchen Stellen das nachschauen, was da eigentlich passieren soll... Gruß aus Berlin Michael
Genau, ich hab da eine While Schleife eingefügt, die laut dem Debugger und dem Logikanalyser soweit funktioniert :( Ist bei euch der Abstand der beiden Geräte und die Antennenlänge egal? Ich hab den Verdacht dass das Signal bei Empfänger nicht richtig verarbeitet wird und deshalb der FIFO immer leer ist.
Hallo, ja, ist in weiten Grenzen egal.
1 | RFM12_send_cmd(0x0000); // Status read |
2 | RFM12_send_cmd(0xC080); // CLK-Frequenz / Batterie-Level |
3 | RFM12_send_cmd(0x80D7); // FIFO ein, C = 11,5pF |
4 | RFM12_send_cmd(0xC2AB); // Thresold, Filter |
5 | RFM12_send_cmd(0xCA81); // FIFO-Level, |
6 | RFM12_send_cmd(0xE000); // WakeUp aus |
7 | RFM12_send_cmd(0xC800); // Low Duty Cycle aus, |
8 | RFM12_send_cmd(0xC4F3); // AFC |
9 | RFM12_send_cmd(0xA620); // Frequenz |
10 | RFM12_send_cmd(0x948C); // Bandbreite |
11 | RFM12_send_cmd(0xC610); // Baudrate 19200 |
Du kannst ja die Parameter, die ich benutzt mal vergelichen oder benutzen, für den RFM12 als Sender habe ich nichts zur Hand (RFM02 als Sender...). Denek aber daran, ich habe 433MHz Module, Band usw. ist also anders. die die etwas kommentiert ist, hier noch die Sendeeinstellungen des RFM02:
1 | rfm02_send_cmd(0xCC00); // Status read |
2 | rfm02_send_cmd(0xC0E0); // Power Settings: Quarz ein, Synthesizer und PA ein bei Send-Command |
3 | rfm02_send_cmd(0xC2A0); // low bat detector, TX Bit Sync, WakUp-Timer Calibrierung aus |
4 | rfm02_send_cmd(0x8883); // Control: 1MHz Clock Out, 12,5pF Last Quarz, 120kHz Shift |
5 | rfm02_send_cmd(0xA620); // Frequenz: 430MHz + (0,0025 * 0x620) -> 433,92MHz |
6 | rfm02_send_cmd(0xB200); // Power 2 * -3dBm -> -6dBm |
7 | rfm02_send_cmd(0xD2C0); // Set PLL: set 33% |
8 | rfm02_send_cmd(0xC810); // Baudrate: 344827 / 19200 = 17 - 1 -> 0x10 |
Gruß aus Berlin Michael
Moin moin, mit deinen Registereinstellungen Empfängt er was, ich sende zwar CC mein Display zeigt aber E6 an. Das Bitmuster ähnelt sich 11001100 CC 11100110 E6 -> Also um einen nach rechts verschoben. Und wenn ich aus CC AA mache ändert sich der Wert beim Empfänger Aber trotzdem könnt ihr euch nicht vorstellen wie sehr ich mich gerade freue. :-D :-D :-D Mal gucken warum kein CC ankommt, aber immerhin MfG und vielen Dank an Michael und Rainer
Matthias S. schrieb: > @Rainer: > Mein Programm hat nun denselben Ablauf wie deins, bleibt aber leider in > der while(SDO==0){} Schleife hängen. > > Die Schleife ist für mich auch logisch, überschreibe den Wert solange > bis SDO was ausgibt und gebe diesen Wert anschließend zurück. Hmm ich glaube du hast das etwas falsch verstanden. Du sollst in der While Schleife nicht dauernd per SPI den Empfangsfifo abfragen, sondern warten und gar nichts machen, solange bis SDO auf 1 wechselt und genau dann den Empfangsfifo abfragen. :) Wenn du genau hinschaust, dann siehst du, daß meine while Schleife ein Semikolon am Ende hat, weshalb er genau in der einen Zeile wartet und keinen weiteren Code ausführt. Es muss also lauten "while(SDO == 0);" und nicht "while(SDO == 0){...}" ;) Michael U. schrieb: > ich habe jetzt keine Gelegenheit, mir das zu SDO gehörige #define oder > macro zu suchen. > > Da SDO ja ein Bit eiens Ports ist, muß ja was in der Art > > while((Portx & (1<<SDO)) == 0); > > dahinterstecken. > > PS: einer der Gründe, weshalb ich auch in C die "Normal-" Schreibweise > bevorzuge, erspart mir an solchen Stellen das nachschauen, was da > eigentlich passieren soll... Naja, "normal" ist Definitionssache. Denn SDO ist kein Makro sondern direkt der Portpin des Controllers. Bei den 8051ern sind alle Ports und viele SFR direkt bitadressierbar, weshalb ich eben nicht diesen "Umweg" über "(Portx & (1<<SDO)) == 0" gehen muß sondern direkt den Pin abfragen kann. Finde ich weit aus schneller und einfacher als wenn ich erst den Port einlesen und dann den Pin ausmaskieren müsste. ;) Ciao, Rainer
Moin Mein Quelltext sieht nach dem ganzen herumgebastle eh ein bischen bescheiden aus. @Rainer Jetzt hab ich das Semikolion auch gesehen -.- sry mein Fehler. Leider bin ich jetzt nicht mehr in meinen Labor aber ich werd das morgen früh gleich ausprobieren. Aber das beim ändern des zu übertragenen Wert sich der Angezeigte Wert am Empfängerdisplay ändert ist für mich wenigsten ein gutes Zeichen. Heut Abend guck werd ich nochmal die Registereinstellungen von Michael mit meinen alten vergleichen, vielleicht bemerk ich dann den entscheidenen Unterschied. Aber ich bin froh das ich was empfange und kann heut Nacht wenigstens besser Schlafen ;-). MfG und schönes Wochenende Matthias
Hallo, Matthias S. schrieb: > mit deinen Registereinstellungen Empfängt er was, ich sende zwar CC mein > Display zeigt aber E6 an. > > Das Bitmuster ähnelt sich > > 11001100 CC > 11100110 E6 > > -> Also um einen nach rechts verschoben. Die linke 1 dürfte noch zum Bit 7 des Kommandos gehören. Da stimmt das Timing nicht, mit dem Du das empfangene Bit einliest oder Du schiebst falsch rein. Ich vermute mal, Du bist da zu schnell, der Fifo kann nicht so schnell gelesen werden wie die Register des RFM. Meine Leseroutine de Daten
1 | for (j=0; j<8; j++) |
2 | {
|
3 | byte = (byte << 1); // eins höher schieben |
4 | if ((RFM12_PIN & (1<<RFM12_SDO)) == (1<<RFM12_SDO)) // Bit 1? |
5 | {
|
6 | byte = (byte | 0x01); // ja |
7 | }
|
8 | asm("nop"); |
9 | RFM12_PORT |= (1<<RFM12_SCK); // CLK auf H |
10 | asm("nop"); |
11 | asm("nop"); |
12 | RFM12_PORT &= ~(1<<RFM12_SCK); // CLK auf L |
13 | }
|
14 | *data_buf++ = byte; |
15 | RFM12_PORT |= (1<<RFM12_CS); // CS auf H |
Gruß aus Berlin Michael
Michael U. schrieb: > Ich vermute mal, Du bist da zu schnell, der Fifo kann nicht so schnell > gelesen werden wie die Register des RFM. Ich weiß ja nicht, auf welche Bitrate er mit seinem software SPI kommt. Aber ich betreibe den RFM12 per hardware SPI mit 2 Mbps ohne Probleme auch beim Auslesen des Empfangsfifo. Laut Datenblatt kann der Fifo nur mit maximal f(res)/4 getaktet werden, was bei 10MHz Quarzfrequenz des RFM12 dann 2,5 Mbps entspricht. Wenn er software SPI benutzt muß er natürlich darauf achten, daß die Timings eingehalten werden. :) Ciao, Rainer
Hallo, Fox Mulder (quakeman): mache ich in einem anderen Projekt ähnlich, auch keine Probleme. Beim Soft-SPI ist es eigentlich prinzipiell merklich langsamer, aber man schafft es schnell, daß 2 Port-Befehle zum setzen/löschen direkt hintereinander geraten. Dann ist der effektive Takt zwar durchaus nur ein paar 100kHz, der Pegelwechsel beider Signale in dem Moment eigentlich 5MHz bei 10MHz AVR-Takr. Da fragt man dann schnell die Leitung ab, bevor deren Pegel stabil ist. In ASM habe ich da keine Probleme, in C darf ich da öfter ins .lss schauen, wenn ich nicht nutzloses Sicherheits-Warten betreiben will. ;-) Sein Bitmuster sieht einfach so aus, als ob er entweder falsch reinschiebt oder liest, bevor SDO nach Taktwechsel auf dem neuen Pegel ist. Gruß aus Berlin Michael
Moin, mit dem Timing ist alles i.O., bloss ich hab dummerweise das Verschieben der Daten am Anfang der Leseroutine gelegt, ist mir bei dem herumgebastle wohl versehentlich passiert. Aber jetzt zeigt er mir den richtigen Wert am Display an. Mich wundert nun bloss warum in dem "schönen" Beispiel von HopeRF das Statusregister ausgelesen wird, bevor die auf das FIFO beim Empfangen eingehen. MfG Matthias
Na das ist doch sehr schön. Nachdem der Grundstein jetzt gelegt ist kannst du ja fröhlich herumexperimentieren mit den RFM12. :) Ich habe damals als ich mit denen angefangen hatte lieber erst mal hardware SPI genommen, da ich möglichst alle Fehlerquellen ausschließen wollte zu Beginn. Deshalb lief es bei mir zum Glück auch so ziemlich auf Anhieb. Aber da sieht man mal wieder, daß der Teufel im Detail steckt. Wegen dem Statusregister habe ich nur gelesen, daß es wohl Sinn macht das nach dem Reset mindestens einmal auszulesen, da das RFM12 ansonsten wohl manchmal etwas herumspinnen könnte. Aber ein generelles auslesen hat meiner Meinung nach keinen weiteren Sinn. Was davon überhaupt stimmt ist aber fraglich, da davon nichts im Datenblatt drinsteht. ;) Ciao, Rainer
Ich werd mich nun mit dem Übertragen von Nutzdaten beschäftigen (CRC, Zieladressen usw.). Könnt ihr eure Signale quer durch mehrere Wände (ca. 4) empfangen? MfG und vielen Dank nochmal für euren Support Matthias
Hallo, Fox Mulder schrieb: > Wegen dem Statusregister habe ich nur gelesen, daß es wohl Sinn macht > das nach dem Reset mindestens einmal auszulesen, da das RFM12 ansonsten > wohl manchmal etwas herumspinnen könnte. Aber ein generelles auslesen > hat meiner Meinung nach keinen weiteren Sinn. Was davon überhaupt stimmt > ist aber fraglich, da davon nichts im Datenblatt drinsteht. ;) Die Behauptung, das es gut ist als allererste Amtshandlung das Statusregister zu lesen, stammt u.a. von mir. Ich hatte sonst manchmal unberechenbares Verhalten nach PowerOn/Reset. Sender war scheinbar an, sendete aber nicht, Sender sendete, kam aber nichts an usw. Ich hatte den Status dann beim Start als Debug ausgelesen und die Fehler traten promt nie wieder auf... Zur eigentlichen Ursache kann ich also nichts sagen. Auch die Empfehlung, einen Elko ca, 10µ über die BEtriebsspannung der RFM-Module zu legen, stammt von meinen Sensoren. Ohne diesen wachten die irgendwann nicht mehr aus dem Sleep auf, die Stromaufnahme lag dann teilweise bei mehr als 25mA und das fanden meine Batterien nicht lustig. Da die Sensoren jetzt seit einem Vierteljagr absolut stabil alle Minute ihre Daten schicken, scheint es zu helfen. Matthias S. schrieb: >Könnt ihr eure Signale quer durch mehrere Wände (ca. 4) empfangen? Wird stark von den Wänden abhängen... Mein Sensor im Keller ist ca. 6m entfernt, Altbau, 2 Decken. Den empfange ich auch stabil komplett ohne Antenne am Empfänger. Gruß aus Berlin Michael
Michael U. schrieb: > ... > Auch die Empfehlung, einen Elko ca, 10µ über die BEtriebsspannung der > RFM-Module zu legen, stammt von meinen Sensoren. Ohne diesen wachten die > irgendwann nicht mehr aus dem Sleep auf, die Stromaufnahme lag dann > teilweise bei mehr als 25mA und das fanden meine Batterien nicht lustig. > > Da die Sensoren jetzt seit einem Vierteljagr absolut stabil alle Minute > ihre Daten schicken, scheint es zu helfen. > ... Den Kondensator hab ich bei mir auch berücksichtigt, da ich das auch hier im Forum gelesen hab. Ich bin vorhin mit einem Mobilen Funkscanner der mir das Frequenzspektrum angezeigt hat durch das FH Gebäude gelaufen und konnte nur direkt vor dem Labor ein gedämpfte Signal empfangen. Aber in diesem Gebäude sind eh ziemlich dicke Wände und viele Stahlschränke die das Signal ordentlich dämpfen. Ich bin mal gespannt wie das bei mir Zuhaus aussieht. MfG Matthias
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.