natevw / node-nrf

Pure-JavaScript nRF24L01 driver library
117 stars 31 forks source link

Beagle Bone and Arduino not talking #24

Open alxAgu opened 9 years ago

alxAgu commented 9 years ago

Hello everyone,

I've been unable to send messages between 2 radios:

Radio BBB
vcc P9_3
gnd P9_2
CSN P9_17 (SPI0_CSO)
CE P9_16(GPIO_51)
MOSI P9_18 (SPI0_D1)
SCK P9_22 (SPI0_SCKL)
IRQ P9_15 (GPIO_48)
MISO P9_21 (SPI0_D0)

These are the configuration details of my Sender (arduino):

STATUS           = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0x726562756c 0x6576616c73
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR          = 0x726562756c
RX_PW_P0-6       = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA            = 0x3f
EN_RXADDR        = 0x02
RF_CH            = 0x23
RF_SETUP         = 0x05
CONFIG           = 0x0f
DYNPD/FEATURE    = 0x00 0x01
Data Rate        = 1MBPS
Model            = nRF24L01+
CRC Length       = 16 bits
PA Power         = PA_HIGH

Configuration in my BBB:

SPI device:  /dev/spidev1.0
CE GPIO:     51
IRQ GPIO:    48
STATUS:      0xe RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0–1:    0x6576616c73 0x726562756c
RX_ADDR_P2–5:    0xc3 0xc4 0xc5 0xc6
TX_ADDR:     0x6576616c73
RX_PW_P0–5:  0x20 0x20 0x0 0x0 0x0 0x0
EN_AA:       0x3f
EN_RXADDR:   0x03
RF_CH:       0x23
RF_SETUP:    0x05
CONFIG:      0x0e
DYNPD/FEATURE:   0x00 0x07
Data Rate:   1Mbps
Model:       nRF24L01+
CRC Length:  16 bits
PA Power:    PA_HIGH

My Nodejs code (BBB):

var radio = require('nrf').connect('/dev/spidev1.0', 51, 48);
radio.channel(35);
radio.dataRate('1Mbps');
radio.crcBytes(2);
radio.autoRetransmit({count:15, delay:4000});
radio.transmitPower('PA_HIGH');

radio.begin(function () {

    var rx = radio.openPipe('rx', 0x726562756c, {autoAck:true, size:32});           
    var tx = radio.openPipe('tx', 0x6576616c73, {autoAck:true, size:32});           

    rx.on('data', function(d){
        console.log("Radio data: ", d.readUInt32BE(0));
    });

    tx.on('error', function (e) {
        console.warn("Error sending: ", e);
    });

    function send(){
        console.log("Sending...");
        tx.write("From BBB!");
    }

    tx.on('ready', function(e){
        console.log("Ready to transmit!");
        radio.printDetails();
    }); 

});

If I try to send data from my BBB, I get the following error:

[Error: Packet timeout, transmit queue flushed.]

I have a 3rd radio [tester] connected to another Arduino and using the same configuration as my BBB, but this one however, is able to send and receive messages to and from the "sender" without issues.

The following table shows the configuration output of the 3 radios:

