natevw / node-nrf

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

RF24 not working with /dev/spidev0.0 but well with native C++ lib #54

Open freegroup opened 7 years ago

freegroup commented 7 years ago

Dear

sorry for the noise but I have some problems to get your lib up and running on my Raspberry Pi 3.

I want use Node.js with your pure and clean JS code but the code didn't find my device.

var NRF24 = require("nrf"),
    spiDev = "/dev/spidev0.0",
    cePin = 24, irqPin = 25;

var nrf = NRF24.connect(spiDev, cePin, irqPin);
//nrf._debug = true;
nrf.channel(0x4c)
    .transmitPower('PA_MAX')
    .dataRate('1Mbps')
    .crcBytes(2)
    .autoRetransmit({count:15, delay:500})
    .begin(function () {
        console.log("PONG back");
        var rx = nrf.openPipe('rx', 0xF0F0F0F000, {
            size: 2,
            autoAck: true
        });

        rx.on('data', function (d) {
            console.log("data");
            console.log("Got data, will respond", d.readUInt32BE(0));
        })
//nrf._debug=true;
nrf.printDetails();
});
SPI device:  /dev/spidev0.0
CE GPIO:     24
IRQ GPIO:    25
STATUS:      0x0 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0–1:  0x0000000000 0x0000000000
RX_ADDR_P2–5:  0x00 0x00 0x00 0x00
TX_ADDR:     0x0000000000
RX_PW_P0–5:    0x0 0x0 0x0 0x0 0x0 0x0
EN_AA:       0x00
EN_RXADDR:   0x00
RF_CH:       0x0
RF_SETUP:    0x00
CONFIG:      0x00
DYNPD/FEATURE:   0x00 0x00
Data Rate:   1Mbps
Model:       nRF24L01
CRC Length:  Disabled
PA Power:    PA_MIN

native C++ code is working well (working GPIO) with the same wiring

#include <RF24/RF24.h>
#include <RF24Network/RF24Network.h>
#include <iostream>
#include <ctime>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/**
 * g++ -L/usr/lib main.cc -I/usr/include -o main -lrrd
 **/

// CE Pin, CSN Pin, SPI Speed
RF24 radio(RPI_BPLUS_GPIO_J8_15,RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ);

RF24Network network(radio);

// Constants that identifies this node
const uint16_t pi_node = 0;

// Time between checking for packets (in ms)
const unsigned long interval = 2000;

// Structure of our message
struct message_t {
  float temperature;
  float humidity;
};

int main(int argc, char** argv)
{
    // Initialize all radio related modules
    radio.begin();
    delay(5);
    network.begin(90, pi_node);

    // Print some radio details (for debug purposes)
    radio.printDetails();
    printf("Ready to receive...\n");

    // Now do this forever (until cancelled by user)
    while(1)
    {
        // Get the latest network info
        network.update();
        printf(".\n");
        // Enter this loop if there is data available to be read,
        // and continue it as long as there is more data to read
        while ( network.available() ) {
  printf("network available\n");
            RF24NetworkHeader header;
            message_t message;
            // Have a peek at the data to see the header type
            network.peek(header);
            // We can only handle the Temperature type for now
            if (header.type == 't') {
                // Read the message
                network.read(header, &message, sizeof(message));
                // Print it out
                printf("Temperature received from node %i: %f \n", header.from_node, message.temperature);
            } else {
                // This is not a type we recognize
                network.read(header, &message, sizeof(message));
                printf("Unknown message received from node %i\n", header.from_node);
            }
        }

        // Wait a bit before we start over again
        delay(2000);
    }

    // last thing we do before we end things
    return 0;
}
================ SPI Configuration ================
CSN Pin      = CE0 (PI Hardware Driven)
CE Pin       = Custom GPIO22
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     = 0xccccccccc3 0xcccccccc3c
RX_ADDR_P2-5     = 0x33 0xce 0x3e 0xe3
TX_ADDR      = 0xe7e7e7e7e7
RX_PW_P0-6   = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA        = 0x3e
EN_RXADDR    = 0x3f
RF_CH        = 0x5a
RF_SETUP     = 0x07
CONFIG       = 0x0f
DYNPD/FEATURE    = 0x3f 0x04
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_MAX
Ready to receive...

