Driver - Nordic nRF24L01+ wireless module driver

Interesting for some reason the code page doesn’t link back to this thread.

So after fiddling with the code/electronics, I finally figured out why my tests were not working. The battery in the KeyFob appears dead. :frowning: Why didn’t sparkfun include a litlte led that lights up when data is transmitted, we may never know. I’m going to get a new battery (soon) and will try again.

I got a new battery, and the solution still doesn’t work. going to put it down again for a while.

@ kurtnelle Could you post your source code?


using System;
using System.Text;
using System.Threading;
using GHIElectronics.NETMF.FEZ;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace KeyFob
{
    public class Program
    {
        public static void Main()
        {
            Gralin.NETMF.Nordic.NRF24L01Plus _radio = new Gralin.NETMF.Nordic.NRF24L01Plus();
            _radio.Initialize(SPI.SPI_module.SPI2, (Cpu.Pin)11, (Cpu.Pin)1, (Cpu.Pin)12);
            _radio.Configure(Encoding.UTF8.GetBytes("KEYIN"), 2);
            _radio.Enable();
            _radio.OnDataReceived += new Gralin.NETMF.Nordic.NRF24L01Plus.OnDataRecievedHandler(_radio_OnDataReceived);
            Thread.Sleep(Timeout.Infinite);
        }

        static void _radio_OnDataReceived(byte[] data)
        {
            throw new NotImplementedException();
        }

    }
}

I’m basically looking for an exception when I press the button.

When the keyfob is press it sends data to a fixed address… unfortunately that address is not “KEYIN” :wink: Try the value as EriSan500 suggested:

_radio.Configure(new byte[] {0xE7,0xE7,0xE7,0xE7,0xE7}, 2);

Ok it put in that value and it didn’t work. How do I know if the Nordic radio is connected properly?

It seems that the address that is set isn’t being read back. This is from the raw project that I downloaded. What could be the cause of that?

As I mentioned in previous post, I’m not sure what will happen if you communicate between two radios with different settings. I guess not all of them need to be the same but the question is which one. Please change the driver source to use 8bit CRC:

private void SetReceiveMode()
...
[b]0[/b] << Bits.CRCO
...

and turn off auto ACK for pipes:

public void Configure(byte[] address, byte channel)
...
[b]0[/b] << Bits.DPL_P0 |
[b]0[/b] << Bits.DPL_P1
...

If this doesn’t work then we can try to disable dynamic payload length…

Is it bad that I can’t get the address back?

What do you mean by that exactly ?

Can you make a test and try to send data from one FEZ to another? This would prove your modules and wiring are ok. I have also added two simple methods to the API that will allow you to get/set channel value. Just use them to read the channel value and it will also prove that the module is working correctly (download the latest source from codeplex).

@ Gralin, I’ll try it out, but it may be possible that the device is damaged. So worst case is that I have to purchase 2 more and test them between my Fezes That’s what I’ll do if this address test doesn’t work.

Dear Gralin:

1.Do you have plan to provide the driver of Nordic nRF24L01+ for Gadgeteer?

  1. I am thinking to design a new board that can connect the nRF24L01+ and Xbee simultaneously.
    Then I can do mixed wireless sensor networks.
    But I am considering two approaches.
  2. A arduino shield based board.
    The nRF24L01+ and Xbee can be inserted to this board simultaneously and then can connect to Netduino or Panda II,
  3. A Individual board that allows the FEZmini, nRF24L01+and Xbee connect to it simultaneously.

How do you think, or do you know any product like I am thinking?

Thanks

@ Tzu Hsuan, I think a gadgeteer driver from nRF24L01+ would fit perfectly. There is not too much work to be done:

  • create gadgetter module template for this driver and use the existing code
  • create prototype board that has the S connector and 2x4 connector for the module (or you can solder the nRF24L01+ chip one the board but that requires some knowledge as you need also remeber about the antena). Something similar to this:

http://nrf24l01.codeplex.com/wikipage?title=Wire%20modules%20to%20boards

I want to helpe with the XBee gadgeteer driver first and hope that someone could make this for me. I have contributed the basic driver so its downhill from this point. As for your device, maybe you could use a gadgeteer mainboard and attatch XBee and nRF24L01+ as modules when those are completed ??

Thank you Gralin:

The gadgeteer can be a good base station or a router, but be an end device node, it seems more expensive and higher power consumption. So I am trying to design an wireless end device node for my project.
For Nordic nRF24L01+, I have more questions.
1.How do you synchronize multiple nRF24L01+ modules if you don’t have GPS?
2. Does your driver can read the RSSI value? The RSSI is useful for some applications.

Thanks for your help.

I find a Pdf for nRF24L01 VS CC2500, may useful for someone.
http://www.rfinchina.com/UploadDocFiles/20100710123812656.pdf
This doc. shows that the nRF24L01 don’t provide the RSSI.

The nRF24L01+ doesn’t have RSSI.

No RSSI. The only thing that is available is a one bit value that tells you if the signal is less or more than -64 dBm (RDP - Received Power Detector)

Dear Gralin:
I test your code, but not work yet.
I use two domino boards .
I just modify the SampleApp.CS to send simple string.
When I start debugging , an unhandled exception occurs on

Debug.Print("I am " + new string(Encoding.UTF8.GetChars(myAddress)));

Then I comment this code, the debugging pass.
But the output shows " Send failed!".



using System;
using System.Text;
using System.Threading;
using GHIElectronics.NETMF.Hardware;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;

