mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik RFM69CW, wer kann helfen?


Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche seit geraumer Zeit eine Kommunikation zwischen zwei 
RFM69CW, bzw. auch RFM69 und RFM12 hinzubekommen. Leider keinerlei 
Empfang. Zwei RFM12 sind kein Problem!
Ich meine zwar, daß alle Register die ich auslese richtig sind, aber 
irgend etwas ist ja offensichtlich falsch. Wer hat Erfahrung und kann 
raten?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, schon mal erfolgreich gemacht. Aber lang her.

Wichtig ist wohl, beim RFM69 das Whitening und CRC auszuschalten.

Des weiteren muss der RFM12 eine korrekte Preamble schicken, sonst 
springt der RX beim RFM69 nicht an.

Zeig mal Code und Initialisierung...

Autor: Bruno M. (brumay)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antwort!

Der Code ist in asm, deswegen habe ich ihn nicht angehängt, weil ich 
damit offensichtlich abschreckend wirke.

Ich habe mal den Registerstatus angehängt, wie ich ihn nach der 
Initialisierung auslesen kann.

Autor: Peter S. (peter_su)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm, da sind noch zu viel Unbekannte.
- feste Paketlänge?
- Interrupt oder Polling?
- RSSI-Schwelle?

...und ja: auch mich schreckt das Lesen von langem ASM-Code ab.

Welche Status-Register sind im "Status.txt" (Ich vermute die vom RFM69)

Beim RFM69 würde ich setzen:
Register 0x2E = 0x88 // REG_SYNCCONFIG = RF_SYNC_ON | RF_SYNC_SIZE_2
Register 0x2F = 0x2D // REG_SYNCVALUE1 = 0x2D
Register 0x30 = 0xD4 // REG_SYNCVALUE2 = networkID
Register 0x37 = 0x80 // REG_PACKETCONFIG1 = RF_PACKET1_FORMAT_VARIABLE
Register 0x3D = 0x12 // REG_PACKETCONFIG2 = 
RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON

Ansonsten hatte ich mir geholfen, in dem ich beim RFM69 auf 
Continuous-RX gestellt hatte und
den Empfangs-FIFO dauerhaft ausgeprinted habe.

Nützt Dir C++ - Code etwas?

Autor: Bruno M. (brumay)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Anliegend die Daten noch als hex, falls es so übersichtlicher sein 
sollte.

Autor: Bruno M. (brumay)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Peter S. schrieb:
> Welche Status-Register sind im "Status.txt" (Ich vermute die vom RFM69)

richtig vermutet.

> Nützt Dir C++ - Code etwas?

Ich kann einigermaßen nachvollziehen was passiert, aber selbst schreiben 
kann ich nicht.

Ich habe z.B. den Code von Felix Pflaum, den ich zum probieren nutzen 
könnte, aber wenn ich das richtig sehe ist das zwar eine main für den 
Empfang, aber nichts zum senden.

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter S. schrieb:
> Beim RFM69 würde ich setzen:
> Register 0x2E = 0x88 // REG_SYNCCONFIG = RF_SYNC_ON | RF_SYNC_SIZE_2

Im Vergleich zu meinen Werten ist mir aufgefallen, daß bei mir in 0x2E = 
0x00 steht. Das kann ja auch nicht funktionieren. Das werde ich gleich 
mal ändern!

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch noch eine Nachfrage:

0x88 = 0b10001000

bit 7   = 1 = Sync on
bit 6   = 0 = FIFO filling condition: if SyncAddress interrupt occurs
bit 5-3 = 001 = Sice of Sync word: 1 byte ??
bit 2-0 = 000

Autor: Peter S. (peter_su)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RFM69:
#define RF_SYNC_SIZE_1            0x00
#define RF_SYNC_SIZE_2            0x08
#define RF_SYNC_SIZE_3            0x10
#define RF_SYNC_SIZE_4            0x18
#define RF_SYNC_SIZE_5            0x20
#define RF_SYNC_SIZE_6            0x28
#define RF_SYNC_SIZE_7            0x30
#define RF_SYNC_SIZE_8            0x38

Das Sync-Word beim RFM12 ist per default (2 Bytes):
0x2D (fest)
   und
0xD4 (einstellbar)

So muss beim RFM69 "RF_SYNC_SIZE_2" = 0x08 gesetzt sein.

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter S. schrieb:
> So muss beim RFM69 "RF_SYNC_SIZE_2" = 0x08 gesetzt sein.

Danke für den Hinweis, hatte ich natürlich auch schon mal gelesen, aber 
wieder vergessen.

Ich habe 0x2E jetzt auf 0x88 geändert, aber leider trotzdem kein Erfolg. 
So einfach war es dann wohl doch nicht.

