7 Replies Latest reply on Jul 10, 2015 3:17 AM by f3d

    Seeking help with Edison + NRF24L01 + upm/node.js

    LVEdison

      Hi there,

       

      I've been spending quite some time trying to get the rf unit to work with the Edison+Arduino expansion board using the RF24 library on the arduino side to no avail.  This past weekend I noticed that there appears to be c++ support in the UPM library and there are a couple C++ examples, but thus far I haven't had any luck using the jsupm_nrf24l01 module.  The issue that I am running into is that I can't figure out the proper way to pass in the localAddress and the broadcastAddress.  This seems to be a case of me not understanding the javascript --> c++ bindings, so any help would be greatly appreciated!

       

      Thanks for reading!

       

       

       

      Error message I am seeing:

      ERROR: /home/root/.node_app_slot/main.js:41                                                                                                                                                                                                  
      ERROR: comm.setSourceAddress([0xf0, 0xf0, 0xf0, 0xf0,0xe1]);                                                                                                                                                                                 
          ERROR:  ^                                                                                                                                                                                                                                
      ERROR: Error: in method 'NRF24L01_setSourceAddress', argument 2 of type 'uint8_t *'                                                                                                                                                          
          at Object.<anonymous> (/home/root/.node_app_slot/main.js:41:6)                                                                                                                                                                           
          at Module._compile (module.js:456:26)                                                                                                                                                                                                    
          at Object.Module._extensions..js (module.js:474:10)                                                                                                                                                                                      
          at Module.load (module.js:356:32)                                                                                                                                                                                                        
          at Function.Module._load (module.js:312:12)                                                                                                                                                                                              
          at Function.Module.runMain (module.js:497:10)                                                                                                                                                                                            
          at startup (node.js:119:16)                                                                                                                                                                                                              
          at node.js:906:3  
      


      The very simple example file:

       

      ////////////// main.js ////////////////
      var m = require('mraa');
      var nrf = require('jsupm_nrf24l01');
      // setup the rf unit with configurable pin options:
      var comm = new nrf.NRF24L01(7,8);
      // debug:
      //console.log(nrf);
      //console.log(comm);
      var running = 0,
          localAddress = [], // ???  [0x01, 0x01, 0x01, 0x01, 0x01]
          broadCastaddress =  [], // ?? [0x01, 0x01, 0x01, 0x01, 0x01] ,
          sigHandler = function(sig){
              var msg = "got signal: ";
              console.log(msg,sig);
              running = 1;
          },
          
          nrf_handler = function(){
              var msg = "recieved:: ";
              console.log(msg,nrf.m_rxBuffer[0]);
          }
          
      /*  reference:  upm/nrf24l01-receiver.cxx at master · intel-iot-devkit/upm · GitHub
      comm = new upm::NRF24L01(7, 8);
          comm->setSourceAddress ((uint8_t *) local_address);
          comm->setDestinationAddress ((uint8_t *) broadcast_address);
          comm->setPayload (MAX_BUFFER);
          comm->configure ();
          comm->setSpeedRate (upm::NRF_250KBPS);
          comm->setChannel (99);
          comm->dataRecievedHandler = nrf_handler;
          */
      comm.setSourceAddress(localAddress);
      comm.setDestinationAddress(broadCastaddress);
      comm.setPayload(16);
      comm.configure();
      comm.setSpeedRate(nrf.NRF_250KBPS);
      comm.setChannel(99);
      comm.dataRecievedHandler = sigHandler;
      console.log(comm);
      
        • 1. Re: Seeking help with Edison + NRF24L01 + upm/node.js
          Intel_Peter

          Hello LVEdison,

           

          Which addresses are you entering on localAddress and broadCastaddress?

          According to the comments in the code above they are either empty or the same, so how are you entering them?

           

          Peter.

          • 2. Re: Seeking help with Edison + NRF24L01 + upm/node.js
            LVEdison

            Thanks for the reply!

             

            Sorry for the incomplete example, I am seeking guidance on the proper way to enter those I suppose.  The error was being thrown upon attempting to set the sourceAddress so I never made it past that step, but the two addresses I was attempting to use are:

             

            local:  [0x01, 0x01, 0x01, 0x01, 0x01]

            remote:  [0xFF, 0xFF, 0xFF, 0xFF, 0xFF]


            I've tried a few ways of passing these in that I could think of such as using an Array, Buffer, String values etc and the error message is the same which leads me to believe that my error is in supplying the address in a way that the driver is expecting.


            _L

            • 3. Re: Seeking help with Edison + NRF24L01 + upm/node.js
              intel_dan

              After playing around with your sample, I think that the Node/JS structure you need is ArrayBuffer

               

              ex: comm.setSourceAddress(new ArrayBuffer(localAddress)); 

              • 4. Re: Seeking help with Edison + NRF24L01 + upm/node.js
                LVEdison

                Thanks intel_dan, I will give that a try this evening and see how things go!

                 

                _L

                • 5. Re: Seeking help with Edison + NRF24L01 + upm/node.js
                  LVEdison

                  Following up - thank you for the help so far! 

                   

                  Switching to an ArrayBuffer did allow setSourceAddress call to fire without returning an error, however the code will not proceed past that line and hangs.

                   

                  Question:  Are there currently plans to provide more node.js examples for the UPM project similar to the examples provided for C++?  It appears that this radio unit should work with the Edison based upon the C++ examples, but getting the configuration correct via Arduino IDE or node.js code hasn't worked for me yet.

                  • 6. Re: Seeking help with Edison + NRF24L01 + upm/node.js
                    Intel_Peter

                    Hello LVEdison,

                     

                    Currently all available Node JS examples can be found in mraa/examples. However there are some functions that are implemented on C++ but not yet on Python/Node JS. I'd suggest you visit the link above from time to time to check if new examples are posted.

                     

                    Peter.

                    • 7. Re: Seeking help with Edison + NRF24L01 + upm/node.js
                      f3d

                      I've been working on the NRF24L01+ with a Gen2 Galileo board.  I decided to write it directly to the SPI and GPIO level as I've had limited success with various libraries.  If you are interested the code is pasted below.  I've tested it in an application that communicates with a microcontroller board and it appears to work well.

                       

                      // NRF24L01+ demo in javascript for the Intel Galileo Gen 2

                      // Author: Frank Duignan. 

                      // Updates posted on http://ioprog.com and http://eleceng.dit.ie/frank

                       

                      var PAYLOAD_LENGTH=10

                      var SOURCE_ADDRESS=([8,0,5,8,6]);

                      var DESTINATION_ADDRESS=([0x0a,1,1,1,4]);

                      /******* Low level setup (configure I/O etc *******/

                      var m=require('mraa');

                      console.log('MRAA version: ' + m.getVersion());

                      // configure SPI for 1MHz operation

                      var SPI=new m.Spi(0);

                      SPI.frequency(1000000);

                      // Set up CE and CSN pins for the NRF24L01

                      // These will be directly controlled by software NOT the SPI hardware

                      var CEPin=new m.Gpio(9);

                      var CSNPin=new m.Gpio(8);

                      CEPin.dir(m.DIR_OUT);

                      CSNPin.dir(m.DIR_OUT);

                      CEPin.write(0);

                      CSNPin.write(1);

                      // Global variable that is updated during each SPI transaction

                      var NRFStatus;

                       

                       

                      // NRF Functions follow

                      function NRFinit()

                      {       

                          NRFWriteRegister(0,0);            // Clear out config

                          NRFWriteRegister(1,3);            // enable auto ack in P0 and P1

                          NRFWriteRegister(4,0x24);        // 750us between retries, 4 retries

                          NRFWriteRegister(2,3);            // enable data pipe 0 and 1

                          NRFWriteRegister(3,3);            // 5 byte addressing

                          NRFWriteRegister(0x05,5);         // select channel 5

                          NRFWriteRegister(0x06,0x06);     // select 1Mbps, maximum power

                          NRFWriteRegister(0x07,0x70);     // clear status flags

                          NRFWriteRegister(0x11,0);        // Auto ack in pipe 0

                          NRFWriteRegister(0x12,PAYLOAD_LENGTH);    // set payload length

                          NRFWriteCE(1);

                          NRFEnableRXMode();                // start listening

                      }

                      function delay(howlong)

                      {

                          howlong = howlong / 2; // yields approx 1us timebase

                          while(howlong > 0)

                          {

                              howlong = howlong -1 ;

                          }

                      }

                      function NRFWriteCE(Value)

                      {   

                          if (Value)

                              CEPin.write(1)

                          else

                              CEPin.write(0)

                             

                      }

                      function NRFWriteCSN(Value)

                      {

                          if (Value )

                              CSNPin.write(1);

                          else

                              CSNPin.write(0);

                      }

                       

                      function transferSPI(data)

                      {       

                          return SPI.writeByte(data);

                      }

                       

                      function NRFReadRegister(RegNum)

                      {

                          var ReturnValue=0;

                          NRFWriteCSN(0);   

                          if (RegNum < 0x20)

                          {

                              NRFStatus = transferSPI(RegNum); // update status after CSN goes low

                              ReturnValue = transferSPI(0xff); // Send dummy byte to generate clocks       

                          }

                          else

                          {

                              ReturnValue = -1;

                          }

                          NRFWriteCSN(1);       

                          return ReturnValue;

                      }

                       

                      function NRFWriteRegister(RegNum, Value)

                      {

                          var ReturnValue=0;

                          NRFWriteCSN(0);   

                          if (RegNum < 0x20)

                          {       

                              NRFStatus = transferSPI(0x20+RegNum); // update status after CSN goes low               

                              ReturnValue = transferSPI(Value);      // Write byte to target

                          }

                          else

                          {

                              ReturnValue = -1;

                          }

                          NRFWriteCSN(1);

                          return ReturnValue;

                      }

                      function NRFFlushTX()

                      {

                          NRFWriteCSN(0);   

                          NRFStatus = transferSPI(0xe1); // Send Flush TX command

                          NRFWriteCSN(1);

                      }

                      function NRFFlushRX()

                      {

                          NRFWriteCSN(0);   

                          NRFStatus = transferSPI(0xe2); // Send Flush RX command

                          NRFWriteCSN(1);

                      }

                       

                      function NRFSetRXAddress0(AddressLength, Address)

                      {

                          var index;

                          switch (AddressLength) {

                              case 3 : {

                                  NRFWriteRegister(3,1); // 3 byte address length           

                                  break;

                              }

                              case 4 : {

                                  NRFWriteRegister(3,2); // 4 byte address length

                                  break;

                              }

                              case 5 : {

                                  NRFWriteRegister(3,3); // 5 byte address length

                                  break;

                              }

                              default: {

                                  return -1; // invalid address length

                              }

                          }

                          NRFWriteCSN(0);

                          NRFStatus = transferSPI(0x20+0x0a); // start write to RX_P0_Pipe address

                          for (index = 0; index < AddressLength; index++)

                          {

                              NRFStatus = transferSPI(Address[index]);

                          }

                          NRFWriteCSN(1);

                      }

                      function NRFSetRXAddress1(AddressLength, Address)

                      {

                          var index;

                          switch (AddressLength) {

                              case 3 : {

                                  NRFWriteRegister(3,1); // 3 byte address length           

                                  break;

                              }

                              case 4 : {

                                  NRFWriteRegister(3,2); // 4 byte address length

                                  break;

                              }

                              case 5 : {

                                  NRFWriteRegister(3,3); // 5 byte address length

                                  break;

                              }

                              default: {

                                  return -1; // invalid address length

                              }

                          }

                          NRFWriteCSN(0);

                          NRFStatus = transferSPI(0x20+0x0b); // start write to RX_P1_Pipe address

                          for (index = 0; index < AddressLength; index++)

                          {

                              NRFStatus = transferSPI(Address[index]);

                          }

                          NRFWriteCSN(1);

                      }

                      function NRFGetRXAddress( MaxAddressLength,  Address)

                      {

                          var index;

                          var actual_length;

                          actual_length = NRFReadRegister(3);

                          actual_length = actual_length + 2;

                          if (actual_length > MaxAddressLength)

                              return -1;

                          NRFWriteCSN(0);

                          NRFStatus = transferSPI(0x0a); // start read from RX_P0_Pipe address

                          for (index = 0; index < actual_length; index++)

                          {

                              Address[index] = transferSPI(0xff);

                          }

                          NRFWriteCSN(1);

                          return(0);

                      }

                      function NRFSetTXAddress(AddressLength, Address)

                      {

                          var index;

                          switch (AddressLength) {

                              case 3 : {

                                  NRFWriteRegister(3,1); // 3 byte address length           

                                  break;

                              }

                              case 4 : {

                                  NRFWriteRegister(3,2); // 4 byte address length

                                  break;

                              }

                              case 5 : {

                                  NRFWriteRegister(3,3); // 5 byte address length

                                  break;

                              }

                              default: {

                                  return -1; // invalid address length

                              }

                          }

                          NRFWriteCSN(0);

                          NRFStatus = transferSPI(0x20+0x10); // start write to TX address

                          for (index = 0; index < AddressLength; index++)

                          {

                              transferSPI(Address[index]);

                          }

                          NRFWriteCSN(1);

                          return(0);

                      }

                       

                      function NRFGetTXAddress(MaxAddressLength, Address)

                      {

                          var index;

                          var actual_length;

                          actual_length = NRFReadRegister(3);

                          actual_length = actual_length + 2;

                          if (actual_length > MaxAddressLength)

                              return -1;

                          NRFWriteCSN(0);

                          NRFStatus = transferSPI(0x10); // start read from TX address

                          for (index = 0; index < actual_length; index++)

                          {

                              Address[index] = transferSPI(0xff);

                          }

                          NRFWriteCSN(1);

                          return(0);

                      }

                      function NRFEnableTXMode()

                      {

                          NRFWriteRegister(0,0x0a); // enable CRC, power up

                      }

                      function NRFEnableRXMode()

                      {

                          NRFWriteRegister(0,0x0b); // enable CRC, power up, RX mode

                      }

                      function NRFWriteData(Length, Data)

                      {

                          var index;

                          if (Length > 32)

                              return -1; // too long

                          NRFWriteCE(0);

                          NRFWriteRegister(0x07,0x70); // clear RX_DR,TX_DS,MAX_RT bits

                          NRFEnableTXMode();

                          NRFWriteCSN(0);

                          NRFStatus = transferSPI(0xa0); // start write to TX buffer

                          for (index = 0; index < Length; index++)

                          {

                              transferSPI(Data[index]);

                          }

                          NRFWriteCSN(1);

                          NRFWriteCE(1);   

                          console.log("Sending..");

                          NRFEnableRXMode();

                      }

                      function NRFReadData(MaxLength,Data)

                      { // data is assumeed to be in data pipe 1

                          var available_bytes;

                          var index;

                          var Length;

                          available_bytes=NRFReadRegister(0x12); // find out how many bytes are available in P1

                          if (available_bytes == 0)

                              return 0;

                          NRFWriteCSN(0);

                          NRFStatus = transferSPI(0x61); // start read from RX buffer

                          if (available_bytes > MaxLength)

                              Length = MaxLength;

                          else

                              Length = available_bytes;

                          for (index = 0; index < Length; index++)

                          {

                              Data[index]=transferSPI(0xff);

                          }

                          NRFWriteCSN(1);

                          return Length;

                      }

                      function printRegisters()

                      {

                          var regnum;

                          for (regnum = 0;regnum < 0x20; regnum++)

                          {       

                              var hexstring= NRFReadRegister(regnum).toString(16);

                              console.log(regnum.toString(16) + " : " + hexstring);

                          }

                      }

                      /* The main body of the program follows. 

                      * The NRF is initialized with correct addresses etc and is periodically

                      * polled to see if there is any data available in the RX FIFO

                      * If there is data it is read and a byte is sent back

                      */

                      function poll()

                      {

                          // check to see if there is any received data

                          if ((NRFReadRegister(0x7) & 0x40) > 0)

                          {

                              // Got data!

                              console.log("Got data");

                              var RXData = new Buffer(10);

                              NRFReadData(10,RXData);

                              console.log(RXData);

                              NRFWriteRegister(0x07,0x70); // clear status flags

                              RXData[1]=~RXData[0];    // send back some 'dummy' data

                              NRFWriteData(10,RXData);

                             

                          }

                          setTimeout(poll,50);

                      }

                       

                      NRFinit();

                      NRFSetRXAddress0(5,DESTINATION_ADDRESS); // set auto ack address = destination

                      NRFSetTXAddress(5,DESTINATION_ADDRESS);     // set destination address

                      NRFSetRXAddress1(5,SOURCE_ADDRESS);         // set source address

                      console.log("Switching to RX mode");

                      NRFFlushTX();

                      NRFFlushRX();

                      NRFEnableRXMode();

                      NRFWriteCE(1);

                      printRegisters();

                      poll();