nRF24L01 and Interrupts

RS_JimRS_Jim Posts: 1,347
edited 2020-03-17 - 14:37:19 in Propeller 1
Jesse (avsa242) has written an excellent Driver and Demo program for the nRF24. After a bunch of issues with trying to compile the demo program with bst, I got the demo up and running. watching the receiver output in the demo program, the demo program displays the receiver continuously and you only see “valid” data for one line when data is transmitted. The driver has an interrupt enable call that I am not understanding. The data sheet states that the nRF chip default condition enables all interrupts. I would like to use WAITPNE instruction at the beginning of the receive loop so that only the latest transmission is displayed. I don’t have a scope so I can watch the pin while the program is running, so I don’t know if in fact Jesse has disabled interrupts on startup or he is using his function to disable unwanted interrupts. Anyone understand this better than me?


  • Hi Jim,
    Interrupts aren't something I'd really implemented fully within the driver. I gave the ability to set which events would trigger an interrupt, with the IntMask method, but there's no facility for monitoring whether an interrupt has occurred, via the dedicated IRQ pin. The driver does implement discrete methods for reading the same status bits, though:
    PayloadReady(): New RX data ready
    PayloadSent(): Data was sent
    MaxRetransReached(): TX retransmits reached maximum limit

    Each of those can be used to get the current status by calling them with any value other than -1 or 1 (TRUE), or to clear the interrupt, call them with -1 or 1.
    I don't explicitly set an enabled interrupt mask in the driver anywhere, so the driver starts up with whatever state the chip was already in (the datasheet shows all three IRQs are enabled by default).

    As for monitoring the IRQ line using waitpne/pe instructions, I haven't used it myself, but this is probably the more reliable way to go on the P1 because I realize you could potentially miss an event trying to read the status over SPI.
    The datasheet says the IRQ line is active low (0). Are you waiting for this state and not high (1)?
    I can try this out in a bit to play along and see if there's a bug somewhere...

  • Thanks Jesse for your reply. My thought was to insert the WAITPNE instruction at the beginning of the receive loop and wait for the INT pin to go low before reading the output of the receiver fifo buffer. That way, only valid info is being passed on to subsequent operations such as motor control. My plan is to use the nRF for control of a robot. The joysticks on transmit side would send their position data via the nRF24 and the receiver would pass the info to the various motors, starting with the wheels and eventually controlling an arm with 6 or so degrees of freedom.
  • Jim,

    Ohhh, I see. In that case then, unless I'm misunderstanding how your RC system works, I don't think you'd have to use interrupts to achieve this. The nRF24's aren't like the "bare-metal" packet radio transceivers like a CC1101, SX1231, etc. where as long as they receive a signal strong enough, data is received into the FIFO (even if it's just background noise or traffic not intended for it).

    With a nRF24, the receive FIFO is only filled with data if:
    * A transmitter sent it to a pipe address that your receiver has a matching address to
    * The CRC check passes
    * The payload length from the transmitter has to match the length the receiver's pipe was set to (unless you're using the DynamicPayload feature?)

    So really, it would just depend on validating the payload received from your robot controller. Do you find you're receiving packets even if the transmitter isn't powered on?
  • I added a small interrupt service routine to the non-shockburst receive demo (attached) - it just sits in another cog waiting for the IRQ pin to go low. When it does, it lights up an LED. When the IRQ pin is no longer asserted - it goes low again.
    This is also PropTool/PST compatible - no preprocessor code.
  • Cool,I will look at this first chance I get. What made me think about this, was that I was observing the data output of the Shockburst demo version. I would have many lines of screen print, then one line of real data from the transmitter. What I saw the receiver print out would have many lines with no usable data and then 1 line of the transmitted data followed with many lines of garbage.
  • Hmmm, interesting. If anything, the Shockburst demos should show the most robust communications. Have you changed any of the default settings (such as enabling CRC checks)? If you don't mind, and you have a chance, would you also be willing to share a screenshot of it when it happens?
  • Jesse,
    I looked at your interrupt code, used you INT_PIN designation and my pin number, copied the line involving the waitPNE , used parts of your setup routine to establish the correct I/O and vola, it worked! This is all done without starting a new cog. I am attaching two log files, one without interrupt control and one with. You can see why I wanted to implement the ISR. These files are from text in OpenOffice and PDF.
  • Jim,
    Glad it worked! So, you're just using the waitpxx statements in your main loop somewhere? Typically it'd live in a separate cog so the main cog can be free to do the application-level stuff, but if it works, it works! The way the output is formatted in those that the way any of my demos are showing up? They shouldn't be if you're using one of the -PST demos with the Propeller Tool terminal...or if you're using one of the other ones with any ANSI-compatible terminal. If you've modified them purposely that's another thing, though ;) - I just wasn't able to decipher the output clearly and wanted to know if they're giving you trouble.

  • Jesse,
    The output capture was using using a terminal program like Minicom. or Teraterm in the VT100 mode. I did not wish to sort out whether the data that I was receiving from the receiver was valid or not. As you can see from the log file(reduced from 64 pages) there are at least 32 reads of invalid information before I get the data I want. Halting the read function until the receiver actually has something to say, saves trying to make some kind of determination as to the validity of the incoming data. The wait until an interrupt makes that all really easy. I probably don’t even need a method to do the pause, just a WAITPNE inline with the fetching code. Thanks for showing how to use the “pipes” as I can use that to easily sort out from which control a command is coming.
Sign In or Register to comment.