Forum: Mikrocontroller und Digitale Elektronik RFM70-Funkmodul funkt nicht!


von H. G. (ledi)


Lesenswert?

Hallo,

ich baue mir eine Fernbedienung mit dem RFM70 2,4GHz Funkmodul von 
HOPERF.
Die Registerbänke 0 und 1 habe ich gesetzt (hoffentlich korrekt)aber ich 
bekomme das Teil nicht in den TX-Mode.
Ich prüfe das mit einer Strommessung. Lt. Datenblatt soll das Modul im 
TX-Mode ca. 11 bis 23mA benötigen (je nach output power Einstellung). 
Ich bewege mich dzt. so um die 5mA (inkl. Mikrokontroller)

Da ich derzeit keine Idee mehr habe, bitte ich um Hilfe!

Link zum Datenblatt:[[http://www.hoperf.com/upfile/RFM70.PDF]]

Lt. Datenblatt muss ich folgende Schritte durchführen:
1.) PWR UP Bit auf 1 und PRIM RX Bit auf 0 setzen
2.) Payload in das TX FIFO laden
3.) High-Impuls auf dem CE-Pin ausgeben

Hier mein Code der Register-Settings:
1
#ifndef RF_init_h
2
#define RF_init_h
3
4
5
//************  Bank1 register 0-13 initialization value
6
7
//In the array RegArrFSKAnalog,all the register value is the byte reversed!!!!!!!!!!!!!!!!!!!!!
8
const unsigned int Bank1_Reg0_13[40]=    
9
{       
10
//    address      data
11
    (0x20|0x00),  0x40,  0x4B,  0x01,  0xE2,    //0xE2014B40  Address 0
12
    (0x20|0x01),  0xC0,  0x4B,  0x00,  0x00,    //0x00004BC0  Address 1
13
    (0x20|0x02),  0xD0,  0xFC,  0x8C,  0x02,    //0x028CFCD0  Address 2
14
    (0x20|0x03),  0x99,  0x00,  0x39,  0x41,    //0x41390099  Address 3  
15
    (0x20|0x04),  0xD9,  0x9E,  0x86,  0x0B,    //0x0B869ED9  Address 4
16
    (0x20|0x05),  0x24,  0x06,  0x7F,  0xA6,    //0xA67F0624  Address 5
17
    (0x20|0x0C),  0x00,  0x73,  0x12,  0x00,    //0x00127300  Address C
18
    (0x20|0x0D),  0x00,  0x80,  0xB4,  0x36,    //0x36B48000  Address D  
19
};
20
21
22
//************  Bank1 register 14 initialization value
23
const unsigned int Bank1_Reg14[12]=
24
{
25
//  address  Data...
26
  (0x20|0x0E),   0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF,
27
//  0x20 = Write Command
28
};
29
30
//************  Bank0 register initialization value
31
const unsigned int Bank0_Reg0_29[18]=
32
{
33
//    address      data
34
    (0x20|0x00),  0x72,  //Disable CRC ,CRC=1byte, POWER UP, TX
35
    (0x20|0x01),  0x01,  //Enable auto acknowledgement data pipe0
36
    (0x20|0x02),  0x01,  //Enable RX Addresses pipe0
37
    (0x20|0x03),  0x03,  //RX/TX address field width 5byte
38
    (0x20|0x04),  0x00,  //auto retransmission disabled
39
    (0x20|0x05),  0x0B,  //channel = 11
40
    (0x20|0x06),  0x34,  //air data rate-1M,out power 0dbm,setup LNA gain-20dB
41
    (0x20|0x1C),  0x01,  //Enable dynamic payload legth data pipe0
42
    (0x20|0x1D),  0x06,  //Enables Dynamic Payload Length,Enables Payload with ACK
43
};
44
45
#endif

Hier der C-Code meiner TX-Testroutine:
1
void main(void)
2
{   
3
  CS_high(3000);          // CS = high
4
5
  DDRC = 0xFF;          // PORTC = Output
6
7
  SPI_Master_Init();        // Init SPI
8
  Init_RF_Settings();        // RF Settings
9
10
    while(1)
11
    {
12
    CS_low(50);          // CS = low 50us
13
14
    SPDR = 0x20;        // Command: Write to Register 0x00
15
    while (!(SPSR & (1<<SPIF)));
16
    SPDR = 0x02;        // Write Data --> PWR_UP Bit = 1
17
    while (!(SPSR & (1<<SPIF)));
18
19
    CS_high(50);        // CS = high 50us
20
    
21
    CS_low(50);          // CS = low 50us
22
23
    SPDR = 0xA0;        // Command Payload TX
24
    while (!(SPSR & (1<<SPIF)));
25
    SPDR = 0xAF;        // Write Data 0xAF
26
    while (!(SPSR & (1<<SPIF)));
27
28
    CE_High_Pulse();      // CE = 1 for 1sek
29
    
30
    CS_high(50);        // CS = high 50us
31
    }
32
}

