Hi,
ich möchte 2 RFM12 miteinander kommunizieren lassen. Klappt natürlich
bisher nicht. Also Fehlersuche. Die guten Datenblätter/
Beispielprogramme habe ich schon erfolglos durchforstet.
Ich weiss durch ein Funkempfänger dass mein Sender sendet. Sowohl
Trägerfrequenz als auch Daten.
Beim Empfänger kommt nichts an. Also habe ich mir erst mal das Auslesen
der
Statusbytes vorgenommen... da bekomme ich auch nix.
Ich verwende den Hardware SPI von einem Mega8. für das Status abfragen
einen Software SPI (oder kann man 2x auslesen für die 16Bit?)
Kann mir jemand bitte einen Tipp geben? Danke!
Um 16Bit per SPI zu übertragen einfach 2x hintereinander abfragen. Das
funktioniert problemlos. Du musst nur dadrauf achten, zwischen den
beiden Übertragungen die nSEL Leitung auf 0 zu belassen.
Ciao,
Rainer
Das mit der Statusabfrage habe ich inzwischen hin bekommen. Nun meckert
der Status vom Empänger ich hätte ein zu starkes Sendesignal (RSSI) Und
der FIFO ist leer...
Moins,
grundsätzlich indem du 2 x 0x00 sendest und einliest. Per Hardware SPI
wäre das 0x00 senden -> einlesen. Nochmal 0x00 senden -> einlesen.
Das ist auch nach wie vor das einzige, was ich hinbekommen habe. Mit
einem Frequenzanalyser sehe ich zwar, dass die Trägerfrequenz da ist und
auch was sendet aber mein Empfänger empfängt nichts... wie programmierst
du?
Mir geht es da derzeit ähnlich. TX scheint zu funktionieren, aber RX
funzt noch nicht.
Nochmal zum Auslesen des Statusregisters:
1. 0x00 senden --> Commando zum Auslesen des Statusbyte
2. 0x00 senden --> Ausgabe 1. Statusbyte am SDO
3. 0x00 senden --> Ausgabe 2. Statusbyte am SDO
Ist das so korrekt?
Ich kenn mich zwar nicht so aus mit Hardware-SPI (mache das "per Hand"),
aber ich denke du müsstest in der rfm_com_send das SPDR wieder auslesen.
so ungefähr:
Oh, das ist noch die alte .inc (vom Mai). Damit hatte gar nichts
funktioniert. Ich hatte inzwischen die Default Einstellungen geändert.
Damit habe ich wenigstens ein DQD beim Receiver bekommen. Wenn auch noch
keine Daten.
Ich hänge mal meine neue an.
Es ist natürlich wie Ziegenpeter schreibt:
1. 0x00 senden
2. SPDR einlesen (Bit15-Bit8 vom Status)
3. 0x00 senden
4. SPDR einlesen (Bit7-Bit0 vom Status)
Ah ok, hab nochmal in die neue Version geguckt.
Du scheinst beim Senden garnicht zu warten bzw. zu überprüfen wie der
FIFO-Status ist.
Hab meinen Code jetzt nicht zur Hand, aber ich meine da musst du SDO
abfragen ob 0 (oder umgekehrt), ohne ein komplettes Byte zu lesen.
Normale Register kannst du schreiben ohne zu warten, aber bei Senden (in
den FIFO schreiben) musst du checken ob er bereit ist ein neues Byte
aufzunehmen.
Und noch einen Fehler entdeckt:
1
ldi YH, 0x2d ; Sync Hi-Byte
2
ldi YL, 0xd4 ; Sync Low-Byte
3
rcall rfm_data_send
Das Sync-Word schickst du auch falsch (in YH kommt der Befehl, nicht das
Daten-Byte).
So muss das:
Hallo,
Ich hab gestern den RX Teil des RFM12 im Interrupt hinbekommen. Wie der
Ziegenpeter schon schrieb, muss man da auf "high" des SDO warten, bevor
man über "0xB200" die Daten einliest. Die Daten stehen dann im LSB vom
rückgelesenen Wert von SDI.
Hab dir mal meine vorab RFM12 Routine angehangen. Die ist für einen
ATtiny2313 geschrieben. Also ohne Hardware SPI. Aber das Prinzip wird
dadurch hoffentlich klarer.
Gruß Steffen
Das sind ja mal super Tipps.
Natürlich habe ich meine Testplatinen bei der Arbeit liegen. Also komme
ich erst Montag dazu das zu testen :(
Nach dem Oszillogramm habe ich aber schon einen Fehler gesehen (Mal
abgesehen von dem Syncwort - Ist ja irgendwie logisch...
Den /CS habe ich immer runtergezogen, die Übertragung gemacht und dann
wieder auf HIGH gesetzt. Ich hatte den Eindruck das funktioniert auch?
Sobald du den Empfänger eingeschaltet (0x8280) und den FIFO
initialisiert (0xCA81)+(0xCA83) hast musst du /CS auf LOW setzen und nun
auf SDO = high warten.
Ist SDO = high kannst du mit 0xB000 ein Datenbyte aus dem FIFO lesen.
Die sync-Bytes werden ja normalerweise (nur wenn du es selber so
wünscht) nicht in den FIFO geschrieben. Du hast also die reinen
Nutzdaten im FIFO stehen.
Wenn du es mit deiner "rfm_com_send" machst, dann wird ja erst CS auf
LOW gezogen, dein Datenbyte eingelesen und dann CS wieder auf High
gesetzt. Soweit alles okay. Wenn deine gesendeten Daten aus mehr als ein
Byte bestehen musst du ja jetzt weitere Bytes aus dem FIFO lesen, bevor
du de FIFO wieder resetest. Dazu musst du also nach dem "rfm_com_send"
den CS wieder auf LOW ziehen und auf SDO = High warten bis du das
nächste Byte aus dem FIFO lesen kannst.
Zur INFO: FIFO RESET =
FIFO wartet nun wieder auf eintreffende Sync-Bytes bevor er gefüllt
wird. Alle anderen empfangenen Bytes werden vom FIFO ignorriert.
Ich hoffe ich hab jetzt keinen Fehler gemacht.
Steffen
Super!!!
Das ist eine tolle Erklärung. Vielen Dank, das hat mir sehr geholfen.
Ich habe noch eine Frage zum nIRQ (PIN 2 am RFM12).
Diesen Pin möchte ich gerne nutzen, um am Mikrocontroller einen ext.
Interrupt auszulösen.
D.h: wenn Nutzdaten am Empfänger eintreffen, soll der nIRQ einen
Interrupt auslösen und in der Interrupt-Routine wird das FIFO mit den
empfangenen Daten ausgelesen.
Weis jemand, welche Einstellungen ich am RFM12 vornehmen muss?
Danke!
ehtersex hat RF12 support und kann mit dem Modul sowohl im
polling-Betrieb wie auch Interrupt-gesteuert umgehen. Hab ich allerdings
nie getestet, vlt. findest du im Source ja Anhaltspunkte, wie das Modul
konfiguriert werden kann.
https://github.com/ethersex -> ethersex hardware radio / rfm12
HTH! :)
Hallo
Ich hab auch gedacht, ich könnt den nIRQ Pin als Interrupt benutzen.
Allerdings bleibt der bei meinem RFM12 ständig auf LOW! Hab es sogar mit
Pullup Widerstand (10k gegen VCC) versucht. Aber nichts zu machen.
Dauer-low.
Ich benutze nun den SDO Pin für den Interrupt!
1. Ich brauche nur 4 Leitungen zum RFM12
2. Der SDO wird HIGH wenn der FIFO gefüllt ist -> Interruppt auf
steigende Flanke
Das klappt herrvorragend so. Das geht gleichermaßen im RX und im TX
Modus.
Wenn man den SDO zum Auslösen des Interrupts nimmt, muss man halt nur
den Interrupt ausschalten nach dem Eintritt in die ISR. Sonst wird ja
stets und ständig ein neuer Interrupt durch das Auslesen des FIFO's
erzeugt. Denn da liest man ja denn die Daten über SDO ein.
Dann nur noch darauf achten den Interrupt vor verlassen der ISR wieder
eizuschalten.
Ach ja, der /CS sollte auf LOW sein während man auf den Interrupt
wartet.
Schönen 1.Advent
Steffen
Ich habe eine Frage zum unten stehenden Codeausschnitt:
rf12_trans(0x8238); // TX on
rf12_ready();
Das verstehe ich: TX einschalten und auf FIFO warten
Danach kommen 5x Datenübertragungen (AA,AA,AA,2D,D4)! Was hat das für
einen Sinn?
Wenn ich aber diesen Teil entferne, werden aber keine Daten mehr
übertragen.
Kann mir bitte jemand erklären warum?
In der For-Schleife werden die Daten des Arrays nacheinander gesendet
bis number erreicht wird.
1
voidrf12_ready(void)
2
{cbi(RF_PORT,CS);
3
while(!(RF_PIN&(1<<SDO)));// wait until FIFO ready
weiss ich jetzt nicht mehr, evtl. auch in dem von SiLabs von denen wohl
der Chip da ist. Vieles hab ich aus dem Thread von Benedikt
herausgelesen.
Holger
Je nachdem welches Datenblatt du hast. Ich empfehle das RF12
(http://www.hoperf.com/upload/rf/RF12.pdf). Das sind die besten
Informationenen drin. Das vom RFM12
(http://www.hoperf.com/upload/rf/RFM12.pdf) ist auch ok.
In den Datenblättern steht unter:
7.FIFO & Reset Mode Command
Das Bit2 (al) der FIFO bei erkannten Sync Bytes gefüllt wird.
(Empfänger)
Konnte das basteln nicht abwarten und habe mir vorhin meine Tranceiver
geholt und bearbeite gerade die .incs :-)
Steffen H. schrieb:> Ich benutze nun den SDO Pin für den Interrupt!> 1. Ich brauche nur 4 Leitungen zum RFM12> 2. Der SDO wird HIGH wenn der FIFO gefüllt ist -> Interruppt auf> steigende Flanke
Wow.. Ganz so einfach war es dann doch nicht. Dieses gilt nur für RFM12
RX.
Im RFM12 TX Mode ist es ein bisschen anders.
1. Problem:
Nach dem Umschalten des RFM12 in den TX-Modus ist der SDO erst mal auf
HIGH. Also wird der Interrupt (steigende Flanke) erstmal nicht
ausgelöst. :-(
2.Problem:
Wenn das letzte Datenbyte an den FIFO übergeben wurde heißt das ja
nicht, dass es auch schon gesendet wurde. Man kann den RFM12 TX Modus
also noch nicht werlassen!
Ich hab dafür bis jetzt noch keine anständige Lösung gefunden. Die
ganzen Codes von Benedikt laufen im polling Betrieb ab.
Ich will aber RX und TX im Interrupt erledigen lassen. Dafür hab ich mir
ein RF_FLAG Register angelegt wo unter anderem das Flag "rf_ready" und
"rf_mode" drin ist.
Ich mache es jetzt so:
>>Umschalten von RX -> TX -> und wenn fertig wieder alles aus
1. RFM12_rf_off (0x8208) -> /CS = HIGH
2. 1ms warten
3. Sendebuffer mit Daten zum Senden füllen
4. Pointer auf Sendebuffer initialisieren
5. Sender RFM12_tx_on einschalten (0x8238) -> /CS = HIGH
Im Flagregister wird das "rf_mode" Flag auf "1" gesetzt
6. nSEL auf Low ziehen (/CS = LOW)
7. mittels rcall Befehl die Interuppt-Routine aufrufen um den FIFO
erstmalig zu füllen
8. Ab jetzt kann man warten bis das "rf_ready" Flag "1" ist
9. Wenn "rf_ready" Flag "1" ist, dann nach 1ms den Sendemodus
ausschalten
-> RFM12_rf_off
Die zwei Punkte 8. und 9. sind noch nicht ganz sauber. Ich hab aber noch
keine Lösung dafür gefunden wie ich erkenne, dass das letzte Datenbyte
den RFM12 verlassen hat. Denn vorher darf man ja den RFM Sender nicht
ausschalten.
Kann mir da jemand helfen? Oder irgendwie auf die Sprünge helfen?
Steffen
Also ich empfange im Interrupt, sende aber ohne.
In der Ini einmal den Status lesen mit 0000 löscht den nIRQ.
Dann schalte ich empfangen ein und die Daten werden per IRQ empfangen.
Zum senden schalte ich den IRQ im PIC aus, sende die Daten, lese den
Status, schalte dann wieder auf Empfang um und gebe den IRQ im PIC
wieder frei
Das funktioniert sehr gut bei mir.
Holger
Ich habe mal meine .inc ein wenig geändert. Leider war es nicht meine
letzte, wo wenigstens das DQD angezeigt wurde. Jetzt habe ich wieder den
Fehler des zu starken Signals... hat da vll jemand eine Idee?
Zu starkes Signal ? wie denn das ?
Sicher dass das Hardware SPI so funktioniert ? Software SPI ist doch so
einfach, da weiss man doch ganz genau ob es funktioniert, vielleicht
stimmen die Einstellungen nicht in der Hardware.
Ich kann nur PIC Assembler und C, mit deinen Sourcen kann ich nicht viel
anfangen.
Ich habe die Inits von Benedikt übernommen und damit von Anfang an keine
Probleme gehabt.
Holger
Sebastian F. schrieb:> rfm12.inc
Das zweite rfm_ready in der rfm_data_send solltest du weglassen.
Wenn er einmal ready ist, dann ist er für die ganzen 16 Bit ready, nicht
nur für das HI-Byte.
Zum Senden im Interrupt-Modus wollte ich noch schreiben, dass ich es so
mache (benutze aber die eigentliche IRQ-Leitung nicht die SDO):
Wenn ich mit den eigentlichen Daten fertig bin, schiebe ich noch ein
"Padding-Byte" in den FIFO.
Wenn der RFM12 bereit ist, noch ein Byte aufzunehmen, schalte ich ab,
weil im FIFO Platz für zwei Byte ist. D.h. wenn ich ein Padding-Byte
drin hab und noch eins reinschieben dürfte (mach ich aber nicht), sind
alle Nutzdaten gesendet und ich kann abschalten.
Sebastian F. schrieb:> Ich habe mal meine .inc ein wenig geändert. Leider war es nicht meine> letzte, wo wenigstens das DQD angezeigt wurde. Jetzt habe ich wieder den> Fehler des zu starken Signals... hat da vll jemand eine Idee?
Was funktioniert denn jetzt noch nicht richtig?
Hast du einen funktionierenden Sender? Dann kannst du ja erst mal deinen
RFM12 Receiver zum funktionieren bringen.
Gruß Steffen
Steffen H. schrieb:> Das klappt aber nur beim Senden, oder?
Funktioniert beides ohne Probleme.
Ich hab das ganze schon etwas länger am laufen, deshalb kann ich mich
nicht erinnern ob bzw. welche Probleme ich beim Interrupt hatte. Ich
glaube keine.
An der Schaltung hab ich auch nichts besonderes (IRQ direkt verbunden,
10 KOhm gegen VCC am FSK/DATA/nFFS).
Im Interrupt-Handler lese ich den Status und falls das RGIT/FFIT Bit
gesetzt ist, schreib bzw. lese ich ein Byte in/aus dem FIFO.
Hab mal meinen Interrupt-Handler als Datei angehängt.
Das Problem bei meiner Initialisierung ist, dass der Empfänger beim
Status lesen dauernd Das RSSI-Bit setzt. Da ich von Funktechnik nicht
wirklich Ahnung habe habe ich natürlich beim Empfänger schon
verschiedenste Varianten im "Receiver Control Command" ausprobiert. Aber
nie was Sinnvolles hinbekommen. Mit den Datenblatt-Settings & denen von
Benedikt war es das selbe. Irgendwann hatte ich eine Sender/Empfänger
Initialisierung, die soweit ok war, dass das RSSI nicht mehr kam. Die
ist aber irgenwie verschwunden :-( Ich muss zugeben, dass ich dann das
Projekt auch zur Seite gelegt habe, gerade weil auch keiner in ASM
wirklich helfen konnte.
Jetzt baue ich gerade ein Software SPI zusammen. Eigentlich fertig, will
aber noch nicht richtig...
Mir würde schon die rfm Bibliothek von Ziegenpeter helfen, da ich
gesehen habe, dass er es unter ASM programmiert hat...
Sebastian F. schrieb:> Mir würde schon die rfm Bibliothek von Ziegenpeter helfen
Kein Problem, ich glaub die Vorlage dafür hab ich auch aus irgend einem
Beitrag hier im Forum.
Das Senden und Empfangen der Daten selbst geht nicht über die
rf12_txData/rf12_rxData, sondern über den Interrupt-Handler, den ich
oben schon gepostet hab.
Hier noch die Funktionen, mit denen ich das Senden und Empfangen
anstoße:
Hallo
Ich hab es immer noch nicht hinbekommen mit dem nIRQ als Interuppt. Der
ist ständig auf LOW!
Wie ist denn der Zustand des nSEL (/CS) Eingangs nach der
Initialisierung? Ich setze ihn ja dann auf LOW (aktiv) um mit Interuppt
zu arbeiten.
Steffen
Steffen H. schrieb:> Ich setze ihn ja dann auf LOW (aktiv) um mit Interuppt> zu arbeiten.
Wie du oben in der initRf12Receiving siehst, ist das letzte vor dem
Aktivieren des Interrupt ein readStatus.
Demnach ist der nSel/CS während der Interrupt-Phase auf HIGH gesetzt.
Wenn's nicht das ist - hast du auch den rigtigen nIRQ angeschlossen? Der
ist direkt neben dem SDO.
Könnte mir vorstellen, dass man den INT und IRQ verwechseln könnte.
Christoph B. schrieb:> wäre auch an einem Interrupt Handler in C interessiert
Hallo,
Habe letztes Jahr mit den Modulen experimentiert.
Habe 2x Pollin RFM Boards mit Mega8 benutzt.
Nachdem es funktionierte, habe ich mich gleich wieder etwas anderem
gewidmet. Also noch nicht längere Zeit getestet.
Sind auch Infos aus diesem Forum eingeflossen.
Kommentare sind auch wohl etwas spärlich.
Werde nächstes Jahr eine Heizungssteuerung damit bauen.
Gruß onifred
Ziegenpeter schrieb:> Demnach ist der nSel/CS während der Interrupt-Phase auf HIGH gesetzt
Aha, das mach ich ja nicht so. Werd ich aber mal noch ausprobieren.
Vielleicht liegt es wirklich an dem /CS.
>Wenn's nicht das ist - hast du auch den rigtigen nIRQ angeschlossen? Der>ist direkt neben dem SDO.
Ja, ich hab es mit dem richtigen nIRQ versucht. Beim RFM02 ist das alles
ein wenig anders. Deswegen dachte ich mir, ich probier das beim RFM12
auch mal so.
Denn beim RFM12 kann man beim Senden den SDO Pin überwachen oder für den
Interuppt mißbrauchen. Der wird nach dem Füllen des Sende FIFOs solange
auf "LOW" gehalten, bis der FIFO wieder leer ist. Dann geht der SDO
wieder auf "HIGH". Dadurch hab ich mir halt den zusätzlichen nIRQ
gespart. Und ich muss auch nicht den Status auslesen.
Aber trotzalledem werd ich das mit dem nIRQ mal noch ausprobieren.
Danke Ziegenpeter
(auch ein verrückter Name :-))
Hallo,
im Anhang mal meine RFM12.c, zugeschnitten auf einen PIC 18F für C18
Compiler.
Senden erfolgt direkt, Empfangen im Interrupt.
Vielleicht kann jemand zumindest Anregungen entnehmen.
Es basiert größtenteils auf dem Code von Benedikt.
Damit laufen bei mir 3 Geräte:
Temperaturfühler aussen, Temperaturfühler /-regler innen, RFM12-USB
Stick am PC mit Datenaustausch / Auswertung
seit einigen Wochen problemlos.
Holger
Holger W. schrieb:> Hallo,> im Anhang mal meine RFM12.c, zugeschnitten auf einen PIC 18F für C18> Compiler.> Senden erfolgt direkt, Empfangen im Interrupt.> Vielleicht kann jemand zumindest Anregungen entnehmen.
Dein Code gefällt mir sehr gut, da ordentlich dokumentiert!!!
Ich werde ihn auf AVR mit SPI-Schnittstelle umschreiben und wenn alles
funktioniert hier posten.
Juhuu, bei mir funkt es jetzt auch. Ich hatte zwar nicht so wirklich
Erfolg mit dem Software SPI (liegt aber daran, dass ich hier kein
Digitales Oszi habe). Aber mit Hardware konnte ich endlich ein Byte
übertragen. Jetzt kommt natürlich die Anpassung, dass alles vernünftig
läuft.
Das Problem war das nSel, welches ich immer nach den Befehlen wieder auf
High gesetzt habe.
Danke an alle unterstützenden! Wenn die Bibliothek fertig ist werde ich
sie natürlich posten.
Hallo
Jetzt versteh ich gar nix mehr. Verhält sich denn jeder RFM12 anders???
Sebastian F. schrieb:> Das Problem war das nSel, welches ich immer nach den Befehlen wieder auf> High gesetzt habe.
Ziegenpeter schrieb im Beitrag #2437188
> Demnach ist der nSel/CS während der Interrupt-Phase auf HIGH gesetzt.
Demnach funktioniert es bei Ziegenpeter mit nSEL=1 und bei Sebastian mit
nSEL=0.
In anderen Beiträgen hab ich auch schon mal gelesen:
> Alles funktionierte schon mal einwandfrei, aber seit neulich will nichts> mehr so funktionieren..
Schon etwas komisch, oder?
Gruß Steffen.
Hallo,
so wie ich das sehe, herrscht hier das allgemeine Problem, dass man (ich
auch nicht) eigentlich nicht so genau weiss, welche Schritte im
einzelnen durchzuführen sind, um ein Byte vom Sender an den Empfänger zu
senden.
Das Ding dann richtig zu programmieren, ob in C, Assembler oder... ist
denke ich nicht das Problem.
Und ein geposteter Code, mit vielen Funktionen, Macros etc. kann auch
schnell noch mehr Verwirrung stiften.
Daher bitte ich jemanden, einen Beitrag zu schreiben, wo die einzelnen
Schritte die durchzuführen sind erklärt werden.
z.B:
Senden eines Bytes:
1.) nSEL auf Low
2.) Sender mit 0x8238 einschalten
3.) Bit xy im Register xy löschen
4.) Synchronisieren (3 mal AA senden)
5.) Startbedingung senden (2D und D4)
.....usw.
Stimmt schon, das ist alles ein wenig verwirrend. Bei mir ist es auf
jeden Fall so, dass der nSEL vom Empfänger auf Low sein muss. Dann
bekomme ich das SDO->High wenn er was empfangen hat.
Wenn ich alles vernünftig am laufen habe versuche ich mal eine
Reihenfolge zu schreiben. Jetzt ist es ja mehr was zusammengewürfeltes,
um überhaupt was hinzubekommen. :-)
Sebastian F. schrieb:> Stimmt schon, das ist alles ein wenig verwirrend. Bei mir ist es auf> jeden Fall so, dass der nSEL vom Empfänger auf Low sein muss. Dann> bekomme ich das SDO->High wenn er was empfangen hat.> Wenn ich alles vernünftig am laufen habe versuche ich mal eine> Reihenfolge zu schreiben. Jetzt ist es ja mehr was zusammengewürfeltes,> um überhaupt was hinzubekommen. :-)
Wie wäre es mit einem Wiki Eintrag. Ich würde dann auch mithelfen.
Allerdings streube ich mich moch vor dem Neuanlegen.
So, jetzt habe ich was, wo man drauf aufbauen kann.
Allerdings gibt es ein kleines Problem: Wenn ich 5 Byte sende, kommt das
erste richtig an. Alle folgenden sind um 1 Bit verschoben!? Kennt dieses
Phänomen jemand?
irgendwie ist mir das zu unübersichtlich und schlecht dokumentiert.
Wieso machst du verschiedene inits für senden und empfangen ?
Mir fällt das auf
sbi SPI, nSEL ; Chip select auf 1
nop
nop
cbi SPI, nSEL ; Chip select auf 0
der erste schaltet CS aus, der zweite ein, einschalten sollte doch am
Anfang und ausschalten am Ende der Routine sein ?
Hab es jetzt aber nur eben mal überflogen.
Prinzipiell geht es ja, du empfängst ja was.
Holger
Sebastian F. schrieb:> So, jetzt habe ich was, wo man drauf aufbauen kann.> Allerdings gibt es ein kleines Problem: Wenn ich 5 Byte sende, kommt das> erste richtig an. Alle folgenden sind um 1 Bit verschoben!? Kennt dieses> Phänomen jemand?
Versuch mal ein Byte (z.B. 0xA1) einzeln zu senden und das ein paar mal
hintereinander!
Was passiert dann?
Ziegenpeter schrieb:> Wenn ich mit den eigentlichen Daten fertig bin, schiebe ich noch ein> "Padding-Byte" in den FIFO.> Wenn der RFM12 bereit ist, noch ein Byte aufzunehmen, schalte ich ab,> weil im FIFO Platz für zwei Byte ist. D.h. wenn ich ein Padding-Byte> drin hab und noch eins reinschieben dürfte (mach ich aber nicht), sind> alle Nutzdaten gesendet und ich kann abschalten.
Super. So hab ich es jetzt auch gemacht. Und siehe da: Es geht
problemlos. Ganz ohne warten oder irrgendwelche delays.
Danke Ziegenpeter
Gruß Steffen
Hallo Leute!
Bitte um Eure Hilfe!
Ich verwende das RFM12B (868 MHz) und möchte ein Byte von Tx auf Rx
übertragen.
Auf der Rx-Seite soll das empfangene Byte am PORTC mit LEDs angezeigt
werden.
Ich sende von Tx alle 1000ms das Byte 0x05 und es passiert nichts.
Ich poste hier mal meine Tx Routine, vielleicht sieht jemand einen
Fehler!
Danke!
1
// main.c
2
3
#define F_CPU 8000000UL
4
#include<util/delay.h>
5
6
voidsend(void);
7
8
intmain(void)
9
{
10
rf12_init();// RFM12 initialisieren
11
12
13
while(1)
14
{
15
send();// Alle 1 Sek. Daten senden
16
_delay_ms(1000);
17
}
18
}
19
20
21
voidsend(void)
22
{
23
rf12_txdata(0x05);// Sende Datenbyte 0x05
24
}
25
26
27
28
29
// rf12.c
30
31
#define F_CPU 8000000UL
32
#include<util/delay.h>
33
34
#define RF_PORT PORTA
35
#define RF_DDR DDRA
36
#define RF_PIN PINB
37
38
#define SDI 6
39
#define SCK 5
40
#define CS 4
41
#define SDO 1
42
43
unsignedshortrf12_trans(unsignedshortwert)
44
{
45
unsignedshortwerti=0;
46
unsignedchari;
47
48
cbi(RF_PORT,CS);
49
for(i=0;i<16;i++)
50
{if(wert&32768)
51
sbi(RF_PORT,SDI);
52
else
53
cbi(RF_PORT,SDI);
54
werti<<=1;
55
56
if(RF_PIN&(1<<SDO))
57
werti|=1;
58
sbi(RF_PORT,SCK);
59
wert<<=1;
60
_delay_us(0.3);
61
cbi(RF_PORT,SCK);
62
}
63
sbi(RF_PORT,CS);
64
returnwerti;
65
}
66
67
voidrf12_init(void)
68
{
69
RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
70
RF_PORT=(1<<CS);
71
72
_delay_ms(200);// wait until POR done
73
74
rf12_trans(0x80E7);// Enable FIFO, 868MHZ, 12pF
75
rf12_trans(0x82D9);// er, ebb, es, ex, dc
76
rf12_trans(0xA67C);// Set Frequency 868,3MHz
77
rf12_trans(0xC647);// 2400 Baud
78
rf12_trans(0x94A0);// VDI out, fast response, Bandbreite 134kHz
79
rf12_trans(0xC2AC);// CR auto mode, slow mode, digital filter
80
rf12_trans(0xCA81);// FIFO generates IT @ 8 bit received data bits, no sensitive reset
81
rf12_trans(0xC483);// AFC a1, oe, en
82
rf12_trans(0x9852);// Tx configuration, FSK modulation parameters, output power -5dB
83
rf12_trans(0xE000);// disable wakeup timer
84
rf12_trans(0xC800);// disable low duty cycle mode
85
rf12_trans(0xC000);// battery detector and MCU clock divider
86
}
87
88
89
90
voidrf12_ready(void)
91
{cbi(RF_PORT,CS);
92
while(!(RF_PIN&(1<<SDO)));// wait until FIFO ready
93
}
94
95
voidrf12_txdata(unsignedchardata)
96
{
97
rf12_trans(0x8238);// TX on
98
rf12_ready();
99
100
rf12_trans(0xB8AA);// Synchronisation 3x AA senden
101
rf12_ready();// damit sich der Empfänger
102
rf12_trans(0xB8AA);// auf den Bitstrom synchronisieren kann
103
rf12_ready();
104
rf12_trans(0xB8AA);
105
rf12_ready();
106
rf12_trans(0xB82D);// Datenschlüssel 2D und 4D senden, damit der Empfänger erkennt,
107
rf12_ready();// wo die Nutzdaten beginnen
108
rf12_trans(0xB8D4);
109
rf12_ready();
110
111
rf12_trans(0xB800|data);// Sende Daten
112
rf12_ready();
113
114
rf12_trans(0xB8AA);// Sende 2x Dummybyte AA, damit der Sender
H. G. schrieb:> Hallo Steffen!>> poste bitte mal deinen Code!
Hallo H. G.
Das wird dir leider nicht sehr viel weiter helfen. Denn ich code in ASM.
Auch dem Sebastian hilft es nicht viel weiter, da ich ein eigenes
Protokoll zur Datenübertragung verwende.
Das Protokoll hab ich mir selber ausgedacht und beinhaltet eine
SLAVE-Adresse wegen der Multimasterfunktionalität und einen CRC wegen
der Datensicherheit. Dazu kommt noch ein Start- und Endebyte.
Außer Start- und Endebyte wird alles im ASCII Code übertragen, da ich
auch Propleme mit Bytes größer 0x7F hatte.
Das 1.Byte hatte ich noch korrekt empfangen und dann ging es los wie bei
Sebastian.
Um dem ganzen aus dem Weg zu gehen sende ich jetzt nur noch
ASCII-Zeichen (0x20..0x7F) oder Steuerzeichen (0x01..0x1F).
Außerdem bin ich durch das EndeByte (EOT = EndOfTransmission = 0x04)
nicht an eine bestimmte Datenlänge gebunden wie in den meisten
Beispielen hier.
Wenn es auch für euch interessannt ist, dann werd ich den Code posten
sobald er multifunktional ist.
zum Protokoll:
01. Byte : 0x01 = SOT = Start of Transmission
02. Byte : SLAVE Adresse BCD1 (ASCII)
03. Byte : SLAVE Adresse BCD0 (ASCII)
04. Byte : 0x0A = LF = LineFeed
05. Byte : Data als Steuerzeichen oder ASCII \
06. Byte : Data als Steuerzeichen oder ASCII > DataPaket (variabele
Länge)
07. Byte : 0x0A = LF = LineFeed / -> Paketende
.. .. ..
.. .. ..
xx. Byte : Data als Steuerzeichen oder ASCII\
xx. Byte : Data als Steuerzeichen oder ASCII \
xx. Byte : Data als Steuerzeichen oder ASCII > DataPaket (variabele
Länge)
xx. Byte : Data als Steuerzeichen oder ASCII /
xx. Byte : 0x0A = LF = LineFeed / -> Paketende
xx+1. Byte : CRC BCD1 (ASCII) CRC= eor über alle Datenbytes + SLAVE
Adresse
xx+2. Byte : CRC BCD0 (ASCII) + LF wie sie gesendet werden (ASCII)
xx+3. Byte : 0x04 = EOT = End of Transmission
Dies funktioniert bereits ohne Probleme. Habe gestern auch meinen RFID
Reader im Funksystem erfolgreich eingebunden.
Gruß Steffen
Hi Steffen,
ich bin zwar immer noch dabei Einstellungen zu testen, woran das liegen
könnte aber die Idee einfach auf ein Bit zu verzichten und den ASCII
Code zu nehmen ist schon genial.
@H.G. Ledi,
Das kann nicht funktionieren, da die RFM nur im halpduplex arbeiten !
Entweder senden oder empfangen.
Du benötigst also zeitgleich einen Sender und einen Empfänger, also 2
Module !
> @Duplex:>> Das kann nicht funktionieren, da die RFM nur im halpduplex arbeiten !>> Entweder senden oder empfangen.>> Du benötigst also zeitgleich einen Sender und einen Empfänger, also 2> Module !
Ja, das ist schon klar.
Ich habe auch 2 Module. Senden und Empfangen funktioniert auch bereits.
Hallo
Na, schon lange kein Eintrag mehr hier zu finden. Scheinbar hat
Sebastian sein RFM12 bendigen können oder er ist schon verzweifelt.
Ich jedenfalls habe nun endlich auch ein RFID-Funk-Modul zum laufen
gebracht. Bilder und Code gibt es demnächst.
Wie ist der Stand der Dinge bei dir Sebastian?
Gruß Steffen
Hi, ich bin teilweise am Verzweifeln...
Ich wollte zuerst das mit das mit den 7Bit-ASCII probieren. Dabei hatte
ich dann bei 16Byte irgendwo wieder ein Byte, welches komplett
übertragen wurde, warum auch immer...
Da ich keine hohen Geschwindikeiten brauche baue ich gerade eine
Ein-Byte Übertragung zusammen, wo dann der Empfänger das übertragene
zurücksenden soll und der Sender dann ein OK oder die Daten noch einmal
senden soll. Lustigerweise sollte es funktionieren, allerdings springt
der Sender nach dem lesen nicht zurück, sondern irgendwohin ins Nirvana
- und der µC wird resettet. Das ist auch in der Simulation so. Bin aber
zwischen den ganzen Weihnachtsfeiern dran :-)
Das mit den 7 Bit ist Blödsinn, auch wenn es erstmal so scheint dass es
funktioniert. Das Problem muss an anderer Stelle stecken.
Mit den Beispielen von Benedikt hatte ich recht schnell Erfolge und
meine Routinen (siehe oben) beruhen größtenteils immer noch darauf.
Ich übertrage ca. 20 Bytes mit 4800 Baud und alle 8 Bit breit, z.b.
negative Temperaturen letzte Nacht.
Holger
Hallo
Steffen H. schrieb:
>Ich jedenfalls habe nun endlich auch ein RFID-Funk-Modul zum laufen>gebracht. Bilder und Code gibt es demnächst.
Hier nun auch die Sourcen und ein paar Bilder vom RFID-Funk-Modul.
Beitrag "RFID-RFM12-Funkmodul"
Holger W. schrieb:
>Das mit den 7 Bit ist Blödsinn, auch wenn es erstmal so scheint dass es>funktioniert. Das Problem muss an anderer Stelle stecken.
Ich hab es mit vollen 8bit ehrlich gesagt garnicht nochmal probiert.
Aber vieles über ASCII zu senden sehe ich trotz allledem als Vorteil. Es
werden zwar dadurch größere Pakete übertragen, aber dafür kann man
Steuerzeichen für Start- und End of Transmission oder anderweilig
versenden. Außerdem hat man die "0" als Strigende zur Verfühgung.
Sebastian F. schrieb:
>Ich wollte zuerst das mit das mit den 7Bit-ASCII probieren. Dabei hatte>ich dann bei 16Byte irgendwo wieder ein Byte, welches komplett>übertragen wurde, warum auch immer...
Das kommt mir jetzt aber wirklich komisch vor. Willst du eine feste
Byteanzahl übertragen?
Gruß Steffen
Steuer- oder Endezeichen oder sowas brauche ich nicht.
Im ersten Byte kommt die Anzahl, danach Steuerbytes und die Nutzdaten,
danach 2 Prüfbytes. Die Anzahl wird auf Maximum geprüft und danach die
Anzahl der Daten gelesen, gegen die Prüfsumme verifiziert.
ASCII senden hat den Vorteil, dass man sich nicht um genügend
Flankenwechsel sorgen muß, das kommt aber bei mir nicht vor.
Holger