Search code examples
c#arduinoraspberry-pi3windows-10-iot-core

Communication between Arduino and Raspberry Pi using nRF24L01p


Arduino Connection Pi Connection

I want to set up the communication between Arduino and Raspberry Pi(running win10 iot) using nRF24L01p module. I use "IS_nRF24L01p" nuget package as driver for the module. My arduino is sending a "Hello World" string. The RPi is a receiver in this case and the program just to check whether or not their communication is established. But I couldnt that. Is it because of the event of data received is not triggered? Or is it the configuration is not correct. Thanks in advance for any help.

The Transmitter (Arduino) code

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8);

const byte rxAddr[6] = "00001";

void setup()
{
  Serial.begin(9600);
  radio.begin();
  radio.setRetries(15, 15);
  radio.setChannel(10);
  radio.openWritingPipe(rxAddr);
  radio.stopListening();
}

void loop()
{
  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));

  delay(1000);
  Serial.println("Sent."); // TO check whether the data is sent.

}

The Receiver (Raspberry Pi) code

using System;
using Windows.UI.Xaml.Controls;
using Windows.Devices.Spi;
using IS_nRF24L01p;
using System.Threading.Tasks;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409

namespace New
{

    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public nRF24L01P nRf24 = new nRF24L01P();
        public MainPage()
        {
            this.InitializeComponent();
            setup();

        }



        private void setup()
        {
            System.Diagnostics.Debug.WriteLine("Initialize MTPNordic");
            nRf24.InitNordicSPI(new SpiConnectionSettings(0), 3000000, 12, 13);
            RFConfiguration();
            }

        private void RFConfiguration()
        {
            byte configByte;
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.RF_CH, new byte[] { 10 });

            configByte = 0;
            nRf24.SetRegisterBit(ref configByte, true, 0);
            nRf24.SetRegisterBit(ref configByte, true, 1);
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.SETUP_AW, new byte[] { configByte });

            configByte = 0;
            nRf24.SetRegisterBit(ref configByte, true, 1);
            nRf24.SetRegisterBit(ref configByte, true, 2);
            nRf24.SetRegisterBit(ref configByte, false, 3);
            nRf24.SetRegisterBit(ref configByte, true, 5);
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.RF_SETUP, new byte[configByte]);

            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.SETUP_RETR, new byte[] { 0x23 });
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.FEATURE, new byte[] { System.Convert.ToByte(Math.Pow(2, 2)) });
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.DYNPD, new byte[] { 0x3F });
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.EN_AA, new byte[] { 0x1 });
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.TX_ADDR, new byte[] { 0x30, 0x30, 0x30, 0x30, 0x31 });
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.EN_RXADDR, new byte[] { 0x3 });

            SetAsPRX();
            nRf24.SetChipEnable(true);
            Task.Delay(1);
            System.Diagnostics.Debug.WriteLine("Finish RFConfiguration()");
        }

        private void SetAsPRX()
        {
            byte configByte;
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.RX_ADDR_P0, new byte[] { 0x30, 0x30, 0x30, 0x30, 0x31 });

            configByte = 0;
            nRf24.SetRegisterBit(ref configByte, true, 0);   
            nRf24.SetRegisterBit(ref configByte, true, 1);     
            nRf24.SetRegisterBit(ref configByte, true, 2); 
            nRf24.SetRegisterBit(ref configByte, true, 3);
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.CONFIG, new byte[] { configByte });
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.STATUS, new byte[] { 0xE });

            byte[] StatusBuffer = null;
            nRf24.FlushRXFIFO();
            StatusBuffer = nRf24.ReadRegister(IS_nRF24L01p.Common.Registers.STATUS);
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.STATUS, new byte[] { System.Convert.ToByte(StatusBuffer[0] | 0x40) });
            System.Diagnostics.Debug.WriteLine("Finish SetAsPrx()");
        }

        private void nRf24_OnDataReceived(object sender, nRF24L01P.DataReceivedEventArgs e)
        {
            int PayloadLength = e.Payload.Length;
            string ReceivedString = "Data Received.";
            System.Diagnostics.Debug.WriteLine(ReceivedString); // TO check if the program enter this function == Data Received
        }

    }
}

