Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatibility with Arduino NANO 33 BLE. #739

Closed
TonioChingon opened this issue Feb 28, 2021 · 11 comments · Fixed by #750
Closed

Incompatibility with Arduino NANO 33 BLE. #739

TonioChingon opened this issue Feb 28, 2021 · 11 comments · Fixed by #750

Comments

@TonioChingon
Copy link

Hi,

this is a great library!
There is however some incompatibility with the Arduino Nano 33 BLE (based on mbed OS).

I have the following setup:

  1. NRF24L01+ as transmitter with an Arduino Nano 33 BLE Sense
  2. NRF24L01+ as receiever with an Arduino Nano 33 BLE
  3. NRF24L01+ as receiever with an Arduino Uno

I am not able to receive any data on the Radio 2, transmission works well as data is received in Radio 3.

In order to debug the code, I tried to use printDetails and printf_P. Unfortunately they did not print any information.

After some research, I was able to make it work by inserting at line 27 of printf.h the following (see line 44 in https://github.com/arduino/ArduinoCore-mbed/blob/8564c3a97f9a2f74a54f3952ddd9a0516da22add/cores/arduino/macros.h):

#elif defined(ARDUINO_ARCH_MBED)
REDIRECT_STDOUT_TO(Serial);
#endif

Original code of printf.h:

RF24/printf.h

Lines 20 to 28 in 2af44fc

#if defined(ARDUINO_ARCH_AVR) || defined(__ARDUINO_X86__)
int serial_putc(char c, FILE *)
{
Serial.write(c);
return c;
}
#endif

Unfortunately, I did not figure it out how to insert it inside printf_begin().

I was able to perform the debugging, but with no success, i.e. I am still not able to receive data with Radio 2.
The Radios 2 and 3 seem to behave exactly the same during setup commands, however at the time of reading the data, there is no available data in Radio 2. The tests were carried out while Radio 2 and 3 were both on and only either of them was on.

Any thoughts? I will keep trying.

PS. I was debugging library v.1.3.11 but today I made the update to 1.3.12 also with no success (but no debugging).

@TMRh20
Copy link
Member

TMRh20 commented Feb 28, 2021

As far as I know the library is working with the Nano 33, so it would likely be a hardware or coding issue, especially since it is working as transmitter, just not receiving.

Can you show the output of printDetails? Are you using the included examples to test? (same code on radio 2 and 3?)

@2bndy5
Copy link
Member

2bndy5 commented Feb 28, 2021

This is going to sound ironic, but the Nano 33 BLE uses a nRF52840 as its CPU which internally employs a cortex M4 (maybe a SAMD -- going off of memory here) for user-code execution. I'm not too surprised that printf.h isn't working on this platform given #414 , but all that only addresses why you can't get debugging info printed to Serial.

The real problem is why your project isn't working, but it would be easier to address this if we see your code. If posting your code publicly is prohibited, then I would go with TMRh20's suggestion and load up a library example (gettingStarted.ino seems the most applicable) and test only a pair of radios at a time (the examples aren't written for transmitting to 2 RX nodes).

@TonioChingon
Copy link
Author

TonioChingon commented Mar 1, 2021

Hi @TMRh20 and @2bndy5,

first of all, thanks a lot for you reply and the good news, that the library should work well with the Nano 33 BLE.
There must be a problem on my side.

I have discarted a HW problem, as a I switched the NRFL2401+ boards among the Arduinos and the problem persists.
I started with the example "gettingStarted.ino" and then I simplify it to test it.

The Arduino Uno can send/receive with no problem.
But the Arduino Nano 33 BLE seems to only be able to send data.

These are the codes:

Sender (Arduino Nano 33 BLE)

//SENDER
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include "printf.h"

RF24 radio(9, 10);                // CE, CSN         
const byte address[6] = "fffff";  //Address. This should be same on the receiving side.
bool flag = false;

void setup() {
  Serial.begin(9600);
  while(!Serial);
  delay(1000);
  Serial.println("Lets go Sender");
  printf_begin();                       //needed only for Arduino Uno
  
  flag = radio.begin();
  Serial.print("radio.begin(): ");
  Serial.println(flag);
  radio.printDetails();          
  radio.printPrettyDetails(); 

  radio.setDataRate(RF24_250KBPS);
  Serial.print("radio.setDataRate(RF24_250KBPS): ");
  Serial.println(flag);
  radio.printDetails();          
  radio.printPrettyDetails();

  radio.openWritingPipe(address);       //Setting the address where we will send the data
  Serial.println("radio.setDataRate(RF24_250KBPS): ");
  radio.printDetails();          
  radio.printPrettyDetails(); 
  
  radio.setPALevel(RF24_PA_MAX);         //You can set it as minimum or maximum depending on the distance between the transmitter and receiver.
  Serial.println("radio.setPALevel(RF24_PA_MAX): ");
  radio.printDetails();          
  radio.printPrettyDetails();

  radio.stopListening();                //This sets the module as transmitter
  Serial.println("radio.stopListening(): ");
  radio.printDetails();          
  radio.printPrettyDetails();
  }

void loop(){
  const char text[] = "Hello there...";
  radio.write(&text, sizeof(text));                  //Sending the message to receiver

  delay(1200);
}

Receiver (Arduino Nano 33 BLE and/or Arduino Uno)

//RECEIVER
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include "printf.h"

RF24 radio(9, 10);                // CE, CSN         
const byte address[6] = "ffff";  //Address. This should be same on the trasmission side.
bool flag = false;

void setup() {
  Serial.begin(9600);
  while(!Serial);
  delay(1000);
  Serial.println("Lets go Receiver");
  printf_begin();                   //needed only for Arduino Uno
  
  flag = radio.begin();
  Serial.print("radio.begin(): ");
  Serial.println(flag);
  radio.printDetails();          
  radio.printPrettyDetails(); 

  flag = radio.setDataRate(RF24_250KBPS);
  Serial.print("radio.setDataRate(RF24_250KBPS): ");
  Serial.println(flag);
  radio.printDetails();          
  radio.printPrettyDetails();

  radio.openReadingPipe(1, address);  //Setting the address at which we will receive the data
  Serial.println("radio.setDataRate(RF24_250KBPS): ");
  radio.printDetails();          
  radio.printPrettyDetails(); 
  
  radio.setPALevel(RF24_PA_MAX);       //You can set this as minimum or maximum depending on the distance between the transmitter and receiver.
  Serial.println("radio.setPALevel(RF24_PA_MAX): ");
  radio.printDetails();          
  radio.printPrettyDetails(); 
  
  radio.startListening();              //This sets the module as receiver
  Serial.println("radio.startListening(): ");
  radio.printDetails();          
  radio.printPrettyDetails();
  }
  
void loop(){
  uint8_t pipe;
  bool goodSignal;
  char payload[50] = "";                      //Saving the incoming data
  uint8_t bytes;
  Serial.println("----------------------------");
  
  if (radio.available(&pipe)){                   //Looking for the data.
    
    bytes = radio.getPayloadSize();         // get the size of the payload
    radio.read(&payload, bytes);            // fetch payload from FIFO
    
    Serial.println("Data Received.");
    Serial.print("Bytes: ");
    Serial.println(bytes);                    // print the size of the payload
    Serial.print("Pipe: ");
    Serial.println(pipe);                     // print the pipe number
    Serial.print("Data: ");
    Serial.println(payload);                // print the payload's value
  }else{
    Serial.println("Data is not available.");
    }
  
  flag = radio.testRPD();
  Serial.print("radio.testRPD(): ");
  Serial.println(flag);

  flag = radio.isChipConnected();
  Serial.print("radio.isChipConnected(): ");
  Serial.println(flag);

  flag = digitalRead(9);
  Serial.print("CE: ");
  Serial.println(flag);
  delay(500);

  radio.printPrettyDetails();
  
  }

Below you can find the output of the Serial Monitor. Only the information inside of the "loops" is displayed.

Sender (Arduino Nano 33 BLE) Working
grafik

Receiver (Arduino Uno) Working
grafik

Receiver (Arduino Nano 33 BLE) Not working

grafik

The following can be observed:

Receiver side:

  • The CONFIG register is configured correctly, i.e. PWR_UP and PRIM_RX are both active.
  • The Pin CE is active.
  • Auto-ACK is enabled.
  • Pipe 1 is open and has address: 0x6666666666

Sender side.

  • Pipe 0 is open and has address: 0x6666666666

The sender works fine, as the module connected to the Arduino Uno is displaying the data in the serial monitor.
But both receivers have the same configuration (marked in blue) but only the Arduino Uno is able to receive the data.

What I have tried:

  • Different NRF24L01+ modules.
  • Different addresses and pipes.
  • Different transmission speeds.
  • Disabling the auto-acknoweledgment.
  • Different messages.

PS1. Only 2 ouf 3 systems are powered while the test occurs (Nano 33 BLE and Uno, or two Nano 33 BLE's).
PS2. I happened to find a thread (https://forum.arduino.cc/index.php?topic=467810.0), where a very similar issue was discussed but with an Arduino MEGA, no solution was found. I will test the code also with a MEGA and post later my findings.
PS3. I inserted 2 lines of code in the method RF24::available(...) to print the CONFIG and STATUS registers while checking if data is available in the receiver.. The problem is still there without this modification, also without the modification to printf.h of my first post.

bool RF24::available(uint8_t* pipe_num)
{
    // get implied RX FIFO empty flag from status byte
	print_byte_register(PSTR("CONFIG\t"), NRF_CONFIG);
	print_status(get_status());
    uint8_t pipe = (get_status() >> RX_P_NO) & 0x07;
    if (pipe > 5)
        return 0;

    // If the caller wants the pipe number, include that
    if (pipe_num)
        *pipe_num = pipe;

    return 1;
}

Best regards,

Tonio

@2bndy5
Copy link
Member

2bndy5 commented Mar 1, 2021

Only 2 ouf 3 systems are powered while the test occurs (Nano 33 BLE and Uno, or two Nano 33 BLE's).

To power off a radio, do you disconnect the usb cable (and whatever the radio's VCC pin is supplied with)? Or do you call radio.powerDown()?

Just trying to eliminate the possibility that the payload is intercepted.

I don't often get to say this, but you've got me stumped. print*Details() output looks as it should, RX operation doesn't require the same current consumption (at least when not sending an ACK packet) as TX operation requires, and even the RPD flag is not getting asserted (as it should when detecting any signal on that channel & data rate).

If you run the scanner example (found in "examples/old_backups" folder) and no signals are detected, then I would think the radio module is defective (especially in the presence of WiFi/Bluetooth).

@TonioChingon
Copy link
Author

Hi,
To disconnect a radio, I am unplugging the Arduino from the usb voltage source.

Sometimes the RPD flag gets active, but very rarely.

This is the output of the scanner example. It seems that the default channel (0x4C) is not being affected by noise.
I tried few other channels and it did not work (great Scanner example, btw).

grafik

Btw, I tried the same NRF24L01+ module with an Arduino DUE and it worked perfectly.

Some brainstorming...

  • Could it be a timing issue? Since the Uno and the Nano 33 BLE run at different clock speeds, there might be a factor in the .h files that is causing the trouble?
  • The Uno has a 5V logic whereas the Nano 33 BLE has a 3V3 logic. However, the DUE has also 3V3 logic aswell, and it worked fine.
  • The BLE module of the Nano 33 BLE creates interference, but it is not even activated in the code, and the channel is not suffering interference according to the scanner example.

@2bndy5
Copy link
Member

2bndy5 commented Mar 1, 2021

Love the brainstorming: Your brain is on the same page as mine. Thanks for the scanner output; this not only verifies that the radio is in working order but also the CE pin is behaving as expected.

Could it be a timing issue?

This is worth reviewing... I would start with source code for RF24::RF24()

@TonioChingon
Copy link
Author

yeah, I will do that, it will take a while though.

Btw, I did the scanner test, while another NRF14L01+ module was transmitting data on the 0x69 channel, which is being reflected in the scanner test, i.e. the module is actually "seeing" data.

@2bndy5
Copy link
Member

2bndy5 commented Mar 1, 2021

BTW, according to BLE specs, any BLE device only focuses on channels 2, 26, and 80 (and nRF24->BLE uses the address 0x6b7d9171 on 1Mbps -- though specs say 2Mbps is acceptable, but I've had little success with 2Mbps for BLE).

Also, frequency resolution using 1Mbps data rate is +/- 1 channel. With 2Mbps, the resolution is +/- 2 channels.

@TonioChingon
Copy link
Author

TonioChingon commented Mar 2, 2021

I figured it out, well partially. It was a HW problem.

Apparently, the 3V3 output of the Nano 33 BLE was the problem.
I changed the 3V3 source to an external source and now it is working well.

I am not sure why the voltage output of the Nano 33 BLE is not enough. According to the datasheet of the NRF24L01+, more current is drawn on RX mode than in TX mode. There does not seem to be a large difference in the RX and TX modes, though.

grafik

This is kind of disappointing, as I will have to include an external 3V3 voltage source to my setup.

Anyways, it was fun debugging the library and getting to know in detail the NRF24L01+ module.
I think this might be useful to other users of this library with the Nano 33 BLE, specially with the printf.h fix in the first post.

PS. Of course a capacitor on the VCC/GND pins of the radio module was always there...

@TMRh20
Copy link
Member

TMRh20 commented Mar 2, 2021 via email

@2bndy5
Copy link
Member

2bndy5 commented Mar 2, 2021

Good work! It's been so long since I looked at that part of the datasheet (I blame PA/LNA modules for that). I bet the scanner example will show much more ambient signals with a proper power source also.

2bndy5 added a commit that referenced this issue Mar 19, 2021
@2bndy5 2bndy5 linked a pull request Mar 20, 2021 that will close this issue
kripton pushed a commit to kripton/RF24 that referenced this issue Apr 10, 2021
convert _SPI calls to pointers where applicable

typo made BCM driver fail

overload begin() and amended docs about begin()

fix faulty #ifdef logic

doxygen v1.9.1 deprecated COLS_IN_ALPHA_INDEX tag

bump version to v1.4.0

exclude only RF24_LINUX

apply ptr treatment to Teensy, LittleWire, & Due

trigger ArduinoCLI action

doxygen action shouldn't create a docs folder

no need to specify output dir in doxygen action

make my life simpler: use new RF24_SPI_PTR macro

trigger ArduinoCLI action

forgot about c'tor; fix 2-space indent in begin()

abstract SPI::begin() from _init_pins()

adjust csn_pin before SPI.begin() on BCM driver

conforming whitespace

add printf.h fix from @TonioChingon in nRF24#739

rename atxmega.md & add link to supported product

add Due to ArduinoCLI action

fix teensy support; add PIO CI for teensy

[PIO CI] use quoted matrix entries

[PIO CI] use single quotes?

I hate YML

Gimme that badge

add MRAA to Linux CI action

typo

[Linux CI] MRAA install needs special permission

try with "sudo bash -c"

[Linux CI] MRAA not cross compiling (I think)

add example code snippets to Arduino support pg

doc typos

Due can't use SPI_PTR; delete ATXMEGA/readme.md
(use docs/atxmega.md instead)

fix nRF24#414; note need mbed example in arduino.md

fix printf() only for adafruit/ArduinoCore-SAMD

add msg about COMMON_ISSUES to README

add estimated mbed example to arduino.md

avr/pgmspace.h was added to Due core in 2013

oops, undo my testing change

remove useless Due config file nRF24#752

ammend support for SPI_UART in csn()

Confirm working 2nd SPI bus on esp8266 nRF24#648

fix indent

c-n-p artifact; more indent inconcsistencies

comment out theroretical example snippets

add pinout img from RF24Audio repo

doxygen sux at reading imgs

implement nRF24#539

my CnP skills are lacking

need to test py wrapper

[py_wrap] begin fails to compile

[py wrap] oops left the old begin still in there

[py wrap] use thin wrapper for begin_w/_pins

[pr wrap] try explicit begin(void)

boost.py docs suck

[py wrap] try using same name for begin(pin, pin)

[py wrap] c'tor overload is bad

[py wrap] "optional<>" template didn't take

[py wrap] unmatched parenthesis

advise that teensy doesn't need overloaded begin()

docs review
2bndy5 added a commit that referenced this issue Apr 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants