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

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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:

Rich (BB code):
define osc 4


 a var byte
 csn var portc.4
transmit var portc.3
so var portc.2
si var portc.1
sck var portc.0
high csn
pause 100
low transmit

low csn
shiftout si, sck, 1, [%00100000, %00010010]
high csn
pause 5
'low csn
'shiftout si, sck, 1, [%00110000, "aaaaa"]
'high csn 
'pause 5
low csn
shiftout si, sck, 1, [%00110001, %00000001]
high csn 

pause 5

  do
 low csn
shiftout si, sck, 1, [%10100000, %00000001]
high csn

high transmit
pause 10
low transmit
pause 1000

 low csn
shiftout si, sck, 1, [%10100000, %00000010]
high csn

high transmit
pause 10
low transmit
pause 1000

 low csn
shiftout si, sck, 1, [%10100000, %00000011]
high csn

high transmit
pause 10
low transmit
pause 1000
 
 
  
  
  
  loop
RX code:

Rich (BB code):
high portc.5
 a var byte
 b var byte
 c var byte
 d var byte
 e var byte
 f var byte
 csn var portc.3
receive var portc.4
so var portc.2
si var portc.1
sck var portc.0
low receive
high csn
pause 100


pause 5
'low csn
'shiftout si, sck, 1, [%00101010, "aaaaa"]
'high csn 
'pause 5
low csn
shiftout si, sck, 1, [%00110001, %00000001]
high csn 
pause 5
low csn
shiftout si, sck, 1, [%00100000, %00000011]
high csn


pause 50
low csn
shiftout si, sck, 1, [%00010001]
shiftin so, sck, 0, [a]
high csn
pause 50
low csn
shiftout si, sck, 1, [%00001010]
shiftin so, sck, 0, [b, c, d, e]
high csn

pause 50
f = "a"
serout portc.5, 0, [12]
 pauseus 60
 serout portc.5, 0, ["reg:", #a, " ", #b, " ", #c, " ", #d, " ", #e, " ", #f]
 pauseus 40
 pause 500


high receive


 

  do
 low receive
 pause 2 
  low csn
shiftout si, sck, 1, [%01100001, 0]
shiftin so, sck, 0, [a, b, c, d, e, f]
high csn
 pause 2
high receive



pause 500
  
  


  serout portc.5, 0, [12]
 pauseus 60
 serout portc.5, 0, ["rx:", #a, " ", #b, " ", #c, " ", #d, " ", #e, " ", #f]
 pauseus 40
  
  pause 20
 
 
  
  loop
 
Last edited:

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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:

Rich (BB code):
low csn
shiftout si, sck, 1, [%10100000, 1, 2, 3, 4, 5]
high csn

high transmit
pause 1
low transmit
pause 500
receive code:

Rich (BB code):
low csn
shiftout si, sck, 1, [%01100001, 1, 1, 1, 1, 1]
shiftin so, sck, 0, [a, b, c, d, e] 
high csn
also tried:

Rich (BB code):
low csn
shiftout si, sck, 1, [%01100001, 1, 1, 1, 1, 1]
shiftin so, sck, 0, [a]
shiftin so, sck, 0, 
shiftin so, sck, 0, [c]
shiftin so, sck, 0, [d]
shiftin so, sck, 0, [e]
high csn
 

nickelflipper

Joined Jun 2, 2010
280
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.
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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.
 

nickelflipper

Joined Jun 2, 2010
280
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?
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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.
 

nickelflipper

Joined Jun 2, 2010
280
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:
Rich (BB code):
1.  Is IRQ pin low?
  a.  wait 10 ms   'i.e. for ack to be sent
  b.  CE = 0
  c.  SPI Read (b'00000111', var)  'read status register
  d.  var = var & b'01110000'  'mask to see if interrupt occurred
  e.  Is var = ! b'00001110'  '???
            1.  SPI Write (0xb'00100111', b'01110000')  'clear the status register interrupts
  f.  SPI Read (b'01100001', payload)  'read R_rxpld register
  g.  CE = 1
  h.  Print payload out on LCD etc.
  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.
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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.
 
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:
Rich (BB code):
SPI_rfWrite(W_txpld, pyld)
'--OR--
SPI_rfRead(R_rxpld, pyld)        'Word value
...
...
...
sub SPI_rfWrite (addr, payload as word)
CSN = 0
SPI_Xfer(addr)
For clocks = 1 to 16
    If payload.15 = 1 Then
        MOSI = 1
    Else
        MOSI = 0
    End if
    SCK = 1
    SCK = 0
    Rotate payload Left Simple
Next
CSN = 1
end sub

sub SPI_rfRead (addr, payload as Word)
CSN = 0
SPI_Xfer(addr)
For clocks = 1 to 16
    If MISO = 1 Then
        payload.15 = 1
    Else
        payload.15 = 0
    End if
    SCK = 1
    SCK = 0
    Rotate payload Left Simple
Next
CSN = 1
end sub

sub SPI_Xfer(xfer)
For clocks = 1 to 8
    If xfer.7 = 1 Then
        MOSI = 1
    Else
        MOSI = 0
    End if
    Rotate xfer Left Simple
    SCK = 1
    If MISO = 1 Then
        xfer.0 = 1
    Else
        xfer.0 = 0
    End If
    SCK = 0
Next
end sub
 
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.
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
test transmit code:

Rich (BB code):
low csn
 shiftout si, sck, 1, [%10100000, a, b2, "xefrtghy"]   
 high csn
test receive code:
Rich (BB code):
low csn
shiftout si, sck, 1, [%01100001]
shiftin so, sck, 0, [a, b, c, d, e, f, g, h, i, j]
high csn
Everything comes out just right. All I did was remove the dummy 1's after the read command.
 
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).
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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.
 
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.
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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.
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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.
 

Thread Starter

rudyauction8

Joined Jan 27, 2012
250
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.
 
Top