Forum: Projekte & Code RFM02 mit Bascom sendet an RFM12


von Klaus A. (klaus-albers)


Angehängte Dateien:

Lesenswert?

Nach einigen grauen Haaren habe ich es endlich geschafft, ein RFM02 
unter Bascom zum Laufen zu bringen. Da ich hier schon super Anregungen 
(in diesem Fall vielen Dank an Benedikt!) bekommen habe, stelle ich den 
Code mal rein.

Hardware:
- Mega16
- RFM02 über SDI,SCK,CS und FSK mit uC verbunden
- CPU Takt: 7.3728 MHz

Benedikt verwendet in seinem Code die Option, die zu sendenden Daten 
über die SDI Leitung einzutakten. Wenn das Modul auf Tx-Sync eingestellt 
ist, gibt es dazu kurze Nadelimpulse im Baudratentakt über die NIRQ 
Leitung raus. Die Daten können dann über die SDI Leitung eingetaktet 
werden und werden mit der fallenden Flanke des NIRQ Impulse übernommen. 
Benedikt's Code prüft per while-Schleife, wann NIRQ hochgeht. Dann 
werden noch innerhalb des kurzen Impulses die Daten an SDI angelegt und 
beim Runterfallen von NIRQ eingelesen. Portiert man den Code auf Bascom, 
funktioniert das Ganze NICHT (FRUST!!!). Grund (LANGE SUCHE): Die 
while-Schleife braucht zu lange beim Pollen (zumindest bei meinem 
Quarztakt). Kann durchaus an Bascom liegen. Es gibt einen 
undokumentierten Befehl (0xD040 oder so), der den Duty-cycle des NIRQ 
Taktes auf 50 % umschaltet. Dann wird laut Forum hier auf der steigenden 
und fallenden Flanke eingelesen. Hab ich nicht zum Laufen bekommen.

Lösung:
Wenn man das Funkmodul für die Datenübertragung über die FSK Leitung 
konfiguriert, ändert sich die ausgegebene Funkfrequenz direkt mit dem 
Pin-Zustand:
FSK=1: f = f0 + Modulationsfrequenz
FSK=0: f = f0 - Modulationsfrequenz
Oder andersrum -> Datenblatt, egal. Ich kann also anstatt den Taktgeber 
des RFM02 zu verwenden auch die Baudrate auch im uC erzeugen und einfach 
die Daten raustakten. Das RFM12 wartet zwecks Abtastsynchronisation nur 
auf die 0xAA's und dann auf das Schlüsselwort (0x2d 0xd4). Hab das mal 
in Bascom eingetippt (Baudratenerzeugung per Timer0) und bislang läuft 
das Ding perfekt.

Cheers

Klaus

p.s.: Hoffe, die Farbe meiner Haare kehrt in den nächsten Tagen zurück.

: Verschoben durch Moderator
von Holger S. (holli_1)


Angehängte Dateien:

Lesenswert?

Na so was, mir ging es genau so. Mit Hilfe eines Logikanalysators habe 
ich meine jetzt auch am Laufen. Bis auf das FSK-Senden verwende ich die 
Bascom SPI-Befehle. So habe ich jetzt die RFM01 und RFM02 am Funken, 
jetzt bin ich bei den RFM12. Da schreibe ich auch noch meine eigenen 
Routinen dazu.
Das RFM02 habe ich auf einem Pollin-Funk-AVR Board, das RFM01 auf einem 
Pollin-Add-On Board verbunden mit Atmel-Evaluation Board jeweils mit 
ATMega8.

Gruß,
Holger

von Holger S. (holli_1)


Angehängte Dateien:

Lesenswert?

Diese Version benutzt den SDI Pin zum Senden. Im Gegensatz zur 
FSK-Version muss hier die Datenübertragung durch Senden von "C6" mit 
anschließendem IRQ-Polling eingeleitet werden. Das ist nicht SPI 
kompatibel, daher verwende ich hier Soft-SPI.

von Klaus A. (klaus-albers)


Lesenswert?

