Forum: Mikrocontroller und Digitale Elektronik RFM24W Datenblatt unklar


von Luca E. (derlucae98)


Lesenswert?

Hallo,

ich möchte mit einem RFM24W Funkmodul einen Enocean PTM210 ersetzen. 
Dieser sendet auf 868MHz (ASK) mit 125kbit/s. 
https://www.enocean.com/de/enocean_module/ptm-210/user-manual-pdf/ (S.6)
Enocean bietet zwar mit dem TCM310 ein passendes Funkmodul an, aber das 
ist mir mit 23€ etwas zu teuer. Daher erst der Versuch mit dem RFM24W.

Ich werde allerdings aus dem Datenblatt des RFM24W nicht wirklich 
schlau.
https://www.rcscomponents.kiev.ua/datasheets/rfm24w-datasheet.pdf

Ab S.13 wird die SPI-Kommunikation beschrieben. Das Modul erwartet ein 
Firmware-Command-Byte und danach verschiedene Parameter-Bytes. Es wird 
allerdings nicht beschrieben, wie das FW-Cmd-Byte und die 
Parameter-Bytes auszusehen haben.

Auf S.19 sind verschiedene API-Kommandos gezeigt. Entsprechen die 
API-Kommandos dem FW-Kommando?
Zum Test habe ich mal den Wert 0x14 an das Modul geschickt (Retrieves 
temp sensor, low battery detector, or ADC reading) und auf Antwort von 
dem Modul gewartet. Die SDO Leitung bleibt aber unverändert high.
Zudem ist nicht erläutert wie die Daten des Temperatursensors und des 
ADCs kodiert sind.
Auf S.30 gibt es zwar unter "Auxiliary Blocks" diverse Unterpunkte, 
diese sind aber nicht näher erläutert.

Wie müssen also das "FW Command"-Byte und die Parameterbytes aufgebaut 
sein? Ich blicke nicht durch...

Bascom Code:
1
$regfile = "m88def.dat"
2
$crystal = 18432000
3
$baud = 9600
4
5
Ddrc = &B111111
6
Ddrd = &B11111110
7
Ddrb = &B11101111
8
9
NSEL alias PortC.0
10
RX_ANT Alias Portc.1
11
TX_ANT Alias Portc.2
12
13
config spi= hard, interrupt = off, Data_order = MSB, Master = yes, polarity = high, phase = 0, Clockrate = 16, Noss = 1
14
spiinit
15
16
dim spi_inp as Byte
17
18
Do
19
 Nsel = 0
20
 spi_inp = spimove(&H14) 
21
 Nsel = 1
22
 print spi_inp
23
24
 waitms 200
25
Loop

von guest (Gast)


Lesenswert?

Schau mal in das DB:
https://www.silabs.com/documents/public/data-sheets/Si4464-63-61-60.pdf
Unter 8.3 (S.44) siehst Du z.B. daß das GET_ADC_READING Kommando nicht 
nur aus 0x14 besteht, sondern dahinter noch zwei weitere Bytes gehören 
und auch was da zurückkommt.

PS:
https://www.silabs.com/products/wireless/proprietary/ezradiopro-ism-band-transmitters-recievers-transceivers/device.si4460
Insbesondere:
https://www.silabs.com/documents/public/application-notes/EZRadioPRO_REVC2_API.zip
da scheint die komplette API-Beschreibung drin zu sein.

Noch ein paar:
http://www.airspayce.com/mikem/arduino/RadioHead/classRH__RF24.html
Am Anfang des da verlinkten 'RH_RF24.h' finden sich weitere Infos/Links, 
z.B.:
"Sigh: the HopeRF documentation is utter rubbish: full of errors and 
incomplete. The Si446x docs are better" :)

von Luca E. (derlucae98)


Lesenswert?

guest schrieb:
> Schau mal in das DB:
> https://www.silabs.com/documents/public/data-sheets/Si4464-63-61-60.pdf
> Unter 8.3 (S.44) siehst Du z.B. daß das GET_ADC_READING Kommando nicht
> nur aus 0x14 besteht, sondern dahinter noch zwei weitere Bytes gehören
> und auch was da zurückkommt.

Danke, das sieht schon mal vielversprechend aus.

Die Übertragung klappt aber trotzdem noch nicht.

Ich sende die 3 Bytes 0x14, 0x10 und 0xCC um den Temperatursensor 
auszulesen und übertrage danach 9 mal 0x14 um die Daten des RFM 
entgegenzunehmen.
Die SDO-Leitung des RFM bleibt aber nach wie vor durchgehend high.
SDI, CLK und NSEL kommen am Modul an.

Ich habe leider keinen Logicanalyzer um die gesendeten Daten zu 
überprüfen.
Auf dem Oszi sehe ich 12 SCK-Pakete und 12 Datenpakete auf SDI.

