nRF24 / RF24Network

OSI Layer 3 Networking for nRF24L01(+) and nRF52x on Arduino and Raspberry Pi
https://nrf24.github.io/RF24Network/
GNU General Public License v2.0
355 stars 164 forks source link

Nano 33 family not working properly #189

Closed amad3v closed 2 years ago

amad3v commented 2 years ago

Hi guys,

I'm trying to establish a network between nano 33 IoT and nano 33 BLE through nRF24L01P with the following configuration on both boards:

CE → D9
CSN → D10
SCK → D13
MOSI → D11
MISO → D12

The scanner sketch works fine and both boards read FFF at the selected channel (+/-1).

If I use the BLE as a receiver (address 000), the IoT outputs Sending...ok. but the BLE doesn't diplay anything. Switching the roles (IoT becomes the receiver), BLE outputs Sending...ok. and the IoT displays random data without the set delay:

Received packet #536871157 at 663627
...
Received packet #1627390464 at 8520
...
Received packet #1627390464 at 8446
...
Received packet #1627390464 at 8520
...
Received packet #0 at 4294967168
...
Received packet #0 at 666887
...
Received packet #0 at 667031
...
Received packet #536871157 at 667128
...

The same code and configuration on 2 Arduino UNO works fine:

Received packet #33 at 68000
Received packet #34 at 70000
Received packet #35 at 72000
Received packet #36 at 74000
Received packet #37 at 76000
Received packet #38 at 78000
Received packet #39 at 80000
Received packet #40 at 82000
Received packet #41 at 84000
Received packet #42 at 86000
Received packet #43 at 88000
Received packet #44 at 90000

The provided examples (helloworld_rx.ino and helloworld_tx.ino) are used

sketch:

#include <Arduino.h>
#include <SPI.h>
#include <RF24.h>
#include <RF24Network.h>

#define NETWORK_CHANNEL 0x64

RF24 radio( 9, 10 ); // nRF24L01(+) radio attached using Getting Started board

RF24Network network( radio ); // Network uses that radio
// #ifdef ARDUINO_ARDUINO_NANO33BLE
#ifdef ARDUINO_SAMD_NANO_33_IOT
const uint16_t this_node  = 000; // Address of our node in Octal format (04, 031, etc)
const uint16_t other_node = 001; // Address of the other node in Octal format
#else
const uint16_t this_node  = 001; // Address of our node in Octal format
const uint16_t other_node = 000; // Address of the other node in Octal format

const unsigned long interval = 2000; // How often (in ms) to send 'hello world' to the other unit

unsigned long last_sent;    // When did we last send?
unsigned long packets_sent; // How many have we sent already
#endif

struct payload_t { // Structure of our payload
    unsigned long ms;
    unsigned long counter;
};

void setup( void ) {
    Serial.begin( 115200 );
    if ( !Serial ) {
        // some boards need this because of native USB capability
    }
// #ifdef ARDUINO_ARDUINO_NANO33BLE
#ifdef ARDUINO_SAMD_NANO_33_IOT
    Serial.println( ( "RF24Network/examples/helloworld_rx/" ) );
#else
    Serial.println( ( "RF24Network/examples/helloworld_tx/" ) );
#endif

    SPI.begin();
    if ( !radio.begin() ) {
        Serial.println( ( "Radio hardware not responding!" ) );
        while ( 1 ) {
            // hold in infinite loop
        }
    }
    network.begin( /*channel*/ NETWORK_CHANNEL, /*node address*/ this_node );
}

void loop( void ) {

    network.update(); // Check the network regularly
// #ifdef ARDUINO_ARDUINO_NANO33BLE
#ifdef ARDUINO_SAMD_NANO_33_IOT
    while ( network.available() ) { // Is there anything ready for us?

        RF24NetworkHeader header; // If so, grab it and print it out
        payload_t         payload;
        network.read( header, &payload, sizeof( payload ) );
        Serial.print( "Received packet #" );
        Serial.print( payload.counter );
        Serial.print( " at " );
        Serial.println( payload.ms );
    }
#else
    unsigned long now = millis();

    // If it's time to send a message, send it!
    if ( now - last_sent >= interval ) {
        last_sent = now;

        Serial.print( "Sending..." );
        payload_t         payload = { millis(), packets_sent++ };
        RF24NetworkHeader header( /*to node*/ other_node );
        bool              ok = network.write( header, &payload, sizeof( payload ) );
        if ( ok )
            Serial.println( "ok." );
        else
            Serial.println( "failed." );
    }
#endif
}

Any suggestions?

Thank you!

2bndy5 commented 2 years ago

My first guess: The nano 33 BLE has a faulty SPI connnection. Try slowing down the SPI speed

RF24 radio(9, 10, 4000000); // uses 4MHz instead of default 10MHz

Did you first try any RF24 lib examples? The scanner sketch is more of a tool than an example. I have to ask as my suggestion doesn't involve RF24Network library, and doing so would help narrow down the problem.

amad3v commented 2 years ago

Thank you @2bndy5 You nailed it 👍🏼 💯 , slowing down the SPI speed solved the issue.

If you don't mind me asking. When you say "has a faulty SPI connection", do you mean internal to the BLE? and why slowing down the SPI speed solves the issue? I'd like to understand what's going on 🤔

2bndy5 commented 2 years ago

Some boards have a high impedance on certain data buses. In such cases, the high-to-low (& low-to-high) transitions on the MOSI/MISO/SCK lines may not be recognizable by the time the pulses reach the radio (or when they are returned to the board). This failure to interpret pulses results in corrupted data (AKA misinterpreted data) going to/from the radio's SPI connections. Some boards' data buses are just extremely sensitive in terms of identifying pulses from noisy power spikes.

Using short wires or pull-up resistors may help (no guarantee from me - please be cautious with pull-up resistors).

IIRC, you aren't the first person that reported this problematic experience with the Nano 33 BLE board.

2bndy5 commented 2 years ago

why slowing down the SPI speed solves the issue?

Sorry, I completely forgot to answer this. By slowing down the SPI speed, we can better serve a series of pulses that are more easily interpreted. And that's about as technical as I can get in this context.

amad3v commented 2 years ago

That was more than enough. Thank you once again!