Looking for Faster Objects for Nordic Wireless Modules nRF24L01+ and nRF2401A

Duane DegnDuane Degn Posts: 10,296
edited 2020-03-07 - 18:10:22 in Propeller 1
Edit: See post #74 for the most recent driver.
You may want to compare the most recent driver to the earlier on in attached to
post #9.

There are two objects in the OBEX to use with these Nordic modules:
Nordic nRF2401 Rf Transceiver Handler
and
nRF24L01 driver and demo

Both of these objects use Spin to communicate with the transceivers.

I have a bunch of nRF2401A modules and at Leon's suggestion I purchased a couple of the newer nRFL01+ modules.

I found this old thread about Nordic modules. I was tempted to resurrect it but I "Want to make me some Propeller Code?" isn't a very helpful thread title.

I'm wondering if anyone else is using these modules and if they have faster objects.

These modules can communicate pretty fast. The nRF24L01+ can use SPI with a 10MHz clock. I'm pretty sure SPI with Spin doesn't come close to this speed.

If someone hasn't already made a faster version of these objects, I'll probably just adapt the SPI one to use the SPI_Asm object.

BTW, I also use XBees but these Nordic modules are generally less expensive and they are smaller than XBees so there are some applications where the Nordic modules are a better choice IMO.

Duane

Here's the datasheets on the two Nordic devices.
nRF24L01P_Product_Specification_1_0.pdf
nRF2401A.pdf

Edit(3/11/15): Warning, the code attached is an old version. There are better options available.
I plan to upload this program or an improved version to my GitHub account
If there isn't a replacement on GitHub send me a message and I'll make sure to upload the replacement code.
«13