Super, danke für die Programme, werde ich durchsehen und ausprobieren. 
Allerdings hat die SDI-basierte Übertragung mit Polling des NIRQ bei mir 
nicht funktioniert. Du hast anscheinend einen 12 MHz Quarz genommen, 
vielleicht macht das die while-Schleife den entscheidenden Tick 
schneller. Was ansonsten prima wäre: Senden von 0xC6 und dann die Daten 
über die SDI Leitung mit uC-gesteuertem Takt rausgeben, ohne das NIRQ 
Signal zu verwenden. Evtl. funktioniert das, wenn man das TX-Sync-Bit 
ausschaltet. So könnte man sich die FSK Leitung sparen.

Cheers

Klaus

von Holger S. (holli_1)


Lesenswert?

Ich glaube nicht, dass das Polling das Problem bei dir war. Ich habe das 
NIRQ Polling in 2 Versionen getestet. Einmal nur auf L-H Flanke warten 
und dann auf L-H/H-L Flanken. In der SDI Version übrigens wartet NIRQ 
nur auf die L-H Flanke. Die Verzögerungen zur FSK/SDI Flanke sind 0,8µs 
bzw. 2,6µs.
Ich werde das auch mal mit anderen Quarzfrequenzen testen.
In der SDI Version wird FSK nicht mehr benutzt. Du meinst bestimmt, ohne 
die IRQ Leitung zu senden. Dann sollte allerdings das Timing zum Start 
der Übertragung stimmen. Nach dem SPI Befehl (hc039) braucht der RFM02 
noch 1ms bis zum Start der Übertragung.

Gruß,
Holger

von Klaus A. (klaus-albers)


Lesenswert?

Zum Polling-Problem: Wenn ich das richtig verstehe, ist der NIRQ-Impuls 
im kurzen duty-cycle ca. 1.6 us. Wenn ich wie Benedikt mit einer 
while-Schleife auf die L-H Flanke gewartet habe, hat der uC die Daten 
immer MEHRERE us nach der L-H Flanke auf SDI gelegt. Da war dann die 
NIRQ Leitung schon wieder auf L runter und hat dementsprechend das 
vorherige SDI-Bit eingelesen.

Was ich noch nicht verstehe: Prinzipiell sollte das egal sein, da es 
keine BYTE-Synchronisation gibt. Ich denke, das RFM02 schickt die Daten 
einfach entsprechend der anliegenden Bits raus und das RFM12 sucht nach 
der richtigen Bitreihenfolge für das Schlüsselwort. Insofern sollte es 
völlig unproblematisch sein, wenn man das zu sendende Bit NACH der H-L 
Flanke von NIRQ an SDI legt, dann wird's halt mit der nächsten NIRQ H-L 
Flanke rausgeschickt. Da ich jetzt immerhin eine funktionierende 
Kommunikation hinbekommen habe, kann ich da mal ein paar Tests machen 
und sicher sein, daß es nicht an anderen Parametern scheitert :-)

von Holger S. (holli_1)


Angehängte Dateien:

Lesenswert?

Der Ablauf stimmt so. Ab dem 2. IRQ läuft die eigentliche 
Datenübertragung.
Im Anhang ist ein Screenshot des Logikanalysators. Ohne den hätte ich 
schon aufgegeben. So kann ich probieren und sehe sofort, ob das noch 
funktioniert oder nicht.

von Klaus A. (klaus-albers)


Lesenswert?

Supi, dann ist soweit eigentlich alles verstanden. Was die Anzahl der 
notwendigen Leitungen angeht, hat man jetzt die Wahl zwischen

SCK, SDI, NIRQ

oder

SCK, SDI, FSK

Macht insofern also noch keinen Unterschied. Für die eigene 
Taktratenerzeugung brauche ich einen Timer, das wäre ein Grund für 
SDI-basierte Übertragung. Warum die bei mir nicht funktioniert hat, ist 
noch offen. Die Zeitverzögerung durch die while-Schleife kann es ja 
nicht gewesen sein. Wenn ich Dein Bild vom Logiganalysator richtig 
interpretiere, vergehen rund 2.5 us (Marker B - Marker A) zwischen L-H 
Flanke von NIRQ und Anlegen des Bits an SDI. Das passt von der 
Grössenordnung zu meiner Verzögerung.