von odo.m (Gast)


Lesenswert?

Hallo,

hat sich hier etwas getan?
Ich glaube, ich habe exakt das gleiche Problem.

von Timmo H. (masterfx)


Lesenswert?

Also bei mir läuft das RFM70 perfekt mit dem Beispielcode von HopeRF 
(1:1 übernommen). Einzig die SPI-Funktionen habe ich etwas angepasst, da 
ich den USART im SPI-Mode betreibe.

von H. G. (ledi)


Lesenswert?

liste mal deine Vorgehensweise Schritt für Schritt auf!

von odo.m (Gast)


Lesenswert?

ok. Heute Abend nach dem Job.

Ich liste dann mal die relevanten Code-Teile.
Vorab schon mal als Zusammenfassung:

2 mal ATMEGA 328 (Arduino Nano). 5V. RFM70 VCC an 3V.
MISO, MOSI, SCK an Standard-Pins. CS nicht am ATMEGAs SS, sondern 
anderem freien Pin. CE an freiem Pin.

SPI-Kommunikation zwischen den ATMEGAs und den RFM70s läuft tadellos. 
Kann Register setzen und lesen.

Der Code entspricht dem aus dem Pic-Example von der Hersteller Web-Site. 
SPI habe ich angepasst.

Register habe ich zunächst mal gesetzt wie im Datasheet beschieben. Da 
macht der Beispielcode von HOPERF was anderes :-) Habe da bereits 
unterschiedliche Varianten ausprobiert. Auch den Registerswap, der im 
Beispielcode drin ist, habe ich mal versucht und mal weghgelassen.

Insbes mache ich:

CONFIG.PWR-UP=1
PTX setze ich CONFIG.PRIM_RX = 0
PRX setze ich CONFIG.PRIM_RX = 1
Ausserdem aktiviere ich die features im FEATURE Register.

Um den TX zu aktivieren setze ich CE auf 1, und packe Payload in den 
TX_FIFO

Auf RX-Seite setze ich ebenfalls CE = 1

Ergebnisse:


1. Versuch: ENAA_P0 = 1  und senden mit SPI-Command W_TX_PAYLOAD
Ergebnis: PTX STATUS Register zeigt instant MAX_RT=1, IRQ geht active 
low und TX_OBSERVE-Register zeigt ARC=15. So, als ob er den Auto 
Retransmit-Delay gar nicht beachtet. Ab der 4. Payload in den TX_FIFO 
zeigt dann Status auch FIFO_FULL.

2. Versuch: Wie 1) aber versenden mit SPI-Command W_TX_PAYLOAD_NO_ACK
Ergebis: STATUS-Register und TX_OBSERVE-Register verändern sich nicht 
bis auf: TX_DS=1. IRQ geht active low.

3. Versuch: ENAA_P0 = 0 und senden mit SPI-Command W_TX_PAYLOAD
Ergebnis: Wie 2.

Auf RX-Seite: Langeweile. CD-Register bleibt auf 0, IRQs werden keine 
ausgelöst.


Vermutungen:
1) 6 Test-chips kaputtgelötet beim Anschluß (unwahrscheinlich :-)
2) Hardwaredefekt ab Werk (möglich aber unwahrscheinlich)
3) Denkfehler. (möglich)

Ad 3) Kann es sein, dass ich da was mit dem CE-Pin falsh verstehe? Darf 
der ggf. nur gepulst werden und wenn ich den HIGH lasse, so wie ich es 
tue, dann gehts nicht?

Leider habe ich auch keine Idee, wie ich nun testen kann, weil ich habe 
kein Equip um zu messen ob da was "on air" passiert.

 Gruß

Odo

von Timmo H. (masterfx)


Lesenswert?