Comments

  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-04-09 - 14:33:33
    I've been working on a driver for the nRF24L01+ modules.

    The one in the OBEX has a serious bug.

    After fixing the OBEX object and writing a transmit method I tried to increase the object's speed.

    I initially used the SPI_Asm object. I then modified the SPI_Asm object by taking out the delays.

    I'm attaching a demo that uses two instances of the driver to have one module communicate with a second one.

    This object has the basics to allow two modules to communicate. There are lots of improvements needed.

    I'd like to improve this driver so it has a FDX type interface. I also want to take advantage of the "Enhanced ShockBurst" mode of these modules.

    Another important feature is to make the object compatible with the older nRF2401A modules.

    I'm posting what I have so far in case anyone else wants to use these modules with a Propeller. This should make it relatively easy to get one module talking to another.

    NordicPlusPlusDemo110409i - Archive [Date 2011.04.09 Time 14.36].zip
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-04-16 - 14:13:48
    Help! I'm stuck.

    I can not get the the newer nRF24L01+ modules to communicate with the older nRF2401A modules.

    I've attached a test program that uses two Nordic modules to make sure they can communicate.

    The program can use any of three possible combinations of modules. Two new modules, two old modules or one new module and one old module.

    If I use two new modules or two old modules it works fine. My problem is when I try to use a new module and an old module.

    There's one constant to change "_CurrentConfig" in order to let the program know which combination of modules to use. This can be set to one of three values: _TwoNewModules, _TwoOldModules, _OneNewAndOneOld (0, 1, 2).


    These constants are located at the end of the constant section
      ' Module configuration enumeration
      #0, _TwoNewModules, _TwoOldModules, _OneNewAndOneOld
    CON  _CurrentConfig = _TwoNewModules  ' Change this to use a different combination of modules
    

    I thought I had all the registers set correctly to let the old and new communicate.

    I'm hoping someone will be willing to look this over and help me get this working correctly.

    Much of the driver code is based on C code Leon posted.

    I know Leon has used these modules before. Leon, do you have time to look at this?

    I'm pleased with how the driver is working with the newer modules. I'm still using the object from the OBEX to control the older modules.

    I have lots of older Nordic nRF2401A modules and I'd really like to get them to work with the new nRF24L01+ modules.

    Here's my latest code. I've tried to clean it up to make it easier to read.

    Thanks,

    Duane

    NordicPlusPlusDemo110416f - Archive [Date 2011.04.16 Time 14.53].zip

    Edit(3/11/15): Warning, the code attached is an old version. There are better options available.
    I plan to upload this program or an improved version to my GitHub account
    If there isn't a replacement on GitHub send me a message and I'll make sure to upload the replacement code.
  • LeonLeon Posts: 7,620
    edited 2011-04-16 - 14:20:17
    It's a long time since I've used the older nRF2401A modules (I've got two of them) and I've never tested interoperability with the nRF24L01. They are supposed to work together.according to the nRF24L01 data sheet, using the correct mode.
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-04-16 - 14:57:16
    I thought I had the configuration on the new modules set to work with the old ones.

    Here's the configuration data for the nRF24L01+
    ''------------------ Cofig settings for new nRF24L01+ modules ----------------------------------------
    '' ----------------- Keep below together and in order ------------------------------------------------
    configNew     byte %00111111 '%00111011  Register $00
                  ' use %00111111($3F)(2 bytes CRC) or %00111011($3B)(1 byte CRC)
                  ' when communicating with older nRF2401A modules
                  ' make sure this matches nRF2401A setting
                  ' %00001111($0F) future with more irq options
                  ' 7 only zero allowed, 6 Mask irq by RX_DR (1 = no irq), 5 Mask TX_DS, 4 Mask MAX_RT,
                  ' 3 Enable CRC, 2 CRC size (1 = 2 bytes), 1 1 = power up, 0 1 = PRX 0 = PTX
                  ' RX_DR Receive Data Ready
                  ' TX_DS Transmit Data Sent
                  ' MAX_RT Maximum Retries
                  byte $00 '$03 ' Register $01 Auto Acknowledge
                  ' use $00 when communicating with older nRF2401A modules
                  ' %00111111 future
                  ' 7:6 only %00, enable pipe 5 through 0
                  byte %00000011 ' Register $02
                  ' 7:6 only zero allowed, 5:0 enable rx addresses pipe 5:0
                  byte $03 ' Register $03 SETUP_AW setup Address Widths 
                  ' 7:2 only %000000, 1:0 %01 = 3 %11 = 5
                  byte $00 ' Register $04 SETUP_RETR Setup Auto Retransmission
                  ' use $00 when communicating with older nRF2401A modules     
                  ' %00101111 = 750us delay to retx, tx 15 tries
                  ' %01001111 = 1250us delay to retx, tx 15 tries
                  ' 7:4 ARD delay 1111 = 4000us, 3:0 retry count 0 - 15 (1111)
                  byte $02 ' Register $05 RF_CH RF Channel
                  ' 7 leave 0, 6:0 frequency channel
                  ' F = (2400 + RF_CH)MHz (both nRF24L01+ and nRF2401A modules)
                  byte $06 ' Register $06 RF_SETUP RF Setup
                  ' don't use 2Mbps when communicating with older nRF2401A modules
                  ' $06 = 1Mbps and full power
                  ' 7:6 %00 only, 5 RF_DR_LOW 1 = 250kbps use 0 for higher speeds, 4 leave %0
                  ' 3 1 = 2Mbps 0 = 1Mbps, 2:1 RF_POWER %11 = 0dBm (highest power), 0 don't care
                  ' Register $07 STATUS Status Register used below.
                  ' Register $08 OBSERVE_TX 7:4 lost packet count (read only),
                  ' 3:0 retransmitted packets count (read only).  I plan to use this
                  ' register's infomation in the future.
                  ' Register $09 RPD 7:1 reserved (read only), 0 Received Power Detector (read only)
                  ' Register $0A RX_ADDR_P0 39:0 Receive address pipe 0, 5 bytes maximum LSByte written first
                  ' used below rxAddress0 and rxAddress1
                  ' Register $0B RX_ADDR_P1 39:0 Receive address pipe 1
                  ' Register $0C RX_ADDR_P2 7:0 Receive address pipe 2
                  ' Register $0D RX_ADDR_P3 7:0 Receive address pipe 3
                  ' Register $0E RX_ADDR_P4 7:0 Receive address pipe 4
                  ' Register $0F RX_ADDR_P5 7:0 Receive address pipe 5
                  ' Register $10 TX_ADDR 39:0 Transmit address
    'configNew[7]
    rxPayload     byte 25 '32   ' Register $11 RX_PW_P0
                  ' This will need to be reduced to 25 (assuming 2 bytes CRC and 5 bytes address)
                  ' to work with older nRF2401 modules.
                  ' Newer nRF24L01+ modules can have payloads as large as 32 bytes.
                  ' 7:6 only zero allowed, 5:0 Number of bytes in RX payload in data pipe 0
                  ' (1 to 32)(0 = pipe not used)
                  ' Register $12 RX_PW_P1 7:6 only zero allowed,
                  ' 5:0 Number of bytes in RX payload in data pipe 1
                  ' (1 to 32)(0 = pipe not used)
                  ' Register $13 RX_PW_P2 7:6 only zero allowed,
                  ' 5:0 Number of bytes in RX payload in data pipe 2
                  ' Register $14 RX_PW_P3 7:6 only zero allowed,
                  ' 5:0 Number of bytes in RX payload in data pipe 3
                  ' Register $15 RX_PW_P4 7:6 only zero allowed,
                  ' 5:0 Number of bytes in RX payload in data pipe 4
                  ' Register $16 RX_PW_P5 7:6 only zero allowed,
                  ' 5:0 Number of bytes in RX payload in data pipe 5
                  ' Register $17 FIFO_STATUS 7 only zero allowed, 6 TX_REUSE (read only), 
                  ' 5 TX_FULL %1 = full (read only), 4 TX_EMPTY %1 = empty (read only),
                  ' 3:2 only zero allowed, 1 RX_FULL %1 = full (read only),
                  ' 0 RX_EMPTY %1 = empty (read only)
                  ' Register $1C DYNPD Enable dynamic payload length, 7:6 only zero allowed,
                  ' 5 DPL_P5 Enable dynamic payload length data pipe 5 (Requires EN_DPL and ENAA_5)
                  ' 4 DPL_P4 Enable dynamic payload length data pipe 4 (Requires EN_DPL and ENAA_4)
                  ' 3 DPL_P3 Enable dynamic payload length data pipe 3 (Requires EN_DPL and ENAA_3)
                  ' 2 DPL_P2 Enable dynamic payload length data pipe 2 (Requires EN_DPL and ENAA_2)
                  ' 1 DPL_P1 Enable dynamic payload length data pipe 1 (Requires EN_DPL and ENAA_1)
                  ' 0 DPL_P0 Enable dynamic payload length data pipe 0 (Requires EN_DPL and ENAA_0)
                  ' Register $1D FEATURE Feature Register 7:3 only zero allowed,
                  ' 2 EN_DPL Enables Dynamic Payload Length, 1 EN_ACK_PAY Enables Payload with ACK,
                  ' 0 EN_DYN_ACK Enables the W_TX_PAYLOAD_NOACK command
     
    '' ----------------- Keep above together and in order ------------------------------------------------             
    nordicStatus  byte %01000000 ' $40   %01110000   '$70
                  ' only zero allowed, Data Ready RX, TX ACK received, MAX_RT failed,
                  ' 3:1 Data pipe with payload %111 if empty (read only), 0 1= TX FIFO full (read only)
    '' ----------------- Keep below together and in order ------------------------------------------------             
    rxAddress0    byte $E7[5] ' Register $0A Receive address data pipe 0, LSByte first
    'rxAddress0    byte $CD, $E7, $E7, $E7, $CD ' Register $0A Receive address data pipe 0, LSByte first
    txAddress0    byte $E7[5] ' Register $10 Transmit address data pipe 0, LSByte first
    'txAddress0    byte $CD, $E7, $E7, $E7, $CD ' Register $10 Transmit address data pipe 0, LSByte first
    'txAddress0    byte $C2, $C2, $C2, $C2, $C2 ' Register $10 Transmit address data pipe 0, LSByte first
    '' ----------------- Keep above together and in order ------------------------------------------------             
    '' ----------------- Keep below together and in order ------------------------------------------------             
    rxAddress1    byte $E7[5] ' Register $0A Receive address data pipe 0, LSByte first
    'rxAddress1    byte $CD, $E7, $E7, $E7, $CD ' Register $0A Receive address data pipe 0, LSByte first
    txAddress1    byte $E7[5] '  Register $10 Transmit address data pipe 0, LSByte first
    'txAddress1    byte $CD, $E7, $E7, $E7, $CD '  Register $10 Transmit address data pipe 0, LSByte first
    'txAddress1    byte $C2, $C2, $C2, $C2, $C2 '  Register $10 Transmit address data pipe 0, LSByte first
    '' ----------------- Keep above together and in order ------------------------------------------------             
     
    

    I think the first six registers are he ones I need to worry about when using these with the older modules.

    And here's the configuration data to the nRF2401A
    nordicTx3     byte $E7, $E7, $E7, $E7, $E7, "tx3 to address$E7E7E7E7E7", 13, 0[14]   
     
    nordicConfig3 byte $C8  ' Data2 width (bits) excluding addr & crc (25 bytes) 
                  byte $C8  ' Data1 width (bits) excluding addr & crc (25 bytes)
                  byte $CD, $E7, $E7, $E7, $CD  ' Channel #2
                  'byte $CD, $E7, $E7, $E7, $CD  ' Channel #1      
                  byte $E7, $E7, $E7, $E7, $E7  ' Channel #1      
                  'byte $CD, $E7, $E7, $E7, $CD  ' Channel #1      
                  byte $A3  ' $A3 = %10100011
                  ' 7-2:address width(40), 1:CRC Mode(16), 0:CRC enable(on)
                  byte $6F  ' $6F = %01101111
                  ' 7:Dual Ch mode(off), 6:ShockBurst mode(on), 5:1m/250k bps(1mbps), 4-2:xtal sel(16Mhz), 1-0:rf Power(hi)
                  byte $05  ' $05 = %00000101
                  ' 7-1:RF channel(2), 0:RX enable(on=Rx mode)
    

    The older modules need the tx address to precede the payload. The new modules use a register for the tx address.

    I've tried various combinations of addresses without success.

    I've spent a lot of time reading the nRF24L01+ datasheet but I haven't read the nRF2401A nearly as much. I'm afraid it's time to read nRF2401A datasheet again.

    Thanks Leon for the original C code. It made this task a lot easier.
  • LeonLeon Posts: 7,620
    edited 2011-04-17 - 12:11:50
    I've just ordered four of these modules:

    http://cgi.ebay.co.uk/ws/eBayISAPI.dll?ViewItem&item=320674876163&ssPageName=STRK:MEWNX:IT

    The price is very good. They'll take a couple of weeks to arrive, as I went for the free postage option.

    I'll have to modify my PCB design slightly for the different connector.
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-04-18 - 18:54:49
    Wow, that's a great price.

    I think the same place is selling them to the states for $6.40. I might buy several of these.

    If anyone else is thinking about using these nRF24L01+ modules, the code I posted in #3 makes these relatively easy to use with the Propeller.

    I don't have the auto acknowledgment and resend features supported yet but you can use the code for two way communication.

    I'm taking some time off of working on this object but I plan to return to it and add some more features after a bit of a break.
  • koehlerkoehler Posts: 599
    edited 2011-04-19 - 16:49:35
    Cool thread and link.
    I'm getting 2 @$7 each with shipping from http://cgi.ebay.com/Mini-2-4Ghz-Wireless-NRF24L01-Transceiver-Module-/320608404697?pt=LH_DefaultDomain_0&hash=item4aa5c004d9
    Seems like he has a longer time on eBay.

    Is that an etched antenna?. Anyone know what the real-world range is with this type of set-up?
  • Duane DegnDuane Degn Posts: 10,296
    edited 2020-03-07 - 18:09:45
    Previously Post #9

    I've received a request to for a different demo program for this object. Here are a couple of new demos for the Nordic object.

    These demos will only work with the newer nRF24L01 modules.

    There is both a master demo and a slave demo.

    The master sends two bytes to the slave device. The slave device adds these two numbers together and sends the original two bytes with the sum back to the master device.

    I had the numbers sent as ASCII characters of hexadecimal numbers. I've recently been using this method with one of my robots so I used it here also.

    These demos use different pins than my earlier demo.

    I realize I've only looked at the output from the master board. Here's what I get in the PST window.
    Start of Nordic Demo (Master)
    Nordic Started
    rx address = $E7 $E7 $E7 $E7 $E7
    tx address = $E7 $E7 $E7 $E7 $E7Receiver (new module) configured.
    Status = %01100000
    Received from slave: $00 + $01 = $0001
    <$00><$00><$00><$00><$00><$00><$00>
    Status = %01100000
    Received from slave: $01 + $03 = $0004
    <$00><$00><$00><$00><$00><$00><$00>
    Status = %01100000
    Received from slave: $02 + $05 = $0007
    <$00><$00><$00><$00><$00><$00><$00>
    Status = %01100000
    Received from slave: $03 + $07 = $000A
    <$00><$00><$00><$00><$00><$00><$00>
    Status = %01100000
    Received from slave: $04 + $09 = $000D
    <$00><$00><$00><$00><$00><$00><$00>
    Status = %01100000
    Received from slave: $05 + $0B = $0010
    <$00><$00><$00><$00><$00><$00><$00>
    Status = %01100000
    Received from slave: $06 + $0D = $0013
    <$00><$00><$00><$00><$00><$00><$00>
    Status = %01100000
    
    As you can see, I've also outputted the value of the status register.

    The "<$00>" is part of the packet that wasn't used. I had the whole packet displayed. Any characters that aren't printable ASCII (or carriage return) characters are displayed as hexadecimal values.

    I just now successfully tested these demos out on two of my Propeller boards. I hope they work for you.

    Duane
    **** Warning Old Buggy Demos ****
    Nordic_nRF24L01_DemoSlave110505a - Archive [Date 2011.05.05 Time 19.14].zip
    Nordic_nRF24L01_DemoMaster110505a - Archive [Date 2011.05.05 Time 19.16].zip

    EDIT: I'm posting an update version of these demos. I've decided to leave the old demos in place.
    Here are the new ones:

    **** New Demos, As of 7/19/11 ****
    Nordic_nRF24L01_DemoMaster110719a - Archive [Date 2011.07.19 Time 12.21].zip
    Nordic_nRF24L01_DemoSlave110719a - Archive [Date 2011.07.19 Time 12.21].zip
    These demos have different pin assignments than the earlier ones.

    The new start method only uses one pointer.
    All the configuration information needs to be in the correct order.
    This order is different than the previous driver.

    Here's the output of the slave demo.
    Status = %01100000
    Received from master: Please add $B1 + $63
    Sending master following reply:
    $B1 + $63 = $0114
     
    Sent to master: $B1 + $63 = $0114
     
    Status = %01100000
    Received from master: Please add $B2 + $65
    Sending master following reply:
    $B2 + $65 = $0117
     
    Sent to master: $B2 + $65 = $0117
    

    Here's the ouput from the master demo.
    Sent to slave: Please add $B1 + $63
     
    Status = %01100000
    Received from slave: $B1 + $63 = $0114
     
    Sent to slave: Please add $B2 + $65
     
    Status = %01100000
    Received from slave: $B2 + $65 = $0117
    

    I matched the payload size to the size of the message so there aren't the extra zeros anymore.

    Duane

    Edit(3/11/15): Warning, the code attached is an old version. There are better options available.
    I plan to upload this program or an improved version to my GitHub account
    If there isn't a replacement on GitHub send me a message and I'll make sure to upload the replacement code.
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-28 - 11:06:57
    Hey have any of you who ordered the cheap Nordic devices off eBay had a chance to use them yet?

    I was going to order some from the link in post #8. Any reports on how they work?

    Leon, how did yours work?

    koehler, have you received the ones you ordered?

    Bill, are you reading this?

    I've personally just used the modules from SparkFun. I know they work well but I'd like to get a bunch of the cheaper ones, if they work.

    Duane
  • Bill HenningBill Henning Posts: 6,445
    edited 2011-06-28 - 11:10:46
    Hi Duane,

    I guess I am reading this :)

    I tried two cheapie Ebay modules so far, no dice. Since you have had success with the Sparkfun ones, I think I'll order a couple to play with.

    Bill

    Duane Degn wrote: »
    Hey have any of you who ordered the cheap Nordic devices off eBay had a chance to use them yet?

    I was going to order some from the link in post #8. Any reports on how they work?

    Leon, how did yours work?

    koehler, have you received the ones you ordered?

    Bill, are you reading this?

    I've personally just used the modules from SparkFun. I know they work well but I'd like to get a bunch of the cheaper ones, if they work.

    Duane
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-28 - 12:03:24
    Bill,

    Yeah, the ones at SparkFun work fine. I was hoping to buy a bunch of cheap ones off ebay and use one at each air vent in our house (automated temperature control stuff).

    Anyone else? Leon?

    Duane
  • LeonLeon Posts: 7,620
    edited 2011-06-28 - 12:20:19
    Sorry, I still haven't tried those cheap Chinese modules yet. I've designed a PCB for them, with a PIC.
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-28 - 12:33:38
    Leon, Let me know how they work when you get around to trying them out.

    Duane
  • LeonLeon Posts: 7,620
    edited 2011-06-28 - 12:40:31
    I'll get a couple of PCBs made. Actually, I only need one, because I have some of the Sparkfun modules working with PICs. This is what the board looks like:

    Wireless module.jpg


    I need to bring some of the PIC I/O out to pads, for interfacing sensors etc. on the prototyping area.
    1024 x 575 - 65K
  • Mark_TMark_T Posts: 1,981
    edited 2011-06-28 - 20:49:34
    I've bought some of the cheap eBay ones and they are identical to the 'real' ones - not clones as far as I can see.
  • Mark_TMark_T Posts: 1,981
    edited 2011-06-28 - 20:56:21
    Leon wrote: »
    It's a long time since I've used the older nRF2401A modules (I've got two of them) and I've never tested interoperability with the nRF24L01. They are supposed to work together.according to the nRF24L01 data sheet, using the correct mode.

    In particular you can't use 2Mb mode, nor the 'enhanced shockburst' packetizing (which is on by default and needs disabling in various ways with various config registers - auto reply must be switched off, packet id and crc fields must be correct and variable length packets must be disabled - not that I've the older ones to test against either.) I'm using them to pipe digital audio at 2Mb (which needs all the clever stuff disabled for throughput).
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-29 - 12:09:45
    Mark_T wrote: »
    I've bought some of the cheap eBay ones and they are identical to the 'real' ones - not clones as far as I can see.

    Mark,

    Can you go into more detail? Do remember the vendor on eBay you used?

    I'm not sure what you mean by "real" and "cloned". I think as long as a board uses the nRF24L01+ chip it's real.

    Duane

    Edit: Mark, what kind of microcontroller are you using with your modules?
  • LeonLeon Posts: 7,620
    edited 2011-06-29 - 12:13:51
    Bill,

    What exactly was the problem you had with those modules? Were they getting the SPI data and responding OK?
  • Bill HenningBill Henning Posts: 6,445
    edited 2011-06-29 - 12:39:35
    Hi Leon,

    They were not responding to SPI commands sent with the same code that worked for Duane.

    I have a couple of spare modules and will try again soon, this time under a logic analyzer - the price/performance on these modules is hard to ignore, therefore it is worth some effort :)
  • LeonLeon Posts: 7,620
    edited 2011-06-29 - 12:45:57
    With the Microchip MPLAB debugger and an ICD 3 I was able to check the SPI transfers with a simple test program and a scope. Is the problem with the SPI, or are they just not transmitting and receiving?
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-29 - 13:08:24
    Leon and Bill,

    I'm going add a basic test method to the demo I posted earlier. I noticed in the "Similar Threads," Leon made this suggestion before.

    I'm thinking I'll read the rx address from the module, then write a different address to it and read the address back. This should indicate if the Propeller is communicating with the Nordic device via SPI.

    I should have time to write the code now. I'm post it here when I'm done.

    Duane
  • LeonLeon Posts: 7,620
    edited 2011-06-29 - 13:22:19
    You've probably got my C code. I can post it here if not.
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-29 - 13:34:51
    Leon,

    My driver is based on the code you posted here.

    Do you have any code significantly different?

    Duane
  • LeonLeon Posts: 7,620
    edited 2011-06-29 - 13:39:34
    I meant this simple SPI test program:
    /*
    ** test.c
    ** SPI test program for PIC18F4520 and nRF24L01 or nRF24L01+
    ** Checks SPI comms between PIC and wireless chip
    ** 
    ** RA0	LED (output)
    ** RA1	PB (input)
    */
    
    #include <p18f4520.h>
    #include <spi.h>
    
    //function prototypes
    unsigned char spi_Send_Read(unsigned char);
    void dly(void);
    
    // Defines
    #define SPI_SCK		LATCbits.LATC3		// Clock pin, PORTC pin 3 
    #define SPI_SO		LATCbits.LATC5		// Serial output pin, PORTC pin 5 
    #define SPI_SI		PORTCbits.RC4		// Serial input pin, PORTC pin 4 
    #define SPI_CSN		LATCbits.LATC2		// CSN output pin, PORTC pin 2
    #define SPI_CE		LATCbits.LATC1		// CE output pin, PORTC pin 1
    #define SPI_IRQ		PORTBbits.RB0		// IRQ input pin, PORTB pin 0
    #define SPI_SCALE	4              		// postscaling of signal 
    #define LED			LATAbits.LATA0
    #define PB			PORTAbits.RA1
    
    
    // Macros
    #define nop() _asm nop _endasm
    
    void main(void)
    {
    	unsigned char status = 0;
    	unsigned char data[5];
    	int i;
    
    	// run internal oscillator at 8 MHz
    	OSCCON = OSCCON | 0b01110000;
    	while (!OSCCONbits.IOFS)	// wait for IOFS to go high
    		;
    
    	OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); //open SPI1
    	PORTA = 0x00;
    	ADCON1 = 0x0F;		// set up PORTA to be digital I/Os
    	TRISA = 0x02;		// PORTA<7.2,0> outputs PORTA<1> input
    	TRISCbits.TRISC3 = 0;	// SDO output
    	TRISCbits.TRISC5 = 0;   // SCK output
    	TRISCbits.TRISC2 = 0;	// CSN output
    	TRISCbits.TRISC1 = 0;	// CE output
    	SPI_CSN = 1;		// CSN high
    	SPI_SCK = 0;		// SCK low
    	SPI_CE	= 0;		// CE low
    	nop();
    
    	//write TX_ADDRESS register
    	SPI_CSN = 0;			//CSN low
    	spi_Send_Read(0x30);
    	spi_Send_Read(0x11);
    	spi_Send_Read(0x22);
    	spi_Send_Read(0x33);
    	spi_Send_Read(0x44);
    	spi_Send_Read(0x55);
    	SPI_CSN = 1;			//CSN high
    
    
    	//read TX_ADDRESS register
    	//Check that values are correct using the MPLAB debugger
    	SPI_CSN = 0;			//CSN low
    	status = spi_Send_Read(0x10);
    	data[0] = spi_Send_Read(0x00);	// 0x11
    	data[1] = spi_Send_Read(0x00);	// 0x22
    	data[2] = spi_Send_Read(0x00);	// 0x33
    	data[3] = spi_Send_Read(0x00);	// 0x44
    	data[4] = spi_Send_Read(0x00);	// 0x55
    	SPI_CSN = 1;					// CSN high
    
    	while (1)
    		;
    }
    
    
    unsigned char spi_Send_Read(unsigned char byte)
    {
    	SSPBUF = byte;	
    	while(!DataRdySPI())
    		;	
    	return SSPBUF;
    }
    
  • Bill HenningBill Henning Posts: 6,445
    edited 2011-06-29 - 13:41:54
    Leon & Duane:

    Bits were being sent to the module, it just was not responding. I checked my wiring about 100x, so I don't think that was the problem.

    It will be a few days before I can get a test setup running again for the nRF modules; I have some RoboProp work I must finish first.

    Just in case I got a bad batch of cheap modules, I will order some from SparkFun today.

    I appreciate the help guys, thanks.
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-29 - 13:45:21
    Leon,

    No, I didn't have that code. It's pretty much what I'm planning to do with the Propeller. I was going to use the RX address instead of the TX address. I don't think it matters. We just want to make sure we can communicate with the device.

    Thanks. Your C code really helped me get the hang of these modules.

    Duane
  • LeonLeon Posts: 7,620
    edited 2011-06-29 - 13:57:14
    By putting the reads/writes in a loop it should be possible to see the data with a scope.
  • Duane DegnDuane Degn Posts: 10,296
    edited 2020-03-07 - 18:16:53
    Here a simple test program to make sure the Nordic module and the Propeller are communicating via SPI.

    Here's the output to the debug window.
    Press any key to start test.
    Press any key to start test.
    Press any key to start test.
    Press any key to start test.
    Press any key to start test.
    Attempting to read rx address from module.
    rx address = $E7E7E7E7E7
    Attempting to write following rx address to module: $AABBCCDDEE
    Reading rx address from module: $AABBCCDDEE
    !!!!Success!!!!
    The rx address was successfully changed.
    The test rx address will not necessarily be the rx address used
    in communicating with other modules.
     
    Press any key to start retest.
     
    Attempting to read rx address from module.
    rx address = $AABBCCDDEE
    The present rx address is the same as the test address.
    Changing the test address from $AABBCCDDEE, to $BBCCDDEEFF
    Attempting to write following rx address to module: $BBCCDDEEFF
    Reading rx address from module: $BBCCDDEEFF
    !!!!Success!!!!
    The rx address was successfully changed.
    The test rx address will not necessarily be the rx address used
    in communicating with other modules.
     
    Press any key to start retest.
     
    Attempting to read rx address from module.
    rx address = $BBCCDDEEFF
    The present rx address is the same as the test address.
    Changing the test address from $BBCCDDEEFF, to $CCDDEEFF10
    Attempting to write following rx address to module: $CCDDEEFF10
    Reading rx address from module: $CCDDEEFF10
    !!!!Success!!!!
    The rx address was successfully changed.
    The test rx address will not necessarily be the rx address used
    in communicating with other modules.
     
    Press any key to start retest.
    

    To make sure the Propeller actually does write to the module, the program makes sure the information it plans to write isn't already present. If the current rx address is the same as the test rx address, then the test rx address is changed so we can be sure the data really was written.

    You can see this in the above output. The first time the test is run the rx address was different than the test address. The the test address had to be changed on the second test since it already matched what was stored in the rx address register.

    As you can see, the program continues to loop with the press of any key on the keyboard.
    Duane

    Edit: This original code had a bug in it. It worked in determining if the Prop was communication with the Nordic module. The program displayed the incorrect address after the second reading of the module.

    Here's the output.
    Press any key to start.
    Start of Nordic SPI Check
    This program does not communicate with other
    Nordic modules.  This just checks the SPI
    link between the Propeller chip and the
    attached Nordic module.
    Nordic Started
    Attempting to read rx address from module.
    rx address = $E7E7E7E7E7
    Attempting to write following rx address to module: $AABBCCDDEE
    Reading rx address from module: $AABBCCDDEE
    !!!!Success!!!!
    The rx address was successfully changed.
    The test rx address will not necessarily be the rx address used
    in communicating with other modules.
     
    Press any key to start retest.
    
    I unplugged the module and ran the test again.
     
    Attempting to read rx address from module.
    rx address = $0000000000
    Attempting to write following rx address to module: $AABBCCDDEE
    Reading rx address from module: $0000000000
    ** Failure **
    The rx address was NOT changed.
    The Propeller was not able to communicate with the
    Nordic module.
     
    Press any key to start retest.
    

    Here's the fixed program.

    Nordic_nRF24L01_SpiTest110719a - Archive [Date 2011.07.19 Time 13.35].zip

    This program uses an updated driver. The pin assignments are different than the original program I posted.

    Duane

    Edit(3/11/15): Warning, the code attached is an old version. There are better options available.
    Edit(3/7/20): I believe the best version of my driver available is attached to post #74. There are likely better versions available from other sources.
  • Mark_TMark_T Posts: 1,981
    edited 2011-06-29 - 23:19:47
    Duane Degn wrote: »
    Mark,

    Can you go into more detail? Do remember the vendor on eBay you used?

    I'm not sure what you mean by "real" and "cloned". I think as long as a board uses the nRF24L01+ chip it's real.

    Duane

    Edit: Mark, what kind of microcontroller are you using with your modules?

    I have two sets, one from ebay (http://cgi.ebay.co.uk/ws/eBayISAPI.dll?ViewItem&item=320696838110&ssPageName=STRK:MEWNX:IT) and one from mdfly. They look identical - under a lens there are some clues its a clone board for the ebay ones, such as slightly different ground vias and some tiny chinese lettering silk screened on the ebay ones.

    Actually a clone might have substandard aerial filter components so it might matter (also the board material matters for tuning the pcb antenna).

    I tested them at 2MB with no noticeable difference between real and ebay ones. The crystal accuracy doesn't matter at 2.4G anyhow with 1MHz channel spacing...

    I'll leave it to those who have a spectrum analyzer to really compare them thoroughly.

    Someone asked about range - I get about 8m at 2Mb rate, but with interference from a hifi audio sender (frequency hopping ISM) 250kb should get at least 10dB more

    I'm using propeller to interface of course! PASM for speed
  • Duane DegnDuane Degn Posts: 10,296
    edited 2011-06-30 - 08:55:29
    Mark, Thanks for the info.

    So did you write your own object? I don't suppose I could talk you into posting it?

    I was just adding up instructions in my SPI driver and I think it's sending data to the device at 3.6Mb/s (454.5kB/s) @80MHz. Since I'm using packets there is some overhead. I haven't tested what kind of continuous data rate I can get with these transceivers. So far I haven't needed much speed but it would be nice to know what they are capable of.

    I just ordered six of the transceivers you linked to on ebay. (The six cost less than buying two from SparkFun.)

    Duane
Sign In or Register to comment.