jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.48k stars 372 forks source link

nRF24 support for SAMD21 #189

Closed javilesm closed 3 years ago

javilesm commented 3 years ago

Hello, you have a nice work many thanks.

The issue I'm facing is with the SAMD21 architectures, for AVR like Arduino nano the library is working very good but when moving the code to Arduino NANO 33 IoT it just doesn't work, the serial output is -> [nRF24] Initializing ... failed, code -16 The project is a simple Rx based on NRF24, the slave or the receiver is Arduino NANO 33 IoT stacked on Arduino Nano I/O shield.

Sketch that is causing the module fail

// sketch is based on example nRF24_Receive.ino

#include <RadioLib.h>

// nRF24 has the following connections:
// CS pin:    10
// IRQ pin:   2
// CE pin:    9
// i am routing CE pin to 9 due to nano I/O shield, see details in hdw setup section
nRF24 radio = new Module(10,2,9);

void setup() {
  Serial.begin(9600);
  // i added function while since serial had no output
  while(!Serial);
  // initialize nRF24 with default settings
  Serial.print(F("[nRF24] Initializing ... "));
  int state = radio.begin();
  if(state == ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while(true);
  }

  // set receive pipe 0 address
  // NOTE: address width in bytes MUST be equal to the
  //       width set in begin() or setAddressWidth()
  //       methods (5 by default)
  Serial.print(F("[nRF24] Setting address for receive pipe 0 ... "));
  byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89};

  state = radio.setReceivePipe(0, addr);
  if(state == ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while(true);
  }
}

void loop() {
  Serial.print(F("[nRF24] Waiting for incoming transmission ... "));

  // you can receive data as an Arduino String
  // NOTE: receive() is a blocking method!
  //       See example ReceiveInterrupt for details
  //       on non-blocking reception method.
  String str;
  int state = radio.receive(str);

  // you can also receive data as byte array
  /*
    byte byteArr[8];
    int state = radio.receive(byteArr, 8);
  */

  if (state == ERR_NONE) {
    // packet was successfully received
    Serial.println(F("success!"));

    // print the data of the packet
    Serial.print(F("[nRF24] Data:\t\t"));
    Serial.println(str);

  } else if (state == ERR_RX_TIMEOUT) {
    // timeout occurred while waiting for a packet
    Serial.println(F("timeout!"));

  } else {
    // some other error occurred
    Serial.print(F("failed, code "));
    Serial.println(state);

  }
}

Hardware setup

Debug mode output

18:50:34.358 -> R   0   0   
18:50:34.358 -> R   0   0   
18:50:34.358 -> R   0   0   
18:50:34.358 -> R   0   0   
18:50:34.358 -> R   0   0   
18:50:34.358 -> 
18:50:34.358 -> address:    0x0
18:50:34.358 -> bits:       3 2
18:50:34.358 -> value:      0b1100
18:50:34.358 -> current:    0b0
18:50:34.358 -> mask:       0b1100
18:50:34.358 -> new:        0b1100
18:50:34.358 -> read:       0b0
18:50:34.358 -> 
18:50:34.358 -> failed, code -16

Additional info (please complete):

jgromes commented 3 years ago

There's an important difference between Arduino Nano (the one with ATmega328P) and Arduino Nano 33 IoT - Nano 33 IoT is a 3.3V device. The shield you're using assumes you have a 5 V logic device, take a look at the schematic:

Screenshot_1

You'll notice resistor voltage dividers on CE, SCK, NSS and MOSI. These will half the voltage level of signals incoming from the Arduino Nano. So if you're using a 5V Arduino Nano, the signals you're sending to nRF24 will be 2.5 V (seems like nRF24 is able to handle that - haven't checked the datasheet though). However, if you use Nano 33 IoT, the voltage level will be only 1.65 V.

Bottom line is: that shield isn't compatible with Nano 33 IoT. You can either wire the nRF24 directly to you Nano, or desolder all the resistors shown above (R5 - R12) and replace R5 - R8 with 0R resistors, or just a blob of solder.

