Hi!
Ich habe zwei RFM69W-Module vor mir liegen, die ich mit einem
STM32-Nucleo Board verbunden habe (an getrennten SPIs; DIOs habe ich
bisher nicht verwendet).
Ich möchte ein Byte von einem RFM69-Modul zum anderen senden.
Es ist mir egal
- mit welcher Datenrate
- ob verschlüsselt wird
- ob CRC geprüft wird
- ob die Sendeleistung automatisch angepasst wird
- usw
Einfach ein Byte von A nach B zu bekommen würde mir (vorerst) reichen.
Ich habe Probleme damit, alle Register korrekt zu initialisieren (auch
nach mehreren Abenden Datenblattstudim).
Was schon geht:
SPI-Kommunikation vom µC zu den beiden Modulen, ich kann Register
schreiben und deren Wert auch wieder abfragen.
Was ich suche:
Eine Sequenz an Register-Initialisierungen für ein Minimalbeispiel, z.B.
sowas:
Reg 0x01 am Empfänger auf 0x12 setzen
Reg 0x02 am Empfänger auf 0x34 setzen
Reg 0x03 am Empfänger auf 0x56 setzen
Reg 0x04 am Sender auf 0x78 setzen
Reg 0x05 am Sender auf 0xAB setzen
...
Fertige Libs habe ich nicht viele gefunden, wenn dann waren sie für
Raspi oder Arduino oder nicht in C geschrieben, also schwer
auszuprobieren.
Das kenne ich natürlich, aber hier wird sehr viel mehr gemacht als
unbedingt nötig, außerdem sehe ich zwar Werte für Register, das konkrete
Prozedere für Senden/Empfangen auf SPI-Ebene ist aber aus dem Code sehr
schwer herauszufinden.
Hast du das hier schon mal angeschaut:
Beitrag "Re: Wer verwendet RFM69?" ?
In der RFM69.c gibt es eine Funktion rfm_init(), in der die
entsprechenden Kommandos stehen. Bei Rückfragen zu den einzelnen
Einstellungen, bin ich gerne bereit zu helfen.
Ich habe heute auch mit dem RFM69CW angefangen. Es gibt eine Software
für ein SX1231 Starter-Kit von Semtech zum Download. Ohne
angeschlossenes Board ist die Software erstmal inaktiv, aber man kann
mit Strg+Alt+N das übergehen (Weiß leider nicht mehr, wo ich das
aufgeschnappt habe).
Damit kann man sich eine Konfiguration zusammen klicken und aus der
gespeicherten Datei die Registerwerte recht komfortable extrahieren z.B.
mit Excel Verketten-Funktion.
Fertiges Beispiel habe ich aber leider noch nicht aber gerade gesehen,
dass sich grundsätzlich etwas halbwegs sinnvolles tut ;o)
Bin jetzt aber mehr mit Löten beschäftigt, als mit Programmieren.
Felix, ich spiele gerade mit deinem Code.
Ich kann Register nicht zuverlässig schreiben.
Wenn ich z.B. in Register 5 den Wert 2 schreibe und anschließend
zurücklese steht eine 0 drin.
Bei manchen Registern funktioniert es, bei manchen nicht.
Woran könnte das liegen?
Ich kontrolliere die SPI-Kommunikation mit einem Logic Analyzer.
Zweite Frage: Warum initialisierst du in deinem Code 20 Mal in einer
Schleife? Hängt das damit zusammen?
Ich habe mal einen Screenshot des Logic Analyzers angehängt. Man
erkennt, dass die Bytes 0x86 (= Schreibzugriff auf Register 6) und 0xE1
(neuer Wert für das Register) gesendet werden. Genau das erwarte ich
auch.
Auf MISO antwortet das RFM69-Modul mit 0x40, das ist der alte Wert des
Registers. OK.
Aber wenn ich mehrmals hintereinander 0x86 0xE1 schicke, antwortet das
Modul IMMER mit 0x40, d.h. es übernimmt meinen Wert nicht. Warum?
Muss man das Modul in einen bestimmten Modus schalten, bevor man die
Register beschreiben kann? Im Datenblatt habe ich dazu nichts gefunden.
Dass Werte nicht direkt übernommen werden, kenne ich nur von den drei
Frequenzregistern 0x07, 0x08 und 0x09. Die Werte in 0x07 und 0x08 werden
erst aktualisiert, nachdem man auch 0x09 geschrieben hat.
Wie hast du den Reset-Pin am RFM69 beschaltet?
Hintergrund: Ich komme ursprünglich vom RFM12, wo ich immer einen
10k-Pullup an Reset (beim RFM12 NRES) hatte, und habe den in meinen
Layouts immer weiter verwendet - hat super funktioniert. Irgendwann las
ich dann mal im Datenblatt, dass die Reset-Logik beim RFM69CW eine
andere sein soll, habe auf den Pullup verzichtet und den Pin floaten
lassen: Das führte dann zu seltsamem Verhalten und Empfangsausfällen.
Solltest du also nicht erklärbares Verhalten feststellen und den
Reset-Pin nicht beschaltet haben, versuch es mal mit einem 10k-Pullup
oder -Pulldown.
Das mehrfache Schreiben der Config war ursprünglich als
Sicherheitsmaßnahme gedacht, ja. Ob es irgendwas bringt, weiß ich nicht.
Ich hatte den Reset-Pin nicht verbunden gehabt. Ich versuche es jetzt
mit einem 10K-Pulldown.
Über was ich auch gestolpert bin: Manche Bits in Registern lesen sich
immer als 0, auch wenn man eine 1 drauf geschrieben hat ("write one to
clear").
Hier muss man beim zurücklesen auch aufpassen.
Ich werde es weiter probieren und berichten...
Markus R. schrieb:> Muss man das Modul in einen bestimmten Modus schalten, bevor man die> Register beschreiben kann? Im Datenblatt habe ich dazu nichts gefunden.
Ich setze SS auf low und schicke den Schreibbefehl auf Register 0x01 und
dann die ganzen Bytes (Copy&Paste aus dem genannten Programm bis
ausschliesslich Temperatur-Register 0x4E) über die SPI-Schnittstelle.
Dann wieder SS auf high.
Bei mir gibt es beim Wiederauslesen der Register 0x01 bis 0x4D nur
Abweichungen bei 0x0B (einige bytes unused) und 0x24 (read only). Sollte
also ok sein.
Beim RFM69CW als Transmitter erscheint auf meinem GY561-Frequenzzähler
auch die richtige Frequenz. Auch der Clockout wird geändert. Bei mir
läuft die SPI-Übertragung vermutlich also.
Felix P. schrieb:> Hintergrund: Ich komme ursprünglich vom RFM12, wo ich immer einen> 10k-Pullup an Reset (beim RFM12 NRES) hatte, und habe den in meinen> Layouts immer weiter verwendet - hat super funktioniert.
Verstehe ich Dich wirklich richtig. Ein RFM69CW arbeitet gut mit einem
Pullup am Reset-Eingang?
Ich habe arbeite gerade auch mit einem Leiterplatten-Design, dass
ursprünglich für den RFM12 gedacht war (Reset mit uC verbunden und an
Pullup) und bin heute auf die Stelle im Datenblatt bezüglich des Reset
gestoßen. Ca. eine Stunde vor Deinem Posting habe ich die Leiterbahnen
durchgetrennt ;o)
Das Datenblatt spricht ja schon vom Floaten lassen und der ClkOut läuft
auch während des Reset weiter und man kann ihn nicht zur Überprüfung
verwenden.
Vielleicht sicherheitshalber wirklich einen Pulldown anlöten?
Ansonsten muss ich eher noch mit den Einstellungen experimentieren.
Klaus I. schrieb:> Verstehe ich Dich wirklich richtig. Ein RFM69CW arbeitet gut mit einem> Pullup am Reset-Eingang?
Ja, das verstehst du richtig.
Offenbar sind die 10k genug, damit der Pin sich keine Störungen
einfängt, aber auch nicht ausreichend, um wirklich einen Reset
auszulösen.
Hatte wie gesagt nicht groß darauf geachtet, als ich die Module
getauscht habe und es gab nie Probleme - die traten erst auf, als ich
den Pin floaten ließ.
Ich habe mit den Parametern gespielt und habe jetzt eine funktionierende
Kommunikation zwischen zwei RFM69CW hinbekommen. Reichweite ist min. 17m
in meiner Wohnung. Reset ist aktuell floatend.
@Markus
Die angehängten Beispiele sind für 433 MHz. Ich hoffe das passt für
dich?
Wie gesagt ich schreibe sämtliche Register bis ausschließlich
Temperatur-Register in einen Rutsch. Minimalbeispiele habe ich noch
nicht probiert.
Edit: Für Verbesserungsvorschläge wäre ich sehr dankbar, aber so läuft
es erstmal für die ersten Experimente
Felix P. schrieb:> Hatte wie gesagt nicht groß darauf geachtet, als ich die Module> getauscht habe und es gab nie Probleme - die traten erst auf, als ich> den Pin floaten ließ.
Super Hinweis, Merci vielmals.
Habe gerade ausprobiert: Floaten, Pull-up und Pull-Down. Funktioniert
anscheinend alles, werde den RESET aber sicherheitshalber nicht mehr
floaten lassen.
Im Moment macht mir die CRC-Funktion Kummer. Ohne CRC läuft es gut, aber
mit CRC auf beiden Seiten aktiviert kommt nichts sinnvolles mehr an bzw.
CrcOK-Pin wird nicht gesetzt. Wenn man dennoch den FIFO ausliest bekomme
ich immer das gleiche Zeichen meistens 111111... (Fixed length 32 byte).
Um CrcOK habe ich mich nie gekümmert, ich habe die Funktion CrcAutoClear
(d.h. Bit 3 im Register 0x37 = 0, Bit 4 = 1, damit Crc überhaupt aktiv
ist) aktiviert und frage das Bit PayloadReady ab. Das wird nur gesetzt,
wenn der CRC erfolgreich war, ansonsten wird das Empfangene gleich
verworfen.
Bei mir geht es mittlerweile, danke v.a. an Felix.
Da ich es auf einem STM32-Controller versucht habe, bei dem ich mich
v.a. an die SPI-Kommunikation mit dem RFM69 herantasten musste, war
meine Herangehensweise folgende:
Alle Register initialisieren und danach zurücklesen.
Das Zurücklesen hat jedoch seine Tücken:
1. Die "write one to clear" bits in manchen Registern lesen sich
natürlich immer als 0, obwohl 1 reingeschrieben hat
2. Manche Register übernehmen den Wert nicht sofort, sondern ein anderes
Register zeigt an, wenn der Vorgang abgeschlossen ist
(Zustandsübergänge)
3. Die Register mit der Carrier- Frequenz übernehmen den Wert erst, wenn
man alle drei geschrieben hat.
Dies alles muss man beim zurücklesen bedenken. Möglicherweise hatte ich
auch mit dem Reset-Pin ein Problem.
Ich hänge mal mein funktionierendes Minimalbeispiel an (Controller ist
ein STM32F302R8).
Vielen Dank an alle!