Forum: Mikrocontroller und Digitale Elektronik STM32 RF24 Kommunikation


von Robert S. (gips1gott)


Lesenswert?

Moin Leute,

ich versuche ein STM32 Nucleo L476RG mit einem NRF24L01+ kommunizieren 
zu lassen. Habe die Kommunikation mit zwei Arduino's problemlos 
herstellen können.

Ich verwende mbed und habe die Lib von Maniacbug ausschließlich für 
STM32 und portiert von Arduino für mbed verwendet.

Mit beiden Lib's bekomme ich keine Kommunikation zu meinem sendenden 
Arduino zustande. Ich bekomme ständig bei radio.available() eine null.

Auch die Open Source Lib von Christian J. hat mir bisher nicht 
weiterhelfen können.

Hat jemand bereits eine erfolgreiche Kommunikation herstellen können? 
Gibt es Tipps oder evtl. Libs die bei euch laufen?

Vielen Dank und Grüße,

von Robert S. (gips1gott)


Lesenswert?

Mein Code:
1
#include "mbed.h"
2
#include "RF24.h"
3
#include "SPI.h"
4
5
/*************  USER Configuration *****************************/
6
7
Serial serial0(USBTX, USBRX);
8
9
//#define nrf_CE      D3
10
//#define nrf_CSN     D10
11
//#define spi_SCK     D13
12
//#define spi_MOSI    D11
13
//#define spi_MISO    D12
14
 
15
#define nrf_CE      D8
16
#define nrf_CSN     D10
17
#define spi_SCK     D13
18
#define spi_MOSI    D11
19
#define spi_MISO    D12 
20
21
 
22
RF24 radio(spi_MOSI, spi_MISO, spi_SCK, nrf_CE, nrf_CSN);//*****MOSI MISO SCK CE CS******
23
24
/***************************************************************/
25
26
typedef unsigned char Byte; 
27
28
const uint64_t send_pipe=0xABCDABCD71LL;//These are just arbitrary 64bit numbers to use as pipe identifiers
29
const uint64_t recv_pipe=0x544d52687CLL;//They must be the same on both ends of the communciations
30
31
Byte data[32];                           //Datenpuffer.
32
33
unsigned long counter, rxTimer;          //Counter and timer for keeping track transfer info
34
unsigned long startTime, stopTime;  
35
bool TX=1,RX=0,role=0;
36
37
Timer t;
38
39
void setup(void) {
40
41
    serial0.baud(9600);
42
    serial0.printf("Ready for commands \n");
43
    radio.begin();
44
    radio.setRetries(2,15);
45
    radio.setPALevel(RF24_PA_LOW);
46
    radio.openWritingPipe(send_pipe);
47
    radio.openReadingPipe(1,recv_pipe);
48
    radio.startListening();
49
  
50
    serial0.printf("Setup finished \n");
51
}
52
53
int main(){
54
55
  setup();
56
  t.start();
57
  wait(1);
58
  
59
if(role == RX){
60
     
61
     serial0.printf("Received Mode \n");
62
     
63
     float f = t.read_us();      
64
     serial0.printf("%f \n",f);
65
     
66
     serial0.printf("%d\r\n",radio.available());
67
     
68
      while(radio.available()){ 
69
      radio.read(&data,sizeof(data));
70
      serial0.printf("Daten \n");
71
      counter++;
72
     }
73
     
74
   }
75
   
76
   radio.startListening(); 
77
   t.stop();
78
 }

: Bearbeitet durch User
von Johannes S. (Gast)


Lesenswert?

ich hatte dafür mal diese Lib benutzt und es hatte funktioniert: 
https://os.mbed.com/users/Owen/code/nRF24L01P/
Das Projekt liegt aber hier schon länger auf Eis.

von Robert S. (gips1gott)


Lesenswert?

Johannes S. schrieb:
> Das Projekt liegt aber hier schon länger auf Eis.

Was meinst du damit?

von Mampf unterwegs (Gast)


Lesenswert?

Jan S. schrieb:
> Johannes S. schrieb:
> Das Projekt liegt aber hier schon länger auf Eis.
>
> Was meinst du damit?

d.h. er arbeitet seit längerem nicht mehr daran ...

von Johannes S. (Gast)


Lesenswert?