javilesm commented 3 years ago

Hi guys,

Thanks a lot for your support, I already applied the suggested fixes by taking off the shield but there is no message reception.

Sketch that is causing the module fail

// project: simple Rx based on NRF24 the slave or the receiver is Arduino NANO 33 IoT. .

#include <RadioLib.h>

// nRF24 has the following connections:
// CS pin:    10
// IRQ pin:   2
// CE pin:    9

nRF24 radio = new Module(10,2,9);

void setup() {
  Serial.begin(9600);
  // initialize nRF24 with default settings
  Serial.print(F("[nRF24] Initializing ... "));
  int state = radio.begin();
  if(state == ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while(true);
  }

  // set receive pipe 0 address
  // NOTE: address width in bytes MUST be equal to the
  //       width set in begin() or setAddressWidth()
  //       methods (5 by default)
  Serial.print(F("[nRF24] Setting address for receive pipe 0 ... "));
  byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89};

  state = radio.setReceivePipe(0, addr);
  if(state == ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while(true);
  }
}

void loop() {
  Serial.print(F("[nRF24] Waiting for incoming transmission ... "));

  // you can receive data as an Arduino String
  // NOTE: receive() is a blocking method!
  //       See example ReceiveInterrupt for details
  //       on non-blocking reception method.
  String str;
  int state = radio.receive(str);

  // you can also receive data as byte array
  /*
    byte byteArr[8];
    int state = radio.receive(byteArr, 8);
  */

  if (state == ERR_NONE) {
    // packet was successfully received
    Serial.println(F("success!"));

    // print the data of the packet
    Serial.print(F("[nRF24] Data:\t\t"));
    Serial.println(str);

  } else if (state == ERR_RX_TIMEOUT) {
    // timeout occurred while waiting for a packet
    Serial.println(F("timeout!"));

  } else {
    // some other error occurred
    Serial.print(F("failed, code "));
    Serial.println(state);

  }
}

Hardware setup

Debug mode output

12:43:29.972 -> 
12:43:29.972 -> address:    0x7
12:43:29.972 -> bits:       6 4
12:43:29.972 -> value:      0b1110000
12:43:29.972 -> current:    0b1110
12:43:29.972 -> mask:       0b1110000
12:43:29.972 -> new:        0b1111110
12:43:29.972 -> read:       0b1110
12:43:29.972 -> 
12:43:29.972 -> R   0   3F  
12:43:29.972 -> W   0   7F  
12:43:29.972 -> R   0   7F  
12:43:29.972 -> timeout!
12:43:29.972 -> [nRF24] Waiting for incoming transmission ... R 6   3   
12:43:29.972 -> W   6   3   
12:43:29.972 -> R   6   3   
12:43:29.972 -> R   6   3   
12:43:29.972 -> W   6   3   
12:43:29.972 -> R   6   3   
12:43:29.972 -> R   0   7F  
12:43:29.972 -> W   0   7F  
12:43:29.972 -> R   0   7F  
12:43:29.972 -> R   0   7F  
12:43:29.972 -> W   0   7F  
12:43:29.972 -> R   0   7F  
12:43:29.972 -> R   7   E   
12:43:29.972 -> W   7   7E  
12:43:29.972 -> R   7   E   
12:43:29.972 -> R   7   E   
12:43:29.972 -> R   7   E   
12:43:29.972 -> R   7   E   
12:43:29.972 -> R   7   E   
12:43:29.972 -> R   7   E   
12:43:30.006 -> 

photo_2020-10-19_12-59-02

jgromes commented 3 years ago

I can't really tell anything from that photo.

Please post the complete debug mode output, starting from the initialization. Also, you have only posted the receiver sketch - what are you using as transmitter?

javilesm commented 3 years ago

I just added a 10uF capacitor between GND and VCC and wired to NANO 33 with jumpers, now it is working without issues. I will close the issue, thanks a lot for your support.