Update From Debug Output

'New.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Data\Programs\WindowsApps\Microsoft.NET.CoreRuntime.2.1_2.1.26124.5_arm__8wekyb3d8bbwe\System.Private.CoreLib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\entrypoint\New.exe'. Symbols loaded.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Runtime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\WinMetadata\Windows.winmd'. Module was built without symbols.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\mscorlib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Runtime.InteropServices.WindowsRuntime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Runtime.WindowsRuntime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Runtime.WindowsRuntime.UI.Xaml.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Collections.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Threading.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\IS_nRF24L01p.dll'. Cannot find or open the PDB file.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Private.Uri.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Diagnostics.Debug.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Threading.Tasks.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Initialize MTPNordic
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\Microsoft.VisualBasic.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\netstandard.dll'. Module was built without symbols.
'New.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Data\Users\DefaultAccount\AppData\Local\DevelopmentFiles\b55d8275-9b3c-41b5-9a76-be21517cd280VS.Debug_ARM.New\System.Runtime.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Finish SetAsPrx()
Finish RFConfiguration()
The thread 0xf30 has exited with code 0 (0x0).

Solution

  • From the code you provided, i can not find the line to register the nRf24_OnDataReceived event handler. Please try to add the handler like following code.

        private void setup()
        {
            System.Diagnostics.Debug.WriteLine("Initialize MTPNordic");
            nRf24.InitNordicSPI(new SpiConnectionSettings(0), 3000000, 12, 13);
            nRf24.OnDataReceived += new nRF24L01P.OnDataReceivedEventHandler(nRf24_OnDataReceived);
            RFConfiguration();
        }
    

    Sorry for that i don't have a nRF24L01p module to test this issue. Please feel free let me know if it is helpful for you.

    UPDATE:

    The Transmitter (Arduino) code:

    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    
    RF24 radio(7, 8);
    const byte address[6] = "00001";
    
    void setup()
    {
      Serial.begin(9600);
      radio.begin();
      radio.setRetries(15, 15);
      radio.setChannel(10);
      radio.setPALevel(RF24_PA_MIN);
      radio.openWritingPipe(address);
      radio.stopListening();
    }
    
    void loop()
    {
      const char text[] = "Hello World";
      radio.write(&text, sizeof(text));
    
      delay(1000);
      Serial.println("Sent."); // TO check whether the data is sent.
    
    }
    

    The Receiver (Raspberry Pi) code:

        private void SetAsPRX()
        {
            byte configByte;
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.RX_ADDR_P1, new byte[] { 0xF0, 0xF0, 0xF, 0x0F, 0x0E1 });
    
            configByte = 0;
            nRf24.SetRegisterBit(ref configByte, true, 0);
            nRf24.SetRegisterBit(ref configByte, true, 1);
            nRf24.SetRegisterBit(ref configByte, true, 2);
            nRf24.SetRegisterBit(ref configByte, true, 3);
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.CONFIG, new byte[] { configByte });
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.STATUS, new byte[] { 0xE });
    
            byte[] StatusBuffer = null;
            nRf24.FlushRXFIFO();
            StatusBuffer = nRf24.ReadRegister(IS_nRF24L01p.Common.Registers.STATUS);
            nRf24.WriteRegister(IS_nRF24L01p.Common.Registers.STATUS, new byte[] { System.Convert.ToByte(StatusBuffer[0] | 0x40) });
            System.Diagnostics.Debug.WriteLine("Finish SetAsPrx()");
        }
    

    When the sender sends data, the address in the data packet adopts the address of the "TX_ADD". This address is one of several receiving channels(6 channels) of the receiving end. After receiving the data, the corresponding channel of the receiving end responds, and the address in the response packet is adopted. The address corresponding to the receiving channel is the sending channel address of the transmitting end, and the transmitting end uses channel 0 to answer the most as the default, so the channel 0 address of the transmitting end should be set as the sending channel address.

    It is best to use 1-5 channels for reception, because 0 channels will be used to receive the response when transmitting, and the address of a receiving channel of the other party will be written to the sending channel before sending data.