so isses, habe mich wieder mehr den RFM69 Modulen gewidmet, die sollen 
als Funknodes für Heimautomatisierung dienen.
Die nRF Chips sind auch interessant, aber irgendwie müsste man mehr Zeit 
haben...
Ein nRF51822 Evalboard habe ich noch vor kurzem ausprobiert, das ist ja 
ein Cortex-M0 mit eingebautem nRF24 und BLE Stack. Da gibts jede Menge 
billiger Module im <5$ Bereich beim Chinesen. Diese werden auch von mbed 
unterstützt und die BLE UART, Button oder Beacon Beispiele haben ad hoc 
funktioniert. Aber jetzt möchte ich erstmal einen Massanzug für meine 
RFM Fernbedienung drucken.

von Gips1Gott (Gast)


Lesenswert?

Johannes S. schrieb:
> so isses, habe mich wieder mehr den RFM69 Modulen gewidmet, die
> sollen als Funknodes für Heimautomatisierung dienen. Die nRF Chips sind
> auch interessant, aber irgendwie müsste man mehr Zeit haben... Ein
> nRF51822 Evalboard habe ich noch vor kurzem ausprobiert, das ist ja ein
> Cortex-M0 mit eingebautem nRF24 und BLE Stack. Da gibts jede Menge
> billiger Module im <5$ Bereich beim Chinesen. Diese werden auch von mbed
> unterstützt und die BLE UART, Button oder Beacon Beispiele haben ad hoc
> funktioniert. Aber jetzt möchte ich erstmal einen Massanzug für meine
> RFM Fernbedienung drucken.

Ich werde mich heute mit der Bibliothek ,die du vorgeschlagen hast, 
beschäftigen. Dafür erstmal vielen Dank. Kann ich bei Fragen mich bei 
dir melden?

Danke.

von Chris J. (Gast)


Lesenswert?

Jan S. schrieb:
> Auch die Open Source Lib von Christian J. hat mir bisher nicht
> weiterhelfen können.

Welche?

bei mir spielt auch ein Arduino mit der radiohead Lib mit dem STM32 
zusammen. Denk aber dran dass du bei Daten __packed_array nehmen musst, 
wenn Du structs überträgst.

Vielleicht findest Du ja was was bei dir anders ist, mal eben per ftp 
auf meinen Raspi zugegriffen und es raus geholt:
1
/* AVR standard libs */
2
#include <avr/wdt.h>
3
#include <avr/power.h>
4
#include <avr/sleep.h>
5
#include <avr/io.h>
6
7
/* C standard Libs */
8
#include <stdint.h>
9
10
/* Projekt Libs */
11
#include <SPI.h>
12
#include <nRF24L01.h>
13
#include <DHT.h>
14
#include <printf.h>
15
#include <RF24.h>
16
#include <RF24_config.h>
17
#include <DallasTemperature.h>
18
#include <OneWire.h>
19
20
#define DHTTYPE DHT22     // DHT 22  (AM2302), AM2321
21
#define DHTPIN     2       // what digital pin we're connected to
22
23
#define CE_PIN     8    // CE NRF24L01
24
#define CSN_PIN    7    // CSN NRF24L01
25
26
#define RF_CHANNEL   50
27
28
// Der Transfer Datensatz
29
struct data_t {
30
  uint16_t    id;
31
  uint16_t   nr;
32
  float     temperatur_1;
33
  float     temperatur_2;
34
  float     feuchte;
35
  float    ubatt;
36
} __attribute__((packed)) data;
37
38
/* ----- Instanzen --------- */
39
DHT dht(DHTPIN, DHTTYPE);
40
OneWire oneWire(9);
41
DallasTemperature sensors(&oneWire);
42
DeviceAddress devAdr = { 0x28, 0xff, 0xdc, 0xba, 0xa4, 0x15, 0x04, 0xa7 };
43
RF24 radio(CE_PIN, CSN_PIN);
44
45
const int LED_ROT = 19;
46
const int LED_GLB = 18;
47
const int UB_PIN  = 0;
48
49
// Tx und Rx Adressen
50
uint8_t TXADDRESS [5] = {0x49,0x23,0x06,0x50,0x61};
51
52
uint16_t transmit_counter = 0;
53
54
55
// Fuier DS18B20
56
57
58
void setup()
59
{
60
    wdt_enable(WDTO_4S);
61
  pinMode(LED_ROT,OUTPUT);
62
  pinMode(UB_PIN,INPUT);
63
  digitalWrite(UB_PIN,0);
64
  pinMode(LED_GLB,OUTPUT);
65
66
  digitalWrite(LED_GLB,0);
67
  digitalWrite(LED_ROT,0);
68
69
  delay(250);
70
  digitalWrite(LED_GLB,1);  
71
  digitalWrite(LED_ROT,1); 
72
  delay(800);
73
  digitalWrite(LED_GLB,0);  
74
  digitalWrite(LED_ROT,0); 
75
  analogReference(INTERNAL);
76
  /* ----- DS18B20 ------- */
77
78
  dht.begin();
79
  sensors.begin();
80
  /* Ist T Sensor vorhanden ? */
81
  if (!sensors.isConnected(devAdr)) {
82
         digitalWrite(LED_ROT,1);  
83
      while(1) wdt_reset();
84
  }
85
  
86
  /* 12 Bit Auflösung setzen */
87
  sensors.setResolution(devAdr,12);
88
  
89
  /* ----- RF24 Modul TX einstellen ---- */
90
  SPI.begin();
91
  SPI.setClockDivider(SPI_CLOCK_DIV8);
92
  radio.begin();
93
  
94
  /* Chip Version prüfen */
95
  if (!radio.isPVariant()) {
96
    digitalWrite(LED_GLB,1);  
97
    digitalWrite(LED_ROT,1);  
98
    while(1) wdt_reset();
99
  }  
100
  
101
  radio.setAutoAck(true);        // Auto ACK
102
  radio.setDataRate(RF24_250KBPS);  // 250kbs  
103
  radio.setPALevel(RF24_PA_MAX);    // Minimale Sendeleistung
104
  radio.setChannel(RF_CHANNEL);    
105
  radio.enableDynamicPayloads();    // Dynamische Payload Size aktivieren
106
  //radio.setPayloadSize(sizeof(data)); 
107
  radio.setRetries(15,15);      // 4ms Pause, 5 Wiederholungen
108
  radio.setCRCLength(RF24_CRC_16);  // 16 Bit CRC
109
  radio.openWritingPipe(TXADDRESS);
110
  
111
  set_wdt_isr();
112
  
113
  /* Struct mit Default Werten füllen */
114
  data.nr = 0;
115
  data.id = 0xabcd;
116
  data.ubatt   = 2.4;
117
118
}
119
120
void loop ()
121
{
122
  radio.openWritingPipe(TXADDRESS);
123
124
  data.ubatt      = 0.0033203125 * (float)analogRead(UB_PIN);
125
  pinMode(UB_PIN,INPUT);
126
127
  if (data.ubatt > 2.0) {
128
    sensors.requestTemperatures();
129
    data.temperatur_1   = sensors.getTempC(devAdr);
130
    data.temperatur_2   = dht.readTemperature();
131
    data.feuchte  = dht.readHumidity();
132
  }        
133
  
134
  radio.powerUp();
135
  
136
  /* Datensatz senden an die Basisstation */
137
  if (radio.write(&data,sizeof(data))) {
138
    digitalWrite(LED_GLB,1);
139
    delay(80);
140
    
141
  } else {
142
      digitalWrite(LED_ROT,1);
143
      delay(80);
144
      digitalWrite(LED_ROT,0);
145
      
146
  }
147
  digitalWrite(LED_GLB,0);
148
  digitalWrite(LED_GLB,0);
149
  radio.powerDown();
150
    
151
  data.nr++;
152
  sleep_n_sec(4);
153
154
}

von Markus (Gast)


Lesenswert?

>Ein nRF51822 Evalboard habe ich noch vor kurzem ausprobiert, das ist ja
>ein Cortex-M0 mit eingebautem nRF24

Ist das wirklich so? Könnte man dann den BLE-Stack umgehen und eine 
eigenes Protokoll fahren, dass man mit einem NRF24 am Arduino 
kommunizieren kann?

von Johannes S. (Gast)


Lesenswert?

Markus schrieb:
> Ist das wirklich so? Könnte man dann den BLE-Stack umgehen und eine
> eigenes Protokoll fahren, dass man mit einem NRF24 am Arduino
> kommunizieren kann?

'nRF24L compatible' sagt zumindest die Produktinfo von Nordic:
https://www.nordicsemi.com/eng/Products/Bluetooth-low-energy/nRF51822