Also bei mir ist CE immer HIGH, nur wenn ich auf Rx bzw. Tx Mode 
umschalte wird es kurz auf LOW gesetzt und zwar nur solange wie ins 
CONFIG-Register geschrieben wird.
Wie im Beispielcode eben:
1
void SwitchToRxMode()
2
{
3
  UINT8 value;
4
5
  SPI_Write_Reg(FLUSH_RX,0);//flush Rx
6
7
  value=SPI_Read_Reg(STATUS);  // read register STATUS's value
8
  SPI_Write_Reg(WRITE_REG|STATUS,value);// clear RX_DR or TX_DS or MAX_RT interrupt flag
9
10
  CE=0;
11
12
  value=SPI_Read_Reg(CONFIG);  // read register CONFIG's value
13
  
14
//PRX
15
  value=value|0x01;//set bit 1
16
    SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled..
17
  CE=1;
18
}
19
20
void SwitchToTxMode()
21
{
22
  UINT8 value;
23
  SPI_Write_Reg(FLUSH_TX,0);//flush Tx
24
25
  CE=0;
26
  value=SPI_Read_Reg(CONFIG);  // read register CONFIG's value
27
//PTX
28
  value=value&0xfe;//set bit 0
29
    SPI_Write_Reg(WRITE_REG | CONFIG, value); // Set PWR_UP bit, enable CRC(2 length) & Prim:RX. RX_DR enabled.
30
  
31
  CE=1;
32
}

von odo.m (Gast)


Lesenswert?

Ja schade. So mache ich es auch.

Bleibt also nur noch Chips kaputt, Chips kaputt gemacht beim 
Kabel-anlöten, Interferenzen, unentdeckter Software-Fehler ?

Ich schicke heute Abend mal einen total abgespeckten Referenzcode. 
Vielleicht kannst Du / könntet Ihr den mal bei Euch laufen lassen...

Zum Thema löten: Ich habe 2 chips auf 350 Grad und die restlichen auf 
250 Grad gelötet. Die Löstellen sehen gut aus. Hab mal mit der Lupe 
geschaut. Sonst würde ja auch nicht no viel klappen, wie es aktuell der 
Fall ist.

Soll ich mal Code laufen lassen, der z.B. Kanäle scannt, also alle x 
sekunden weiterschaltet und neuen Sende / Empfangsversuch machen?

@Heimo: Läuft das bei Dir denn jetzt auch?

Gruß

Odo

von Odo M. (odo_m)


Angehängte Dateien:

Lesenswert?

Hi,

hier ist mal mein code als attachment.

der debug sieht dann so aus:

[rfm70 sender]
debug registers: 0:72, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:2E, 8:0, 9:0,
sent payload
debug registers: 0:72, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:2E, 8:0, 9:0,
sent payload
debug registers: 0:72, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:2E, 8:0, 9:0,
sent payload
debug registers: 0:72, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:2E, 8:0, 9:0,
sent payload
debug registers: 0:72, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:2E, 8:0, 9:0,
sent payload
debug registers: 0:72, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:2E, 8:0, 9:0,
sent payload
debug registers: 0:72, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:2E, 8:0, 9:0,
sent payload



[rfm70 receiver]
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,
debug registers: 0:73, 1:1, 2:1, 3:3, 4:0, 5:B, 6:34, 7:E, 8:0, 9:0,


Vielleicht hat ja jemand eine Idee

von Odo M. (odo_m)


Angehängte Dateien:

Lesenswert?

löl. hier nun der richtige code.
sorry ;-)

von odo.m (Gast)


Lesenswert?

Hmm.

Das verrückte ist: auch mein Testcode, den ich letzte Nacht hier 
zunächst aus Versehen gepostet habe, erzeugt den gleichen Debug-Output, 
wie der "echte" Code, den ich ja noch hinterher gepostet habe.

Der Unterschied ist, dass ich in dem Test-Code Code CE nicht auf HIGH 
setze. RFM verhält sich aber bei CE=1 und CE=0 gleich. Das darf doch lt. 
Manual so gar nicht sein... CE=1 und CE=0 muss doch einen gewaltigen 
Unterschied machen.

Ich hab dann mal geprüft, ob da überhaupt Spannung am CE-Pin des RFM 
anliegt, wenn ich den ATMEGA-Pin high setze. Antwort "JA" (puh ;-)

Also back to the roots.

Beschaltung stimmt, Stromversorgung stimmt, SPI-Kommunikation stimmt, 
State-Machine des RFM tut so, als ob sie was tut, Over-the-Air: Klappt 
nicht.

Kann mal jemand die Register-Setting checken Habe ich da alles richtig 
gemacht?

von H. G. (ledi)


Lesenswert?

Folgende Reihenfolge bei der Initialisierung:

1.) Settings RB0 (Reg. 0...29)
2.) Toggle RB1
3.) Settings RB1 + Reg.14
4.) Toggle RB0
5.) Activate(0x73)

von odo.m (Gast)


Lesenswert?