It would be great if you have some ideas whats could be wrong on my side.

Best Regards

Andreas

natevw commented 7 years ago

@freegroup Thanks for trying out node-nrf! Did you see the note at https://github.com/natevw/node-nrf/#troubleshooting about SPI not working after using C++ RF24 library? I suspect this could be the only problem, but want to make sure before closing this ticket.

freegroup commented 7 years ago

Hi

thanks - this helps a lot. I can now see the configuration settings - in this case the communication to the RF modul is working - but unfortunately no data arrives.

The Arduino -> Arduino setup is working fine but I have some problems with my Node code.

Code of the Arduino Receiver (works)

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xf0f0f0f0e1 0xf0f0f0f0d2
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xf0f0f0f0e1
RX_PW_P0-6   = 0x02 0x02 0x00 0x00 0x00 0x00
EN_AA        = 0x00
EN_RXADDR    = 0x02
RF_CH        = 0x4c
RF_SETUP     = 0x07
CONFIG       = 0x0f
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_MAX
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <FormattingSerialDebug.h>
#include <TrueRandom.h>

RF24 radio(9,10);
uint64_t   pipes[] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL};

unsigned int  gotData;

void setup(){
  SERIAL_DEBUG_SETUP(57600);
  radio.begin();
  radio.setAutoAck(0);                    // Disable autoACK
  radio.setRetries(0,15);                 // Smallest time between retries, max no. of retries
  radio.setPayloadSize(sizeof(gotData));                // Here we are sending 1-byte payloads to test the call-response speed
  radio.openWritingPipe(pipes[0]);        // Both radios listen on the same pipes by default, and switch when writing
  radio.openReadingPipe(1,pipes[1]);
  radio.startListening();                 // Start listening
  radio.printDetails();                   // Dump the configuration of the rf unit for debugging
}

void loop(void) {

    byte pipeNo;
    while( radio.available(&pipeNo)){
      radio.read( &gotData, sizeof(gotData) );
      DEBUG("Got Message");
   }
}

Code of the node.js receiver (not working)

I didn'T understand why the TX_ADDR is so different between node and my arduino code. Additional some flags are verry different to the arduino setup.

SPI device:  /dev/spidev0.0
CE GPIO:     24
IRQ GPIO:    25
STATUS:      0xe RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0–1:  0xf0f0f0f0d2 0xf0f0f0f0e1
RX_ADDR_P2–5:  0xc3 0xc4 0xc5 0xc6
TX_ADDR:     0xe7e7e7e7e7
RX_PW_P0–5:    0x2 0x2 0x0 0x0 0x0 0x0
EN_AA:       0x3c
EN_RXADDR:   0x00
RF_CH:       0x4c
RF_SETUP:    0x07
CONFIG:      0x0e
DYNPD/FEATURE:   0x00 0x07
Data Rate:   1Mbps
Model:       nRF24L01+
CRC Length:  16 bits
PA Power:    PA_MAX
var NRF24 = require("nrf"),

spiDev = "/dev/spidev0.0",
pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2],
cePin = 24, irqPin = 25;

var nrf = NRF24.connect(spiDev, cePin, irqPin);
//nrf._debug = true;
nrf.channel(0x4c)
    .transmitPower('PA_MAX')
    .dataRate('1Mbps')
    .crcBytes(2)
    .autoRetransmit({count:15, delay:500})
    .begin(function () {
        var    rx = nrf.openPipe('tx', pipes[1], {autoAck:false, size:2});

        rx.on('data', function (d) {
           console.log("data");
        });
        rx.on('ready', function () {
           nrf.printDetails()
        });
});

code of the Arduino transmitter (works)

STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1     = 0xf0f0f0f0d2 0xf0f0f0f0e1
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR      = 0xf0f0f0f0d2
RX_PW_P0-6   = 0x02 0x02 0x00 0x00 0x00 0x00
EN_AA        = 0x00
EN_RXADDR    = 0x03
RF_CH        = 0x4c
RF_SETUP     = 0x07
CONFIG       = 0x0e
DYNPD/FEATURE    = 0x00 0x00
Data Rate    = 1MBPS
Model        = nRF24L01+
CRC Length   = 16 bits
PA Power     = PA_MAX
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <FormattingSerialDebug.h>