Register Sender Tester (Works) BBB (Doesn't Work)
RX_ADDR_P0-1 0x726562756c 0x6576616c73 0x6576616c73 0x726562756c 0x6576616c73 0x726562756c
RX_ADDR_P2-5 0xc3 0xc4 0xc5 0xc6 0xc3 0xc4 0xc5 0xc6 0xc3 0xc4 0xc5 0xc6
TX_ADDR 0x726562756c 0x6576616c73 0x6576616c73
RX_PW_P0-6 0x20 0x20 0x00 0x00 0x00 0x00 0x20 0x20 0x00 0x00 0x00 0x00 0x20 0x20 0x0 0x0 0x0 0x0
EN_AA 0x3f 0x3f 0x3f
EN_RXADDR 0x02 0x02 0x03
RF_CH 0x23 0x23 0x23
RF_SETUP 0x05 0x05 0x05
CONFIG 0x0f 0x0f 0x0e
DYNPD/FEATURE 0x00 0x01 0x00 0x01 0x00 0x07
Data Rate 1MBPS 1MBPS 1MBPS
Model nRF24L01+ nRF24L01+ nRF24L01+
CRC Length 16 bits 16 bits 16 bits
PA Power PA_HIGH PA_HIGH PA_HIGH

Notice how the only registers that differ are:

EN_RXADDR
CONFIG
DYNPD/FEATURE

I've spent some time now on this but haven't been able to see what the problem is. Am I doing something silly? Any help would be much appreciated!!

alxAgu commented 9 years ago

Update:

I tested it in a Raspberry PI but the results are exactly the same. At least I know now the problem is not hardware related?

I also noticed that none of the test apps work for me (neither in BBB nor R-PI)... I must be doing something really dumb :(

alxAgu commented 9 years ago

Update 2:

Ok, I finally got it working receiving data from the arduino sender. However, I'm still unable to send data back (transmit).

As soon as I call tx.write(...) I get the error "[Error: Packet timeout, transmit queue flushed.]" and my rx stops receiving data.

natevw commented 9 years ago

Hmm, I wonder if this is related to the DYNPD/FEATURE difference. Have you tried using .toggle_features() in the Arduino RF24 code? IIRC this is what turns on the autoack logic that your BBB sender wants to rely on.

alxAgu commented 9 years ago

Hi Nathan,

Yes, that's what I thought, I tried setting the registers myself but the result is the same.

radio.setStates({DYNPD:0x00, FEATURE:0x01});

Also, if that was the case, the test.js app should be working when I run them in my BBB and Raspberry PI.

Register Raspberry PI (ping) BBB (pong)
SPI device /dev/spidev0.0 /dev/spidev1.0
CE GPIO 24 51
IRQ GPIO 25 48
STATUS 0xe RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0 0xe RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0–1 0xf0f0f0f0e1 0xf0f0f0f0d2 0xf0f0f0f0d2 0xf0f0f0f0e1
RX_ADDR_P2–5 0xc3 0xc4 0xc5 0xc6 0xc3 0xc4 0xc5 0xc6
TX_ADDR 0xf0f0f0f0e1 0x6576616c73
RX_PW_P0–5 0x20 0x20 0x0 0x0 0x0 0x0 0x20 0x20 0x0 0x0 0x0 0x0
EN_AA 0x3f 0x3f
EN_RXADDR 0x03 0x03
RF_CH 0x4c 0x4c
RF_SETUP 0x07 0x07
CONFIG 0x0e 0x0f
DYNPD/FEATURE 0x03 0x07 0x03 0x07
Data Rate 1Mbps 1Mbps
Model nRF24L01+ nRF24L01+
CRC Length 16 bits 16 bits
PA Power PA_MAX PA_MAX
natevw commented 9 years ago

So it looks like you did also try enabling the features on Arduino? This library is unlikely to work right after you use the low-level setStates method to disable the features on the BBB — those methods are basically to be used only with the datasheet and without using the higher level pipe/etc methods.

alxAgu commented 9 years ago

No, I haven't really changed the Arduino code. I'm actually using the latest version of the RF24 library which doesn't really have the .toggle_features() you refer to.

I only used setStates() trying to see if by disabling features manually I could get the radio to transmit something. But again, no luck whatsoever.

It's odd to see that receiving data works, but after trying to send something (tx.write), everything stops working.

natevw commented 9 years ago

Haven't reviewed latest RF24 but it still seems it is not configured to send acknowlegement packets yet.

(And btw, If a tx.write to a pipe fails (as it will if you have autoAck enabled and the other end is not ACKing packets) the pipe will be closed, and you need handle that error condition by creating a new pipe. Trying the same thing doesn't really help you recover if something is truly misconfigured, but hopefully clarifies why "everything stops".)

alxAgu commented 9 years ago

The latest version of the RF24 definitely uses autoAck, I've been using it for a while now to connect multiple Arduinos.

Regardless, both Raspberry PI and BBB should be able then to communicate with each other since they are both using the nrf library.

I didn't know about the pipes being closed on error, but, if that's the case, shouldn't the tx be closed and the rx pipe stay working normally? Because when I say "everything stops working" I mean, even receiving data on my rx pipe fails.

alxAgu commented 9 years ago

I finally discovered what the problem was.

It turns out that the new RF24 library has a fixed payload size of 32 bytes by default while the nrf library (I assume) has dynamic payloads enabled by default.

I managed to have bidirectional communication between my BBB and Arduino by enabling dynamic payloads on the Arduino side (enableDynamicPayloads()), and removing the {size:32} opt of my tx pipe.

Now I wonder: is my assumption correct? (payloads are dynamic by default in the nrf library) and, how can I change that without using low-level setStates?

natevw commented 9 years ago

Ah, great! Yes, I suppose that would affect things as well.

This is an interesting situation and I already had to go back to the datasheet. Still need a little more research, but here's what I think the situation is right now:

So I think you should try calling radio.setStates({EN_DPL:0}) yourself and see what effect it has…if it works, I would consider it a valid workaround until this whole matter can get chased out more thoroughly.

alxAgu commented 9 years ago

Ok, I've been doing a lot of tests and these are my findings:

Receiving Data

Sending Data

In Summary

You need to enable dynamic payloads in the RF24 library if you want a smooth communication between both radios (Arduino and BBB).

Final Note

I was horrified and very disappointed when I discovered that the ping time using my BBB is about 65ms. In fact only the tx.write() method takes ~5ms to send 8 bytes. I say horrified because the average ping time of 2 radios running over the RF24 library is ~4 ms for 32 bytes! (In case you are wondering, yes, I tested it at 2Mbps and even tried to increase the SPI clock speed to 8Mhz).

I assume this may have something to do with the poor GPIO speed of the BeagleBone. Any advice regarding this?

cgpgh commented 9 years ago

alexagudelo, I am looking to do the same thing like you, communicate 2way between Arduino and BBB. I am having challenges to get my BBB to recognize my NRF24L01. can you please give me the steps you followed to get them to talk. Thanks in advance for your help.

cgpgh commented 9 years ago

I was able to get the NRF working on my BBB had incorrect wiring. was able to get BBB and arduino to talk with the sample ping/pong scripts. If you