ok. bei mir ist Activation vor RB1 + Reg 14 setting.
Ich stell das heute Abend mal um.

Kannst Du / kann jemand evtl mal funktionierende Init-Werte für die 
Register posten? Es gibt ja einige threads mit unterschiedlichen 
Auffasungen zu Reihenfolgen der bytes und einiger Werte und 
byte-toggle-patches etc.. Kann ja sein, dass ich da ein nicht 
funktionierendes setup habe.

Siehe auch meinen Code. Ich lese die in meinem Code definierten Werte 
alle von links nach rechts in die Register ein.

von Timmo H. (masterfx)


Lesenswert?

odo.m schrieb:
> Kannst Du / kann jemand evtl mal funktionierende Init-Werte für die
> Register posten?
Gibts doch bei HopeRF. So wie die da sind funzt das einwandfrei.

von odo.m (Gast)


Lesenswert?

Also mit gedrehten Bank1 Reg 9-13 ? Warum ist das so schräg 
programmiert?
Auszug des HOPERFM-Codes:

1
for(i=0;i<=8;i++)//reverse
2
  {
3
    for(j=0;j<4;j++)
4
      WriteArr[j]=(Bank1_Reg0_13[i]>>(8*(j) ) )&0xff;
5
6
    SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
7
  }
8
9
  for(i=9;i<=13;i++)
10
  {
11
    for(j=0;j<4;j++)
12
      WriteArr[j]=(Bank1_Reg0_13[i]>>(8*(3-j) ) )&0xff;
13
14
    SPI_Write_Buf((WRITE_REG|i),&(WriteArr[0]),4);
15
  }

Ich hab da mal einfach meine Konstanten für die initialisierung 
umgedreht und Register 0-13 alle mit dem gleichen code geschrieben


und: brauch ich das auch? Das steht nicht so im Datenblatt:

1
//toggle REG4<25,26>
2
  for(j=0;j<4;j++)
3
    //WriteArr[j]=(RegArrFSKAnalog[4]>>(8*(j) ) )&0xff;
4
    WriteArr[j]=(Bank1_Reg0_13[4]>>(8*(j) ) )&0xff;
5
6
  WriteArr[0]=WriteArr[0]|0x06;
7
  SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);
8
9
  WriteArr[0]=WriteArr[0]&0xf9;
10
  SPI_Write_Buf((WRITE_REG|4),&(WriteArr[0]),4);

Gruß

Odo

von Timmo H. (masterfx)


Lesenswert?

odo.m schrieb:
> Also mit gedrehten Bank1 Reg 9-13 ? Warum ist das so schräg
> programmiert?
das ist nicht schräg programmiert, sondern die Hardware erwartet diese 
Bits verdreht.
Siehe Datenblatt:
1
 <Data  bytes:  LSB  byte  to  MSB  byte, 
2
MSB  bit  in  each  byte  first>  for  all 
3
registers  at  bank  0  and  register  9  to 
4
register 14 at bank 1 
5
„
6
  <Data    bytes:    MSB    byte    to    LSB    byte, 
7
MSB bit in each byte first> for register 0 
8
to register 8 at bank 1

von Odo M. (odo_m)


Lesenswert?

Ha!
Timmo, Du bist ein Held. Da war ein Dreher in den Register-Settings.

Jetzt klappt der Transfer.

Aber einen Carrier Detect bekomme ich leider trotzdem nicht. Da habe ich 
dann wohl das Datasheet noch nicht so ganz verstanden. Dachte, wenn ich 
was empfange, muss CD zwangsläufig auf 1 gehen... Ist das nicht so?