Autor: Peter S. (peter_su)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Init-Werte...
- ohne Frequenz
- ohne Baudrate
- mit Interruptbetrieb
- mit Whitening (ggf. rausnehmen: RF_PACKET1_DCFREE_WHITENING)
- mit CRC (ggf. rausnehmen: RF_PACKET1_CRC_ON)
/* 0x01 */ { REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY },
/* 0x02 */ { REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 }, // no shaping
/* 0x05 */ { REG_FDEVMSB, RF_FDEVMSB_90000}, // default: 5KHz, (FDEV + BitRate / 2 <= 500KHz)
/* 0x06 */ { REG_FDEVLSB, RF_FDEVLSB_90000},
/* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2 }, // (BitRate < 2 * RxBw)
/* 0x25 */ { REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01 }, // DIO0 is the only IRQ we're using
/* 0x26 */ { REG_DIOMAPPING2, RF_DIOMAPPING2_CLKOUT_OFF }, // DIO5 ClkOut disable for power saving
/* 0x28 */ { REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN }, // writing to this bit ensures that the FIFO & status flags are reset
/* 0x29 */ { REG_RSSITHRESH, 170 }, // must be set to dBm = (-Sensitivity / 2), default is 0xE4 = 228 so -114dBm <-------- ACHTUNG, zuviel dBm verursachen ziemlich fehlerhaften Empfang
/* 0x2E */ { REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_0 },
/* 0x2F */ { REG_SYNCVALUE1, 0x2D },      // attempt to make this compatible with sync1 byte of RFM12B lib
/* 0x30 */ { REG_SYNCVALUE2, networkID }, // NETWORK ID
/* 0x37 */ { REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_WHITENING | RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF },
/* 0x38 */ { REG_PAYLOADLENGTH, 66 }, // in variable length mode: the max frame size, not used in TX
/* 0x3C */ { REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE }, // TX on FIFO not empty
/* 0x3D */ { REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF }, // RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent)
/* 0x6F */ { REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0 }, // run DAGC continuously in RX mode for Fading Margin Improvement, recommended default for AfcLowBetaOn=0


Konstanten von hier:
https://github.com/LowPowerLab/RFM69/blob/master/R...

: Bearbeitet durch User
Autor: Peter S. (peter_su)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bruno M. schrieb:
> So einfach war es dann wohl doch nicht.

falls es tröstet: ich habe mehrere Wochen damit zugebracht, RFM12 und 
RFM69 kompatibel zu bekommen.

Dafür hab ich aber die CRC-Generierung und das Whitening in Software für 
den RFM12 geschrieben. Der RFM69 kann ja beides in Hardware.

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter S. schrieb:
> alls es tröstet: ich habe mehrere Wochen damit zugebracht, RFM12 und
> RFM69 kompatibel zu bekommen.

Mir würde es ja schon reichen, wenn zwei RFM69 miteinander sprechen 
würden. Das kann doch eigentlich nicht so schwierig sein, wenn man die 
gleiche Initialisierung benutzt.

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter S. schrieb:
> Register 0x3D = 0x12 // REG_PACKETCONFIG2 =
> RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON

wodurch ergeben sich die 2 bits delay?

Autor: Andreas Z. (andreas_z15)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du schon mal auf der Seite von JeeLabs nachgesehen. Da gibt es eine 
Lib für Arduino die mit RFM12 und RFM69 funktioniert. Ich habe es bei 
mir implementiert und es funktioniert. Allerding gibt es Probleme mit 
dem ACK zwischen verschiedenen Modulen.

Andreas

Autor: Peter S. (peter_su)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Laut Datenblatt:
After PayloadReady occurred, defines the delay between FIFO empty and the start of a new RSSI phase for next packet. Must match the transmitter’s PA ramp-down time.

Ich denke, das ist die minimale Zeit zwischen Ende eines Paketes und dem 
Start eines Folgepaketes. Ist aber sicher nicht kriegsentscheidend und 
muss sicher nicht genau zum Sender passen).

Empfängst Du per Polling oder Interrupt?

Und bedenke, der RFM69 hat einen Sequencer drin, der den Ablauf zwischen 
RX/TX und Standby handhabt.

Nach dem Umschalten muss man warten:
void RFM69::setMode(uint8_t newMode)
{
  switch (newMode) {
    case RF69_MODE_TX:
      writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER);
      break;
    case RF69_MODE_RX:
      writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER);
      break;
    case RF69_MODE_SYNTH:
      writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SYNTHESIZER);
      break;
    case RF69_MODE_STANDBY:
      writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY);
      break;
    case RF69_MODE_SLEEP:
      writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SLEEP);
      break;
    default:
      return;
  }

  int max_tries = 20000;
  while (((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00) && (max_tries-- > 0)); // wait for ModeReady
}

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter S. schrieb:
> Empfängst Du per Polling oder Interrupt?

Z.Zt. überwache ich das PayloadReady Bit (Bit 2 von RegIrqFlag2 0x28).

Ich habe aber auch schon versucht den FIFO ständig auszulesen.

Den Sender habe ich so eingestellt, daß er laufend (mit kurzen Pausen) 
sendet.

Peter S. schrieb:
> Nach dem Umschalten muss man warten:

Ich schalte z.Zt. nicht um!

Autor: Peter S. (peter_su)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bruno M. schrieb:
> Z.Zt. überwache ich das PayloadReady Bit (Bit 2 von RegIrqFlag2 0x28).
Genauso - korrekt.

...

Schreibe gelegentlich:

writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | 
RF_PACKET2_RXRESTART);

Das startet den RX-Fifo neu.

Mein RX-Init sieht so aus:
void RFM69::rx_enable()
{
  setMode(RF69_MODE_STANDBY);
  if (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY)
    writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks
  writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01); // set DIO0 to "PAYLOADREADY" in receive mode
  setMode(RF69_MODE_RX);
}

...

Ansonsten schon mal den TX-Teil getestet? (sieht man an der 
Stromaufnahme oder mit einem SDR)

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hurra, ich kann einen kleinen Erfolg melden. Ich empfange zumindest das 
erste Packet. Anschließend zwar Müll, aber ich habe zumindest den 
Beweis, daß sie sich verstehen!

Autor: Sascha Weber (sascha-w)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Bruno,

anbei mal ASM-Code der bei mir auf mehreren RFM69CW läuft.
(nur RFM69 <-> RFM69)

Sascha

Autor: Bruno M. (brumay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sascha,

herzlichen Dank!! Danach habe ich schon lange gesucht.

Aber heute habe ich erstmal genug!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.