// Creates a new instance using SPI plus pins 9 and 10
RF24 radio(9, 10);
uint64_t pipes[] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL};

#define BUTTON_PIN 3

// Button debouncing macros
#define DEBOUNCE 15
#define DMASK ((uint16_t)(1<<DEBOUNCE)-1)
#define DF (1<<(uint16_t)(DEBOUNCE-1))

// Macro for detection of falling edge and debouncing
#define DFE(signal, state) ((state=((state<<1)|(signal&1))&DMASK)==DF)

// Button debouncing status store
unsigned int buttonStatus;

// We will be using just 1 address for the RX and TX addressing 
// which means that every module has the same TX/RX address so 
// we need to disable auto acknowledge and auto retransmit 
// otherwise each module would auto acknowledge each other, 
// we’ll implement this functionality ourselves
//
void setup() {
    SERIAL_DEBUG_SETUP(57600);

    // Setup the push button
    pinMode(BUTTON_PIN, INPUT_PULLUP);

    // Initialize the transceiver
    radio.begin();
    radio.setAutoAck(0)  ;        // Disable auto ack: this is true by default
//  radio.enableAckPayload();      // Enables payload in ack packets
    radio.setRetries(1, 15);       // Sets 15 retries, each every 0.5ms, useful with ack payload
    radio.setPayloadSize(sizeof(buttonStatus));       // Sets the payload size to 2 bytes
    radio.setDataRate(RF24_1MBPS); // Sets fastest data rate, useful with ack payload
    radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(1,pipes[0]);
    // Prints current configuration on serial
    radio.printDetails();
}

void loop() {

    delay(1); // Slow down a bit the MCU

    // Checks the push button: if we enter here the button has been pressed
    if (DFE(digitalRead(BUTTON_PIN), buttonStatus)) {
        // Put transceiver in transmit mode
        radio.stopListening();
        // Transmit this node id to the hub
        bool write = radio.write(&buttonStatus, sizeof(buttonStatus));
        DEBUG("Send attempt from node was %s", write ? "successful" : "UNSUCCESSFUL");
    }
}
natevw commented 7 years ago