Das BLE wird als 'softdevice' implementiert, quasi eine Firmware die den 
Stack enthält. Die Quellen kosten Geld, aber es gibt vorkompilierte 
Pakete und so wird das auch in mbed benutzt. Man muss für BLE zu seiner 
App ein .hex file laden das zuerst die Kontrolle bekommt und dann zur 
eigenen App springt.
Ich vermute das softdevice kann man auch weglassen und dann eine eigene 
Kommunikation bauen. Dafür muss man aber die Datenblätter von dem Ding 
studieren, soweit bin ich da nicht drin. Bei Nordic kann man vieles frei 
herunterladen, auch ein SDK.

Gips1Gott schrieb:
> Kann ich bei Fragen mich bei
> dir melden?

Frag hier im Forum, da gibt es Leute die mehr Erfahrung mit dem nRF 
haben. Mich interessiert das Thema BLE weil das mit dem Smartphone 
sprechen kann. Zum Beispiel kann man einen eigenen HRM (heart rate 
monitor) fürs Ergometer bauen der dann mit Standard Smartphone Apps 
quatscht.

von Robert S. (gips1gott)


Lesenswert?

Johannes S. schrieb:
> ich hatte dafür mal diese Lib benutzt und es hatte funktioniert:
> https://os.mbed.com/users/Owen/code/nRF24L01P/
> Das Projekt liegt aber hier schon länger auf Eis.

Moin,

ich habe jetzt sehr lange versucht diese Bibliothek zu nutzen. Leider 
ist es so, dass mein Controller bei my_nrf24l01p.powerUp() hängen 
bleibt. Ich habe jetzt bereits alle Register mit der funktionierenden 
Arduino Bib abgeglichen und weiß nicht mehr weiter.

Fällt euch etwas auf? Arbeite mit dem Nucleo L476RG.

Mein Code:
1
#include "mbed.h"
2
#include "nRF24L01P.h"
3
4
Serial pc(USBTX, USBRX,9600); // tx, rx
5
6
nRF24L01P my_nrf24l01p(D11, D12, D13, D10, D9, D7);    // mosi, miso, sck, csn, ce, irq
7
8
DigitalOut myled1(LED1);
9
DigitalOut myled2(LED2);
10
11
int main() {
12
13
// The nRF24L01+ supports transfers from 1 to 32 bytes, but Sparkfun's
14
//  "Nordic Serial Interface Board" (http://www.sparkfun.com/products/9019)
15
//  only handles 4 byte transfers in the ATMega code.
16
#define TRANSFER_SIZE   4
17
18
    char txData[TRANSFER_SIZE], rxData[TRANSFER_SIZE];
19
    int txDataCnt = 0;
20
    int rxDataCnt = 0;
21
    pc.printf("Setup");
22
23
    my_nrf24l01p.powerUp();
24
    
25
    // Display the (default) setup of the nRF24L01+ chip
26
    pc.printf( "nRF24L01+ Frequency    : %d MHz\r\n",  my_nrf24l01p.getRfFrequency() );
27
    pc.printf("Receive");
28
    pc.printf( "nRF24L01+ Output power : %d dBm\r\n",  my_nrf24l01p.getRfOutputPower() );
29
    pc.printf( "nRF24L01+ Data Rate    : %d kbps\r\n", my_nrf24l01p.getAirDataRate() );
30
    pc.printf( "nRF24L01+ TX Address   : 0x%010llX\r\n", my_nrf24l01p.getTxAddress() );
31
    pc.printf( "nRF24L01+ RX Address   : 0x%010llX\r\n", my_nrf24l01p.getRxAddress() );
32
33
    pc.printf( "Type keys to test transfers:\r\n  (transfers are grouped into %d characters)\r\n", TRANSFER_SIZE );
34
35
    //my_nrf24l01p.setTransferSize( TRANSFER_SIZE );
36
37
    my_nrf24l01p.setReceiveMode();
38
    pc.printf("Receive");
39
    my_nrf24l01p.enable();
40
41
    while (1) {
42
43
        // If we've received anything in the nRF24L01+...
44
        pc.printf("while");
45
        if ( my_nrf24l01p.readable() ) {
46
47
            // ...read the data into the receive buffer
48
            rxDataCnt = my_nrf24l01p.read( NRF24L01P_PIPE_P0, rxData, sizeof( rxData ) );
49
50
            // Display the receive buffer contents via the host serial link
51
            for ( int i = 0; rxDataCnt > 0; rxDataCnt--, i++ ) {
52
53
                pc.putc( rxData[i] );
54
            }
55
56
            // Toggle LED2 (to help debug nRF24L01+ -> Host communication)
57
            myled2 = !myled2;
58
        }
59
    }
60
}

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.