Ideal wäre es, Daten per SDI ohne NIRQ zu übertragen (nur 2 Leitungen). 
Zumindest wenn es nur wenige Bytes sind, sollte das mit einem 
uC-internen Taktgenerator gehen, man darf dann nur die NIRQ Impulse 
nicht "unglücklich treffen" (also SDI Pin möglichst zwischen 2 NIRQ 
Impulsen verändern). Vielleicht gibt es eine charakteristische Zeit, ab 
der die NIRQ Impulse nach Senden von 0xC6 auftreten.

Komme leider bis Fr nicht dazu, das zu testen :-(

Viele Grüsse

Klaus

von Klaus A. (klaus-albers)


Lesenswert?

ich meinte: "logikanalysator" :-)

von Klaus A. (klaus-albers)


Lesenswert?

Heureka. Hab gerade doch mal aus Spass einen 11.0592 MHz Quarz 
eingelötet -> läuft. Vermutung: Die erste while-Schleife, die solange 
NIRQ=0 wartet, geht so langsam, daß die while-Schleife für die NIRQ H-L 
Flanke zu spät geprüft wird. Kann man mal drüber nachdenken, evtl. langt 
eine Prüfung der ersten Flanke oder etwas in der Art, heute nicht mehr 
:)

Cheers

Klaus

von Klaus A. (klaus-albers)


Lesenswert?

Oops, hatte ich überlesen. Du schreibst, Du hast das Warten nur auf die 
L-H Flanke bereits getestet. Falls das funktioniert, wird das evtl. auch 
mit dem langsamen Quarz gehen (vorausgesetzt, die while-Schleife ist 
nicht so langsam, daß sie den ganzen Impuls verpasst). Falls es nicht 
geht, könnte ich natürlich immer noch mit einem Interrupt arbeiten, aber 
am liebsten würde ich die NIRQ Leitung komplett weglassen. Ansonsten 
würde mich trotzdem auch die Sache mit dem undokumentierten 50 % 
duty-cycle Kommando interessieren, vielleicht bekommt man das auch noch 
zum Laufen.

So far

Klaus

von Klaus A. (klaus-albers)


Lesenswert?

Hhmm. Bei 7.3728 MHz Quarztakt beträgt ein Taktzyklus 136 ns. Schätze 
mal, eine einfache while-Schleife in Assembler benötigt rund 10 
Taktzyklen. Das sollte also bei einem 1.6 us Impuls hinkommen. Falls 
Bascom für die while-Schleife Code mit 30 Zyklen generiert, wird's 
vielleicht knapp. Evtl. lohnt es, die while-Schleife selbst in Assembler 
zu programmieren?

von Avr N. (avrnix) Benutzerseite


Lesenswert?

Das könnte man im Simulator doch ablesen. Dann hättest du die Zeiten 
doch.

von Klaus A. (klaus-albers)


Lesenswert?

Hab ich noch nicht benutzt, schaue ich mir mal an (Bascom oder AVR 
Studio?). Die vermutlich kürzeste Schleife der Welt müsste so gehen

$asm
While_start:
SBIS pina,4
RJMP while_start
$end Asm

Bzw. identisch mit SBIC für "while NIRQ=0". Wenn das alles so stimmt.

Cheers

Klaus

von Avr N. (avrnix) Benutzerseite


Lesenswert?

BASCOM :)

$sim  am Anfang eingeben und Compilieren. Dann zum Simulator.

Wenn du den das mal Disassmblieren möchtest

http://comwebnet.weimars.net/forum/showthread.php?tid=366

oder HexHacker bei Google eingeben.

von Klaus A. (klaus-albers)


Lesenswert?

Alright, SBIS und RJMP brauchen laut Simulator zusammen 4 Taktzyklen 
(Datenblatt lesen hilft aber auch :-)). Dann würde die Schleife rund 0.6 
us brauchen, das sollte gehen. Debuggen mache ich meist mit RS232 oder 
LED's auf dem Zielboard, aber der Simulator ist auch ganz nett.

von Holger S. (holli_1)


Angehängte Dateien:

Lesenswert?

