nrf24l01 problems, tx giving max_rt error, what am I missing

Discussion in 'The Projects Forum' started by rudyauction8, Feb 4, 2014.

  1. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    I got a pair of nrf24l01's on ebay a couple months ago, spent a couple days working with them with absolutely no success and put them in my parts box until earlier today (yesterday - its 4:30 in the morning) when I decided to give them one more shot. I found many errors in my code and added a few parts to the circuit but after 7 hours the farthest I have gotten is writing and reading the registers successfully (confirmed the correct values were getting written using my LCD) and getting a max_rt interrupt on the tx side while getting a solid "0" output on the rx side. I have a 16x2 LCD on the rx and an LED on each interrupt pin. If it makes any difference they are less than a quarter inch apart on the breadboard. The tx is supposed to send 1, 2, 3 with a 1 second pause between each number in a continuous loop. Using picbasic pro and 16f630 microcontrollers. I must be missing something, maybe I need to write another register or there's a typo that I've missed???

    instructions I've been using:
    http://www.diyembedded.com/tutorials/nrf24l01_0/nrf24l01_tutorial_0.pdf

    TX code:

    Code ( (Unknown Language)):
    1.  
    2. define osc 4
    3.  
    4.  
    5.  a var byte
    6.  csn var portc.4
    7. transmit var portc.3
    8. so var portc.2
    9. si var portc.1
    10. sck var portc.0
    11. high csn
    12. pause 100
    13. low transmit
    14.  
    15. low csn
    16. shiftout si, sck, 1, [%00100000, %00010010]
    17. high csn
    18. pause 5
    19. 'low csn
    20. 'shiftout si, sck, 1, [%00110000, "aaaaa"]
    21. 'high csn
    22. 'pause 5
    23. low csn
    24. shiftout si, sck, 1, [%00110001, %00000001]
    25. high csn
    26.  
    27. pause 5
    28.  
    29.   do
    30.  low csn
    31. shiftout si, sck, 1, [%10100000, %00000001]
    32. high csn
    33.  
    34. high transmit
    35. pause 10
    36. low transmit
    37. pause 1000
    38.  
    39.  low csn
    40. shiftout si, sck, 1, [%10100000, %00000010]
    41. high csn
    42.  
    43. high transmit
    44. pause 10
    45. low transmit
    46. pause 1000
    47.  
    48.  low csn
    49. shiftout si, sck, 1, [%10100000, %00000011]
    50. high csn
    51.  
    52. high transmit
    53. pause 10
    54. low transmit
    55. pause 1000
    56.  
    57.  
    58.  
    59.  
    60.  
    61.   loop
    62.  
    RX code:

    Code ( (Unknown Language)):
    1.  
    2. high portc.5
    3.  a var byte
    4.  b var byte
    5.  c var byte
    6.  d var byte
    7.  e var byte
    8.  f var byte
    9.  csn var portc.3
    10. receive var portc.4
    11. so var portc.2
    12. si var portc.1
    13. sck var portc.0
    14. low receive
    15. high csn
    16. pause 100
    17.  
    18.  
    19. pause 5
    20. 'low csn
    21. 'shiftout si, sck, 1, [%00101010, "aaaaa"]
    22. 'high csn
    23. 'pause 5
    24. low csn
    25. shiftout si, sck, 1, [%00110001, %00000001]
    26. high csn
    27. pause 5
    28. low csn
    29. shiftout si, sck, 1, [%00100000, %00000011]
    30. high csn
    31.  
    32.  
    33. pause 50
    34. low csn
    35. shiftout si, sck, 1, [%00010001]
    36. shiftin so, sck, 0, [a]
    37. high csn
    38. pause 50
    39. low csn
    40. shiftout si, sck, 1, [%00001010]
    41. shiftin so, sck, 0, [b, c, d, e]
    42. high csn
    43.  
    44. pause 50
    45. f = "a"
    46. serout portc.5, 0, [12]
    47.  pauseus 60
    48.  serout portc.5, 0, ["reg:", #a, " ", #b, " ", #c, " ", #d, " ", #e, " ", #f]
    49.  pauseus 40
    50.  pause 500
    51.  
    52.  
    53. high receive
    54.  
    55.  
    56.  
    57.  
    58.   do
    59.  low receive
    60.  pause 2
    61.   low csn
    62. shiftout si, sck, 1, [%01100001, 0]
    63. shiftin so, sck, 0, [a, b, c, d, e, f]
    64. high csn
    65.  pause 2
    66. high receive
    67.  
    68.  
    69.  
    70. pause 500
    71.  
    72.  
    73.  
    74.  
    75.   serout portc.5, 0, [12]
    76.  pauseus 60
    77.  serout portc.5, 0, ["rx:", #a, " ", #b, " ", #c, " ", #d, " ", #e, " ", #f]
    78.  pauseus 40
    79.  
    80.   pause 20
    81.  
    82.  
    83.  
    84.   loop
    85.  
     
    Last edited: Feb 9, 2014
  2. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    Update: I got them to communicate the 1,2,3 message but with a 1 second pause it would freeze after ~10-15 seconds, I changed it to half second pause and now it works OK.

    However when I try a 5 byte payload sending 1,2,3,4,5 then 5,4,3,2,1 then 3,3,2,3,3 with half second gap I can only get the last byte from the receiver, and the freeze up starts again.

    EDIT I fixed up the freezing problem but still can't get the whole 5 bytes out of the rx. The last byte (5 in the code below) shows up in every variable. What am I doing wrong?

    Transmit code:

    Code ( (Unknown Language)):
    1.  
    2. low csn
    3. shiftout si, sck, 1, [%10100000, 1, 2, 3, 4, 5]
    4. high csn
    5.  
    6. high transmit
    7. pause 1
    8. low transmit
    9. pause 500
    10.  
    receive code:

    Code ( (Unknown Language)):
    1.  
    2. low csn
    3. shiftout si, sck, 1, [%01100001, 1, 1, 1, 1, 1]
    4. shiftin so, sck, 0, [a, b, c, d, e]
    5. high csn
    6.  
    also tried:

    Code ( (Unknown Language)):
    1.  
    2. low csn
    3. shiftout si, sck, 1, [%01100001, 1, 1, 1, 1, 1]
    4. shiftin so, sck, 0, [a]
    5. shiftin so, sck, 0, [b]
    6. shiftin so, sck, 0, [c]
    7. shiftin so, sck, 0, [d]
    8. shiftin so, sck, 0, [e]
    9. high csn
    10. [/b]
     
  3. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    In the receive code I would try polling the nrf Status register every so often (say 100ms?) and wait for the received data flag. Clear the flag bit if it isn't done so by reading the register. Then read the rcv'd data register and stash the data byte into a buffer. Continue on polling till you have read all five bytes. Then print out the buffer(s) on the terminal or lcd.
     
  4. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    That's one of the things I've tried, still just get the last byte 5 times. I'm almost ready to give up and send 5 single packets but that would slow down my code significantly.

    The tutorial says to send the read data register instruction with 1 dummy byte for every byte I want to read. It doesn't matter what the dummy bytes are or even how many I send I still get only the last byte.
     
  5. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    First off, I have to say these nrf2401(+) modules are the most frustrating things to work with ever. Huge library full of defines and subs. Second it's been a couple of years since I have worked with them.

    Debugging with lcd and a terminal attached to the master and slave helped a lot. I used the interrupt method over polling, but shouldn't make much difference.

    Using the 250kbps rate will help give any sort of distance, around 20+ feet line of sight, with chip board antenna.

    One thing I can see from the code is that the payload width is being set to one byte. I think at one time I had been transmitting a word variable for a ds1820b, so the payload width was set to 2. This seems to follow the results observed?
     
  6. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    In the code I first listed the payload width was 1 byte but when I tried sending more than one I made sure to change it. I've tried 2 and 5 so far without luck, I know the registry is set right because it won't receive a 1 byte packet once setup for a 5 byte payload.
     
  7. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    Sorry for throwing darts, hoping for a solution to your problem. Persistence will overcome all odds.

    In my case the receive code checked for these things inside the Do Loop:
    Code ( (Unknown Language)):
    1. 1.  Is IRQ pin low?
    2.   a.  wait 10 ms   'i.e. for ack to be sent
    3.   b.  CE = 0
    4.   c.  SPI Read (b'00000111', var)  'read status register
    5.   d.  var = var & b'01110000'  'mask to see if interrupt occurred
    6.   e.  Is var = ! b'00001110'  '???
    7.             1.  SPI Write (0xb'00100111', b'01110000')  'clear the status register interrupts
    8.   f.  SPI Read (b'01100001', payload)  'read R_rxpld register
    9.   g.  CE = 1
    10.   h.  Print payload out on LCD etc.
    11.   i.  wait 500 ms  
    I'm not in a position to recreate the project. Looks like I felt it necessary to clear the interrupts, as stated earlier.
     
  8. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    The only interrupt flag I clear is the max_rt on the tx. You think if I try clearing it after reading each byte I'll be able to read the whole payload? I'll give it a try. After all, it's 20 below with windchill so I'll be working on this the rest of the night.
     
  9. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    Tried reading a byte, clearing interrupt and reading another byte, no luck.
     
  10. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    Got it to work, I didn't send any dummy bytes and I got all of the data out. Weird.
     
  11. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    I am not clearing the interrupt flags each byte but before each payload read in the rcv routine. Not using PBPro, so I will show my word size (two byte) SPI Write/Read routines if could be any help?

    Haven't really looked at the tx code yet. I did flushtx before main or do-loop though.

    Here's the psuedo code for the word payload subs:
    Code ( (Unknown Language)):
    1. SPI_rfWrite(W_txpld, pyld)
    2. '--OR--
    3. SPI_rfRead(R_rxpld, pyld)        'Word value
    4. ...
    5. ...
    6. ...
    7. sub SPI_rfWrite (addr, payload as word)
    8. CSN = 0
    9. SPI_Xfer(addr)
    10. For clocks = 1 to 16
    11.     If payload.15 = 1 Then
    12.         MOSI = 1
    13.     Else
    14.         MOSI = 0
    15.     End if
    16.     SCK = 1
    17.     SCK = 0
    18.     Rotate payload Left Simple
    19. Next
    20. CSN = 1
    21. end sub
    22.  
    23. sub SPI_rfRead (addr, payload as Word)
    24. CSN = 0
    25. SPI_Xfer(addr)
    26. For clocks = 1 to 16
    27.     If MISO = 1 Then
    28.         payload.15 = 1
    29.     Else
    30.         payload.15 = 0
    31.     End if
    32.     SCK = 1
    33.     SCK = 0
    34.     Rotate payload Left Simple
    35. Next
    36. CSN = 1
    37. end sub
    38.  
    39. sub SPI_Xfer(xfer)
    40. For clocks = 1 to 8
    41.     If xfer.7 = 1 Then
    42.         MOSI = 1
    43.     Else
    44.         MOSI = 0
    45.     End if
    46.     Rotate xfer Left Simple
    47.     SCK = 1
    48.     If MISO = 1 Then
    49.         xfer.0 = 1
    50.     Else
    51.         xfer.0 = 0
    52.     End If
    53.     SCK = 0
    54. Next
    55. end sub
    56.  
     
  12. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    HaHa, late as usual, good going. I think maybe my examples may be showing the same thing that you have stumbled on?

    I am (and other folks) are curious to to see the syntax used in your successful SPI Write and Read routines.
     
  13. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    test transmit code:

    Code ( (Unknown Language)):
    1. low csn
    2.  shiftout si, sck, 1, [%10100000, a, b2, "xefrtghy"]  
    3.  high csn
    test receive code:
    Code ( (Unknown Language)):
    1. low csn
    2. shiftout si, sck, 1, [%01100001]
    3. shiftin so, sck, 0, [a, b, c, d, e, f, g, h, i, j]
    4. high csn
    Everything comes out just right. All I did was remove the dummy 1's after the read command.
     
  14. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    Thanks, now that I see the new syntax, that seems to make a lot more sense.

    Let us know if you think of something clever when the transmitter loses contact with the receiver (my last stumble before shelving project). My transmitter wasn't able to pair up with rx, without a hard reset (power off then on).
     
  15. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    I'm not using any freq hopping or anything, just default freq and settings, so I mask all interrupts on the tx except the max_rt and hook the interrupt to an LED. Then I clear it about 1/4 second after sending the packet. When the LED's flashing there's no signal, when it's solid there's signal. That's more than I expected to get from these so I'm happy with it. Also my range on the lowest power setting is still ~20 feet which is about what I'll need. I haven't tested it on full power yet.
     
  16. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
    Aha, maybe I forgot to constantly clear max_rt then on the tx. I like the led idea, and could give that a go when I get back to them, thanks.

    20 foot range certainly seems really good at default settings.

    Wow these modules seem impossibly cheap now, close to $1.00 ea. range in small quantities. I think I was paying around $5 a module a couple of years ago.
     
  17. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    I've been getting 20 feet on min. power. I don't know about default (full) power, I haven't had a chance to test it yet. I got the pair for about $6 on ebay. Where are you seeing them for $1? By the way, mine are the ready to go boards with built in antennas, not just the bare chips.
     
  18. nickelflipper

    Active Member

    Jun 2, 2010
    280
    35
  19. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    That explains a lot, I never order international. I hate waiting a month to get my stuff. I got mine shipped from the US, and for what they are $3 is still a good price.
     
  20. rudyauction8

    Thread Starter Member

    Jan 27, 2012
    252
    2
    New problem: I've had everything working fine now for a while, but today I got some interference from my wireless routers so I decided to change the address for the first time. No matter what 5 bytes I write I lose the link, but if I leave the addresses at their default values everything works.
     
Loading...