Bascom-Code:
1
$regfile = "m88def.dat"
2
$crystal = 18432000
3
$baud = 9600
4
5
Ddrc = &B111111
6
Ddrd = &B11111110
7
Ddrb = &B11101111
8
9
NSEL alias PortC.0
10
11
dim spi_inp(9) as Byte
12
dim spi_out(3) as Byte
13
dim spi_move as Byte
14
dim i as byte
15
16
config spi= hard, interrupt = off, Data_order = msb, Master = yes, polarity = low, phase = 1, Clockrate = 16, Noss = 1
17
spiinit
18
19
Enable Interrupts 
20
21
Do
22
  spi_out(1) = &H14
23
  spi_out(2) = &B00010000
24
  spi_out(3) = &B11001100
25
  spi_move = &H14
26
27
  nsel = 0
28
  spiout spi_out(1),3
29
  spi_inp(1) = spimove(spi_move ,1)
30
  spi_inp(2) = spimove(spi_move ,1)
31
  spi_inp(3) = spimove(spi_move ,1)
32
  spi_inp(4) = spimove(spi_move ,1)
33
  spi_inp(5) = spimove(spi_move ,1)
34
  spi_inp(6) = spimove(spi_move ,1)
35
  spi_inp(7) = spimove(spi_move ,1)
36
  spi_inp(8) = spimove(spi_move ,1)
37
  spi_inp(9) = spimove(spi_move ,1)
38
  nsel = 1
39
  
40
  for i = 1 to 9
41
   print spi_inp(i)
42
  next i
43
44
  wait 2
45
Loop

von guest (Gast)


Lesenswert?

Luca E. schrieb:
> Ich sende die 3 Bytes 0x14, 0x10 und 0xCC um den Temperatursensor
> auszulesen und übertrage danach 9 mal 0x14 um die Daten des RFM
> entgegenzunehmen.

Das dürfte so nicht gehen, sende mal zum Lesen nur 0x00, ansonsten 
wackelt das Teil wohl auch mit irgendeine Pin (CTS?).