Are you sure your node.js code is what you want? You have rx = nrf.openPipe('tx',… so despite the variable name you are actually setting up a transmitting pipe rather than receiving.

In theory, with the nRF24 it is possible to receive on a PTX pipe (the data comes by way of the ACK packets back to you) but only if:

The main reason you have TX_ADDR: 0xe7e7e7e7e7 in your node debugging is probably because that's the default or something — the TX address changes every time you transmit to a different receiver, but your node code isn't transmitting at all.

Basically, it looks like your Arduino code and node.js code are both set up to be receivers, except that the node.js code does happen to open the pipe as tx. But the usual way to do TX from node-nrf is shown at e.g. https://github.com/natevw/node-nrf/blob/master/test.js#L43 (actually the ping/pong examples are kind of confusing because both sides are active, take a look at https://github.com/natevw/node-nrf/blob/master/test2.js#L34-L41 for a clearer example).

freegroup commented 7 years ago

thanks for your fast support - I'm happy about this.

you are right - my code is broken. I changed it from 'tx' to 'rx' but this didn't solve the problem. :-/

var NRF24 = require("nrf"),

spiDev = "/dev/spidev0.0",
pipes = [0xF0F0F0F0E1, 0xF0F0F0F0D2],
cePin = 22, irqPin = 25;

var nrf = NRF24.connect(spiDev, cePin, irqPin);
//nrf._debug = true;
nrf.channel(0x4c)
    .transmitPower('PA_MAX')
    .dataRate('1Mbps')
    .crcBytes(2)
    .autoRetransmit({count:15, delay:500})
    .begin(function () {
        var rx = nrf.openPipe('rx', pipes[1], {autoAck:false, size:2});
        rx.on('data', function (d) {
           console.log("data");
        });
        rx.on('ready', function () {
           nrf.printDetails()
        });
});
SPI device:  /dev/spidev0.0
CE GPIO:     22
IRQ GPIO:    25
STATUS:      0xe RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0–1:  0xf0f0f0f0d2 0xf0f0f0f0d2
RX_ADDR_P2–5:  0xc3 0xc4 0xc5 0xc6
TX_ADDR:     0xe7e7e7e7e7
RX_PW_P0–5:    0x2 0x2 0x0 0x0 0x0 0x0
EN_AA:       0x3c
EN_RXADDR:   0x02
RF_CH:       0x4c
RF_SETUP:    0x07
CONFIG:      0x0f
DYNPD/FEATURE:   0x00 0x07
Data Rate:   1Mbps
Model:       nRF24L01+
CRC Length:  16 bits
PA Power:    PA_MAX

tankrf24raspberry_bb

nkolban commented 7 years ago

2016-09-10:

I am stuck with exactly the same symptoms as @freegroup in his first post. I am testing on a Pi3 with kernel level 4.4.13 and node version v4.5.0. My plan is to write up this library for a book:

https://leanpub.com/pi

I have tried the recipe of:

$ sudo modprobe -r spi_bcm2835
$ sudo modprobe spi_bcm2835

but it has made no difference. Again, symptoms exactly like the 1st post in this issue. If needed, I can do live screen share or other Q&A through skype: "neil.kolban" if that would assist.

If I get it working, I'll write up for the PI book and then test on the new CHIP single board computer.

I wired up as follows:

nrf24 and pi_bb

And the application looks like:

"use strict";
var nrf = require("nrf");
var CE = 25;
var IRQ = 24;
// Param 1 = CE
// param 2 = IRG
var radio = nrf.connect("/dev/spidev0.0", CE, IRQ);
radio.begin();
radio.on("ready", function() {
    console.log("We are ready!");
    var sendingPipe = radio.openPipe("tx", "1Node");
    sendingPipe.on("error", function(errorData) {
        console.log("We detected an error: " + errorData);
    });
    sendingPipe.write("Hello!");
    radio.printDetails();
});

console.log("All done!");

The output is:

$ sudo node sender.js 
All done!
We are ready!
SPI device:  /dev/spidev0.0
CE GPIO:     25
IRQ GPIO:    24
STATUS:      0x0 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0–1:  0x0000000000 0x0000000000
RX_ADDR_P2–5:  0x00 0x00 0x00 0x00
TX_ADDR:     0x0000000000
RX_PW_P0–5:    0x0 0x0 0x0 0x0 0x0 0x0
EN_AA:       0x00
EN_RXADDR:   0x00
RF_CH:       0x0
RF_SETUP:    0x00
CONFIG:      0x00
DYNPD/FEATURE:   0x00 0x00
Data Rate:   1Mbps
Model:       nRF24L01
CRC Length:  Disabled
PA Power:    PA_MIN

I also tries a receiver app:

"use strict";
var nrf_module = require("nrf");
var CE = 25;
var IRQ = 24;
var nrf = nrf_module.connect("/dev/spidev0.0", CE, IRQ);

nrf.begin();

nrf.on("ready", function() {
    console.log("We are ready!");
    var receivingPipe = nrf.openPipe("rx", "1Node", {
        size: 2,
        autoAck: true
    });
    receivingPipe.on("data", function() {
        console.log("We received some data!");
    });
    receivingPipe.on("error", function(errorData) {
        console.log("We detected an error: " + errorData);
    });
    nrf.printDetails();
});

console.log("All done!");

and it resulted in the same printDetails() dump as the sender.


2016-09-11 I soldered a 2.2uF capacitor across GND and Vcc on the nRF24L01. At the same time, I pulled out all the wires that I had connected and re-connected them again. This time, I was able to get printDetails() output from the runs. I don't know if I had an error in my wiring or whether the capacitor changed the story. However, now I am seeing printDetails() I am off to try and setup a sender/receiver pair.

freegroup commented 7 years ago

hi

i didn't get them up and running. Details are printed but communication fails with the node.js solution.

At the end I implemented a C++ program which works as broker for the nodeJS server.....