namespace Gralin.NETMF.Nordic
{
    public class SampleApp
    {
        private readonly Cpu.Pin _chipEnablePin;
        private readonly Cpu.Pin _chipSelectPin;
        private readonly Cpu.Pin _interruptPin;
        private readonly OutputPort _led;
        private readonly NRF24L01Plus _module;
        private readonly Random _rand;
        private readonly SPI.SPI_module _spi;
        private DateTime _lastActivity;
        private byte _token;
        private byte _delay;
        private byte[] _myAddress;
        private byte[][] _otherBoards;
        

        public SampleApp()
        {
            Debug.EnableGCMessages(true);

            switch (SystemInfo.OEMString)
            {
                case "GHI Electronics, LLC":
                    switch ((Fez)SystemInfo.SystemID.Model)
                    {
                        case Fez.Mini:
                            _chipSelectPin = (Cpu.Pin)11; // FEZ_Pin.Digital.UEXT5
                            _interruptPin = (Cpu.Pin)43;  // FEZ_Pin.Interrupt.UEXT10
                            _chipEnablePin = (Cpu.Pin)1;  // FEZ_Pin.Digital.UEXT6
                            _spi = SPI.SPI_module.SPI1;
                            _led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, true); // FEZ_Pin.Digital.An0
                            break;

                        case Fez.Domino:
                            _chipSelectPin = (Cpu.Pin)11; // FEZ_Pin.Digital.UEXT5
                            _interruptPin = (Cpu.Pin)12;  // FEZ_Pin.Interrupt.UEXT10
                            _chipEnablePin = (Cpu.Pin)1;  // FEZ_Pin.Digital.UEXT6
                            _spi = SPI.SPI_module.SPI2;
                            _led = new OutputPort((Cpu.Pin)20, false); // FEZ_Pin.Digital.Di0
                            Debug.Print("find device");
                            break;

                        case Fez.Cobra:
                            _chipSelectPin = (Cpu.Pin)75; // FEZ_Pin.Digital.UEXT5
                            _interruptPin = (Cpu.Pin)26;  // FEZ_Pin.Interrupt.UEXT10
                            _chipEnablePin = (Cpu.Pin)48; // FEZ_Pin.Digital.UEXT6
                            _spi = SPI.SPI_module.SPI2;
                            _led = new OutputPort((Cpu.Pin)46, false); // FEZ_Pin.Digital.IO46
                            break;

                        default:
                            throw new NotSupportedException("Unknown board!");
                    }
                    break;

                case "Netduino Mini by Secret Labs LLC":
                    // this example will be extended to Netduino family
                    throw new NotSupportedException("Netduino mini is not yet supported!");

                default:
                    throw new NotSupportedException("Unknown board!");
            }

            _module = new NRF24L01Plus();
            _rand = new Random();
        }

        public void Run()
        {
            const byte channel = 10;

            // all addresses need to have the same length
            var fez1 = Encoding.UTF8.GetBytes("Fez1");
            var fez2 = Encoding.UTF8.GetBytes("Fez2");
          

            // here we determine on which device the code is running on
          

                       // case Fez.Domino:
                            _myAddress = fez1;
                            _otherBoards = new byte[2][];
                            _otherBoards[0] = fez2;                                               
                        
            // here we attatch event listener
            _module.OnDataReceived += OnReceive;
            _module.OnTransmitFailed += OnSendFailure;
            _module.OnTransmitSuccess += OnSendSuccess;

            // we nned to call Initialize() and Configure() befeore we start using the module
            _module.Initialize(_spi, _chipSelectPin, _chipEnablePin, _interruptPin);
            _module.Configure(_myAddress, channel);

            // to start receiveing we need to call Enable(), call Disable() to stop/pause
            _module.Enable();
            // example of reading your own address
            var myAddress = _module.GetAddress(AddressSlot.Zero, 5);
            //Debug.Print("I am " + new string(Encoding.UTF8.GetChars(myAddress)));          
            Send();
        }
                     
        private void OnSendSuccess()
        {
            _led.Write(false);
        }

        private void OnSendFailure()
        {
            Debug.Print("Send failed!");
            Send();
        }

        private void OnReceive(byte[] data)
        {
            Debug.Print("Token = " + data[0] + ", Delay = " + data[1]);
            _lastActivity = DateTime.Now;
            _token = (byte) (data[0] + 1);
            _delay = data[1];
            Send();
        }

        private void Send()
        {
           
            SendTokenToNextBoard();
        }
               
        private void SendTokenToNextBoard()
        {
            _led.Write(true);

            // delay added to see LED blink
            // the _delay value is 0...255
            Thread.Sleep(1000);
            byte[] data = Encoding.UTF8.GetBytes("test");
            _module.SendTo(_otherBoards[0], data);
        }
    }
}


new string(Encoding.UTF8.GetChars(myAddress))

This will throw exception if the myAddress array contains bytes other than ASCII ones. In your example you are setting 4 bytes addresses (“Fez1”) and this line

var myAddress = _module.GetAddress(AddressSlot.Zero, 5);

is reading 5 bytes. My guess is you either get an extra zero at the end or your module is not connected properly and you get a series of zeros. Please make a breakpoint here and see the value of myAddress.

Another thing is, do you change this lines before deploying to different boards:

                            _myAddress = fez1;
                            _otherBoards = new byte[2][];
                            _otherBoards[0] = fez2;    

Do you plug in only one Domino at a time? Visual Studio may act weird when two USBizi devices are connected at the same time. Even if you check to deploy to one VS can deploy to other. The same about project, even if one project is active VS can deploy the other. That’s why i always plug one device at a time and have only one project loaded in VS (besides library projects).