Ich probiere gerade mit anderen Taktfrequenzen herum. Wie es aussieht, 
liegt das Problem bei der Erkennung der IRQ-Flanke selbst. Bei 8 MHz 
wird ab und zu ein IRQ-Puls beim Pollen gar nicht erkannt. Bei 12 MHz 
funktioniert alles.
Im Bild sieht man den Vergleich, unten mit 12 MHz und oben mit 8 MHz.

von Holger S. (holli_1)


Angehängte Dateien:

Lesenswert?

Ich habe jetzt noch eine 25µs Warteschleife nach dem IRQ Polling 
eingefügt. Funktioniert immer noch. Das FSK-Bit wird mit Sicherheit erst 
bei der nächsten L-H Flanke des IRQ eingelesen.

von Holger S. (holli_1)


Angehängte Dateien:

Lesenswert?

Jetzt habe ich mal von Polling auf INT umgestellt. Jetzt werden die
Flanken zuverlässig erkannt. Bei 8 MHz und 19,2 kbit Datenrate braucht
der Prozessor ca. 19 µs für die Routine. Zwischen den IRQ's liegen 52
µs. Bei 4 MHz funktioniert das zeitlich nicht mehr, da werden wieder ab
und zu Bits ausgelassen. Da habe ich auf 9.6 kbit umgestellt und es ging
wieder. Wenn du also die Bitrate entsprechend der Prozessorfrequenz
anpasst, dann klappt das auch.

von Klaus A. (klaus-albers)


Lesenswert?

Frage: Hast Du die Flankenerkennung beim Polling mit dem Assemblercode 
oder mit der Bascom while-Schleife gemacht? Laut Bascomsimulator braucht 
die Bascom while-Schleife 15 Takte, die Assemblerschleife aber nur 4 
(aus Interesse: wieviele Takte braucht AVR-GCC?). Das sollte nochmal 
ordentlich was bringen. Bitrate liegt bei mir irgendwo in der Gegend von 
4.8 kbit/s, ist nach Deinen Messungen also auch bei 8 MHz kein Problem. 
Generell würde ich in meiner Anwendung aber gerne mit dem CPU Takt 
weiter runter (Richtung 1 MHz). Daher werde ich nochmal das 50 % 
Tastverhältnis beim NIRQ durch Senden von 0xD040 ausprobieren. 
Umschalten tut das Modul, gibt auf dem Oszi ein schönes Rechtecksignal. 
Noch besser wäre natürlich, wenn man auf das Polling komplett verzichten 
könnte und den Takt im uC erzeugen könnte. Wenn man dann die Daten noch 
per SDI raustaktet bräuchte man nur noch CS, SCK und SDI Leitung 
anschliessen.

von Holger S. (holli_1)


Lesenswert?

Das Problem beim Polling mit niedrigen Frequenzen ist wohl, dass die 
IRQ's einfach ab und zu nicht mehr erkannt werden. Die Assemblerroutine 
würde das Problem verbessern, aber wahrscheinlich nicht komplett lösen. 
Nur das Verwenden des INT ist wohl die beste Lösung.
Das mit dem 0xD040 habe ich schon probiert. Es wird nicht einfach das 
Tastverhältnis des IRQ geändert, sondern das Polling selbst. Nach einer 
steigenden Flanke musst du dann auf die fallende Flanke triggern. Sonst 
passt das zeitlich nicht mehr. Allerdings konnte ich damit nichts 
empfangen. Wer weiß was damit noch verstellt wurde. Könnte sein, das 
auch die Datenrate halbiert wurde oder irgend etwas anderes.
Ich habe bis jetzt hier alles in Bascom programmiert. Auf dem IRQ würde 
ich aber nicht verzichten, damit funktioniert das zuverlässig.

von Holger S. (holli_1)


Angehängte Dateien:

Lesenswert?

Jetzt habe ich fast alles ausprobiert und insgesamt 6 verschiedene 
Versionen zum Funktionieren gebracht, dazu RFM12 mit 16 bit FIFO als 
Zugabe. Das sind:
- Sendedaten an FSK oder SDI,
- NIRQ Polling oder INT0 zur Sendesyncronisierung
- Normale Datenrate oder "Halfrate-Mode" (0xD040)

