Edit: Solution For the curious, the problem all along was just that the 3.3v supply pins on the RPi can’t source enough current to properly drive the RF24+. I switched the RF24 to using an external power supply (itself powered by an RPi USB port) and it started working immediately.
TL;DR: Are there any specific “gotcha’s” when using this radio to communicate between a Pi (3B+) and an Arduino, vs between multiple Arduinos? With Nanos acting as transmitters, the exact same code works fine on the Uno but not on the Pi.
Long version: I have a pile of Arduino’s here (9 LAFVIN Nanos and an Elegoo Uno R3), and a single Canakit Raspberry Pi 3B+. I also have a handful of nRF24L01+ radios – authentic devices from Makerfire, not clones.
I have two Nanos setup with RF24s sending sensor data once a second, and the Uno running a sketch that displays the received data and displays it on the 16x2 LCD, along with a count of how many messages it’s received from each device. This has been working flawlessly for a few days now. All of the devices are setup with the same address, and using pipe 0. The init code on all three of them is identical:
radio.begin();
radio.setPALevel(RF24_PA_LOW); // power level
radio.setChannel(RF_CHANNEL);
radio.setDataRate(RF_RATE);
radio.openWritingPipe(address);
radio.openReadingPipe(0, address);
radio.startListening();
The Nanos simply sleep for a second then turn on an LED, read their sensor data, send it with radio.write(data, size, true), then turn off their LED. The Uno sits in a loop simply checking radio.available(), and reading and printing the data when it’s available. It doesn’t send anything, at least not by my instruction. I only recently found out about the ACK/Multicast option.
Again, let me reiterate, that the above works perfectly for tens of thousands of messages with no issues, transmitting from the Nanos to the Uno. However, taking exactly the same code and compiling and running it on my Pi results in no messages being received. At first I thought this was due to the ACK thing, once I found out about that, so I turned off the Uno (which was still logging messages) and restarted the Pi, to no avail.
Eventually I found that even though both systems are using the same library (tmrh20 v1.3.4), the Pi’s radio.begin() apparently issues a different setup command than the one used on the Arduinos. For example, all the Arduino radios were initialized to channel 76 (before I added the call to setChannel()) while the Pi was initialized to channel 0 according to the information from radio.printDetails() which you can see here:
================ SPI Configuration ================
CSN Pin = CE0 (PI Hardware Driven)
CE Pin = Custom GPIO17
Clock Speed = 8 Mhz
================ NRF Configuration ================
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x0504030201 0xc2c2c2c2c2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x0504030201
RX_PW_P0-6 = 0x20 0x00 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x03
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_LOW
This a full sketch for the Nano doing temperature sensing (I have different sensors on different Nanos):
#include <SPI.h>
#include <RF24.h>
#include <DHT.h>
#define DHT_TYPE DHT11
#define PIN_DHT 2
#define PIN_CE 3
#define PIN_CSN 4
#define PIN_LED 5 // tx LED
typedef enum {
UNK,
UNK_F,
UNK_L,
UNK_UL,
SENS_TEMP,
SENS_ACCEL,
SENS_WLEVEL
} SensorType;
typedef struct SensorReports {
uint8_t address[5];
unsigned int battery_level;
unsigned int voltage;
SensorType sensor_type;
union {
unsigned long data_ul;
long data_l;
float data_f;
};
} SensorReport;
uint8_t address[] = {0x01, 0x02, 0x03, 0x04, 0x05};
RF24 radio(PIN_CE, PIN_CSN);
DHT dht(PIN_DHT, DHT_TYPE);
void copy(uint8_t* src, uint8_t* dst, int len) {
memcpy(dst, src, sizeof(src[0])*len);
}
void setup() {
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
dht.begin();
radio.begin();
radio.setPALevel(RF24_PA_LOW); // power level
radio.openWritingPipe(address);
radio.openReadingPipe(0, address);
radio.startListening();
}
void loop() {
SensorReport report;
// float temp = dht.readTemperature(false);
copy(address, report.address, 5);
report.battery_level = 0;
report.voltage = 0;
report.sensor_type = SENS_TEMP;
report.data_f = dht.readTemperature(false);
digitalWrite(PIN_LED, HIGH);
radio.stopListening();
radio.write(&report, sizeof(SensorReport), true);
radio.startListening();
digitalWrite(PIN_LED, LOW);
delay(1000);
}
And the server code:
#include <stdlib.h>
#include <RF24/RF24.h>
#define PIN_CE RPI_BPLUS_GPIO_J8_11
#define PIN_CSN RPI_BPLUS_GPIO_J8_24
#define RF_CHANNEL 76
#define RF_RATE RF24_1MBPS
typedef enum {
UNK,
UNK_F,
UNK_L,
UNK_UL,
SENS_TEMP,
SENS_ACCEL,
SENS_WLEVEL
} SensorType;
typedef struct SensorReports {
uint8_t address[5];
unsigned int battery_level;
unsigned int voltage;
SensorType sensor_type;
union {
unsigned long data_ul;
long data_l;
float data_f;
};
} SensorReport;
RF24 radio(PIN_CE, PIN_CSN);
uint8_t address[] = {0x01, 0x02, 0x03, 0x04, 0x05};
int main(int argc, char** argv)
{
SensorReport report;
unsigned long rxcounter1 = 0;
unsigned long rxcounter2 = 0;
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.setChannel(RF_CHANNEL);
radio.setDataRate(RF_RATE);
radio.openWritingPipe(address);
radio.openReadingPipe(0, address);
radio.printDetails();
radio.startListening();
if (!radio.isChipConnected()) {
printf("No chip!\n");
return 0;
}
printf("Entering listening loop\n");
while(1) {
while (radio.available()) {
radio.read(&report, sizeof(SensorReport));
printf("Got message (%d)\n", report.sensor_type);
switch (report.sensor_type) {
case SENS_TEMP:
rxcounter1++;
printf("%.1f (%lu)\n", report.data_f, rxcounter1);
break;
case SENS_WLEVEL:
rxcounter2++;
printf("%luW (%lu)\n", report.data_ul, rxcounter2);
break;
}
}
delay(250);
}
return 0;
}
This server code works perfectly on the Uno, replacing the printf’s with console logs or prints to the LCD, but when running on the Pi, it seems to never receive any messages. Any help on why the Pi is behaving differently from the Uno would be appreciated!