Hier schicke ich mal die Register-Settings, die zum Erfolg führten. Ich 
clocke die alle von links nach rechts via SPI.
1
//  0x20 = Write Command
2
//************  Bank0 register initialization commands
3
uint8_t bank0Init[][2]=
4
{
5
//    address      data
6
    { (0x20|0x00),  0x0F },  //Disable CRC ,CRC=1byte, POWER UP, TX
7
    { (0x20|0x01),  0x3F },  //Enable auto acknowledgement data pipe0
8
    { (0x20|0x02),  0x3F },  //Enable RX Addresses pipe0
9
    { (0x20|0x03),  0x03 },  //RX/TX address field width 5byte
10
    { (0x20|0x04),  0xFF },  //auto retransmission disabled
11
    { (0x20|0x05),  0x17 },  //channel = 18
12
    { (0x20|0x06),  0x3F },  //air data rate-1M,out power 0dbm,setup LNA gain-20dB
13
    { (0x20|0x07),  0x07 },//
14
    { (0x20|0x08),  0x00 },//
15
    { (0x20|0x09),  0x00 },//>
16
    { (0x20|0x0C),  0xc3 },  //LSB Addr pipe 2
17
    { (0x20|0x0D),  0xc4 },  //LSB Addr pipe 3
18
    { (0x20|0x0E),  0xc5 },  //LSB Addr pipe 4
19
    { (0x20|0x0F),  0xc6 },  //LSB Addr pipe 5
20
    { (0x20|0x11),  0x20 },  //
21
    { (0x20|0x12),  0x20 },  //
22
    { (0x20|0x13),  0x20 },  //
23
    { (0x20|0x14),  0x20 },  //
24
    { (0x20|0x15),  0x20 },  //
25
    { (0x20|0x16),  0x20 },  //
26
    { (0x20|0x17),  0x20 },  //
27
    { (0x20|0x1C),  0x3F },  //Enable dynamic payload legth data pipe0
28
    { (0x20|0x1D),  0x07 }   //Enables Dynamic Payload Length,Enables Payload with ACK
29
};
30
31
uint8_t bank1Init[][5]= {       
32
//    address      data
33
    { (0x20|0x00),  0x40,  0x4B,  0x01,  0xE2 },
34
    { (0x20|0x01),  0xC0,  0x4B,  0x00,  0x00 },
35
    { (0x20|0x02),  0xD0,  0xFC,  0x8C,  0x02 },
36
    { (0x20|0x03),  0x99,  0x00,  0x39,  0x41 },
37
    { (0x20|0x04),  0xf9,  0x9E,  0x86,  0x0B }, // b9? f9?
38
    { (0x20|0x05),  0x24,  0x06,  0x7F,  0xA6 },
39
    { (0x20|0x06),  0x00,  0x00,  0x00,  0x00 },
40
    { (0x20|0x07),  0x00,  0x00,  0x00,  0x00 },
41
    { (0x20|0x08),  0x00,  0x00,  0x00,  0x00 },
42
    { (0x20|0x09),  0x00,  0x00,  0x00,  0x00 },
43
    { (0x20|0x0a),  0x00,  0x00,  0x00,  0x00 },
44
    { (0x20|0x0b),  0x00,  0x00,  0x00,  0x00 },
45
    { (0x20|0x0C),  0x00,  0x12,  0x73,  0x00 },
46
    { (0x20|0x0D),  0x36,  0xb4,  0x80,  0x00 } 
47
};
48
49
//************  Bank1 register 14 initialization commands
50
uint8_t bank1R0EInit[]=
51
{
52
//  address  Data...
53
  (0x20|0x0E),   0x41,0x20,0x08,0x04,0x81,0x20,0xCF,0xF7,0xFE,0xFF,0xFF
54
};

Ich mach mal den Code wieser sauber und poste den dann hier, falls 
jemand Bedarf ab Arduino-Code für RFM hat...

Danke Euch für die Hilfe !!

Gruß

Odo

von Ralf B. (worstcase)


Lesenswert?

Hallo Ihr da draussen ;-)

Wir kämpfen hier auch mit der Erstinbetriebnahme vom RFM70. Um uns die 
Arbeit leichter zu machen, haben wir zwei Demo_Boards RFM70 V2.0 gekauft 
(weil ja die Software dabei sein sollte) um dann zuschauen, ob es funzt. 
Die zwei Demo-Boards machen auch was sie sollen - nur leider ist nicht 
die komplette Software incl. einlesen der Schalter und das Testprogramm 
dabei. Also "etwas" schwierig auf unserer Seite Software zu 
implementieren um diese dann gegen so ein Demo-Board zu testen....

Deshalb die Frage: Hat einer da draussen den kompletten Demo-Board-Code?

Wir wollen das auch auf SPI umswitchen. hat jemand einen Beispielscode 
dafür? Würde hier eventuelle Bugs gerne ausschließen....

Bin für jeden Tipp dankbar....

Ralf

von GerhardL. (Gast)


Lesenswert?

hallo,
erst mal vielen Dank für die vielfältigen Tips in Sachen RFM70. Ich 
möchte auch mit den Modulen einen Datenlink herstellen. Ich werde 
allerdings den Arduino (5 V Versorgung) nicht direkt mit den RFM70 
(Versorgung 3,3 V) verbinden, da dies ggf. auch zu unkorrektem 
Datenaustausch führen kann. Abhilfe Data Level Converter 3/5 V bzw. 5/3 
V z.B. von Linear

Gerhard

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.