Folgende Erkenntnisse gibt es dazu:
- NIRQ Polling funktioniert bei 8MHz und darunter nicht mehr 
zuverlässig, da der NIRQ Puls zu kurz ist
- Die SDI-Routine ist etwas schneller als FSK
- Bei normaler Datenrate reicht es auf die L-H Flanke des NIRQ zu warten
- Im "Halfrate-Mode" ist das Tastverhältnis des NIRQ 50%, es muss 
allerdings die doppelte Datenrate des Empfängers eingestellt werden.

Bei normaler Datenrate ergaben sich folgende Limits bezüglich 
AVR-Taktrate:
- 1 MHz - 2,6 kbit
- 2 MHz - 4,8 kbit
- 4 MHz - 9,6 kbit
- 8 MHz - 19,2 kbit
- 12 MHz - 38,4 kbit
- 16 MHz - 57,4 kbit

Mit "Halfrate" kann die Datenrate sogar verdoppelt werden:
- 4 MHz - 19,2 kbit
- 16 MHz - 86,2 kbit
Die im RFM02 eingestellte Datenrate ist dann die doppelte der o.g.

Wichtige Anmerkung:
Wer beim Empfänger die Routinen von Benedikt K./Fossie Bär verwendet, 
muss die Werte für die Baudrate exakt eintragen. Statt z.B. 19200 muss 
es 19157 sein, sonst wird ein anderer Wert berechnet und eingestellt. Im 
Beispiel hier sollte es 0xC611 (19157) sein, bei 19200 ist es aber 
0xC610 (20,284 kbit).

von Klaus A. (klaus-albers)


Angehängte Dateien:

Lesenswert?

Habe gerade meine Traumkonfiguration getestet:

RFM02 per SCK, SDI und CS an den Mega. TX-Sync-Bit deaktiviert. Dann 
Datenübertragung mit 0xC6 angestossen und die Daten mit einer im 
uC-generierten Baudrate per SDI rausgeschickt. LÄUFT! I'am very happy. 
Dadurch, daß man das TX-Sync-Bit (Register C2) deaktiviert, sendet das 
RFM02 entsprechend auch keine Impulse auf NIRQ. Ich habe also auch 
keinerlei Synchronisationsprobleme. Da keine Pulse gepollt werden 
müssen, sollte man damit auch mit uC's mit niedrigen Quarzfrequenzen 
arbeiten können.

Vielen Dank an Holger für die ganzen Tests!!!

von Max (Gast)


Lesenswert?

mit

 bitwait

statt

 while

gehts auch unter 8 MHz !

gibt auch weniger Code  :-)

von Klaus A. (klaus-albers)


Lesenswert?

Hallo Max,

besten Dank für den Hinweis, gut möglich, daß ich das Polling für eine 
low power Variante (kleine Frequenz) ohne externen Quarz für die 
Taktrate mal brauchen werde.


Viele Grüsse

Klaus

von Klaus A. (klaus-albers)


Lesenswert?

By the way:

Die Routine mit der eigenen Takterzeugung muss bei hohen Datenraten 
kalibriert werden, da die Schleife in der Senderroutine Zeit benötigt. 
Ich habe als pragramatisch dummen Ansatz den Vorladewert für den Timer 
in der Timer1_routine in einem Bereich um den berechneten Wert variiert. 
Man sieht dann mit Hilfe eines Empfängers, bei welchen Werten die ersten 
Übertragungsfehler beginnen und kann den Wert einfach auf die Mitte des 
Bereichs setzen. Bei niedrigen Übertragungsraten hatte ich damit keine 
Probleme.


Beste Grüsse

Klaus

von MJD (Gast)


Lesenswert?

Sorry guys i'm writing english below your german discussion...
would you please bring me shematic of your successful Rfm01<==>RFm02 
bascom code mr "Holger Sch" ?
my email is dayaghi[at]gmail.com
thanks a lot...

von jack w. (jeck556)


Lesenswert?

jetzt muss ich mal ganz dumm fragen was wird hir gesendet??? welcher 
wert????

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
Noch kein Account? Hier anmelden.