PS: 0x00 ist wohl auch verkehrt :(
Unter einem der obigen Links findest Du die AN633 von SiLabs:
"Reading from the radio requires several steps to be followed. The host 
MCU should send a command with the address it requests to read. The 
radio holds the CTS while it retrieves the requested information. Once 
the CTS is set (0xFF), the host MCU can read the answer from the radio. 
If the CTS is polled on the GPIOs, or the radio is configured to provide 
interrupt if the answer is available, then the response can be read out 
from the radio with the following SPI transaction.
If the CTS is polled over the SPI bus, first the host MCU should pull 
the NSEL pin low. This action should be followed by sending out the 0x44 
Read command ID and providing an additional eight clock pulses on the 
SCLK pin. The radio will provide the CTS byte on its SDO pin during the 
additional clock pulses. If the CTS byte is 0x00, then the response is 
not yet ready and the host MCU should pull up the NSEL pin and repeat 
the procedure from the beginning as long as the CTS becomes 0xFF. If CTS 
is 0xFF, then the host MCU should keep the NSEL pin low and provide 
clock cycles on the SCLK pin, as many as the data to be read out 
requires. The radio will clock out the requested data on its SDO pin 
during the additional clock pulses.
..."

In Deinen Fall käme wohl CTS SW-Polling via SPI in Frage, ist in der AN 
an anderer Stelle noch mal beschrieben:
"To ensure the radio is ready to receive the next command, the host MCU 
has to pull down the NSEL pin to monitor the status of CTS over the SPI 
port. The 0x44 command ID has to be sent and eight clock pulses have to 
be generated on the SCLK pin. During the additional eight clock cycles, 
the radio clocks out the CTS as a byte on the SDO pin. When completed, 
the NSEL should be pulled back to high. If the CTS byte is 0xFF, it 
means that the radio processed the last command successfully and is 
ready to receive the next command; in any other case, the CTS read 
procedure has to be repeated from the beginning as long as the CTS byte 
is not 0xFF."

von Luca E. (derlucae98)


Lesenswert?

Danke für die Antwort. Ich komme allerdings erst nächste Woche wieder 
zum Testen.

von Luca E. (derlucae98)


Lesenswert?

guest schrieb:
> PS: 0x00 ist wohl auch verkehrt :(

Das Modul erwartet zum Senden der Bytes ja nur jeweils 8 Clockimpulse. 
Da wird es egal sein, was ich an das Modul sende. Zumindest geht aus dem 
Impulsdiagramm und dem Text nicht hervor, was genau gesendet werden 
soll, wenn Daten aus dem Modul herausgetaktet werden sollen.

Ich habe es gerade nochmal probiert. Was mich etwas stutzig macht, ist 
dass der SDO-Pin durchgehend high bleibt. Das interpretiert der 
Mikrocontroller als 0xFF, aber müsste SDO im Ruhezustand nicht 
eigentlich low sein?

von Johannes (Gast)


Lesenswert?

Nein, High-Pegel ist schon i.O., weil die SPI-Leitungen normalerweise 
mit Pullup funktioniert und bei zu sendendem Low-Pegel das jeweilige Pin 
über einen internen Transistor auf Masse gezogen wird. Hattest du denn 
mittlerweile (zwei Jahre ist es her) Erfolg?

von spess53 (Gast)


Lesenswert?

Hi

>Nein, High-Pegel ist schon i.O., weil die SPI-Leitungen normalerweise
>mit Pullup funktioniert und bei zu sendendem Low-Pegel das jeweilige Pin
>über einen internen Transistor auf Masse gezogen wird.

Verwechselt du das nicht mit I2C?

MfG Spess

von Luca E. (derlucae98)


Lesenswert?

Johannes schrieb:
> Hattest du denn mittlerweile (zwei Jahre ist es her) Erfolg?

Das Modul ist verbaut, aber ich konnte es nicht in Betrieb nehmen. Ich 
habe mir vorgenommen es erneut zu versuchen, aber mir fehlt aktuell 
einfach die Zeit dafür. Ich melde mich dann, wenn es soweit ist. ;-)

von Johannes (Gast)


Lesenswert?

spess53 schrieb:
> Verwechselt du das nicht mit I2C?

Da ist es m.E. auch so.



Luca E. schrieb:
> mir fehlt aktuell
> einfach die Zeit dafür.

Schade. Ich bin im Moment so weit, dass ich den RFM24W per Python-Script 
von einem Raspberry Pi aus ansteuern kann (wenn ich per SPI den Befehl 
für GPIO auf High setzen sende, macht er das auch), aber er antwortet 
mir noch nichts über SPI bei einem Read Command. Ebenso scheint der 
Clock noch nicht richtig initialisiert zu sein, denn es kommt ein 
Low-Pegel, wenn ich diesen über ein GPIO-Pin ausgeben will.

Ich sende, wie in der Doku (Download 
https://www.silabs.com/documents/public/application-notes/EZRadioPRO_REVC2_API.zip 
) unter 
EZRadioPRO_REVC2/Si4460/revC2A/index_all.html#field_a55aa460_cd81_11e4_a 
451_180373e564d0_GPIO_MODE_5  beschrieben, folgendes:
1
spi.writebytes([0x13, 0x43, 0x45, 0x46, 0x47, 0x4B, 0x4B, 0x00])
0x13 ... Befehl GPIO_PIN_CFG
0x43 ... GPIO0 Pullup_EN, High-Pegel
0x45 ... GPIO1 Pullup_EN, 32KHz CLK
0x46 ... GPIO2 Pullup_EN, Boot CLK
0x47 ... GPIO3 Pullup_EN, Divided CLK
0x48 ... NIRQ Pullup_EN, SDO Mode
0x48 ... SDO Pullup_EN, SDO Mode
0x00 ... DRV_STRENGTH set to HIGH

Egal ob ich im Standby-Mode konfiguriere oder im SPI_ACTIVE Mode, das 
Ergebnis bleibt das gleiche: Es kommt kein CLK-Signal, nur der Boot CLK 
und bei SDO Mode hängt der Spannungspegel in der Mitte bei 1,5 V herrum.

Meine Abfolge bisher:
Ich schicke erst Boot command POWER_UP:
(NO_PATCH, FUNC PRO, XTAL, XO_FREQ_DEFAULT)
1
spi.writebytes([0x02, 0x01, 0x00, 0x01, 0xC9, 0xC3, 0x80])
dann setze ich die Clock Property:
(GROUP 0x01, NUMPROP=1, STARTPROP=1, DIVCLKEN,DIV_7_5,INTERNRC)
1
resp = spi.writebytes([0x11, 0x01, 0x01, 0x01, 0x5B])
Dann wechsel ich den Modus (Change State:
(in diesem Fall Sleep/Standby)
1
spi.writebytes([0x34, 0x01])
Dann setze ich die GPIOs, wie oben beschrieben.
Nachher versuche ich auch noch die Part info auszulesen (Command 0x01), 
aber SDO bleibt in allen Fällen unverändert.

Was mache ich falsch?

von Johannes (Gast)


Lesenswert?

Johannes schrieb:
> Egal ob ich im Standby-Mode konfiguriere oder im SPI_ACTIVE Mode, das
> Ergebnis bleibt das gleiche: Es kommt kein CLK-Signal, nur der Boot CLK
> und bei SDO Mode hängt der Spannungspegel in der Mitte bei 1,5 V herrum.

ok, also der Clock funktioniert jetzt, ich hatte aus Versehen die 
falsche Gruppe in der Konfiguration angegeben. Aber SDO funktioniert 
immer noch nicht. Weiß jemand, woran das liegt?

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.