Servtes 0 Posted March 2, 2015 Share Posted March 2, 2015 Thanks!!!!!!!! Now function very well with 2553 and 2452 Things what I do not made: 2553 ---> jumper "HW UART" - MISO P1.6 - MOSI P1.7 2452----> jumper "SW UART" - MISO P1.7 - MOSI P1.6 Thank you very much for your help! Quote Link to post Share on other sites
ecrampton 0 Posted March 5, 2015 Share Posted March 5, 2015 I read in the ENRF24 code that AutoAck is not enabled when in 250kbps mode. Is that an implementation restriction or is that a hardware restriction? I don't remember reading that in the data sheet and I have run the pure C implementation of the msprf24 library and I feel like I was able to use AutoAck at that speed. But maybe I am missing something. Thanks. Quote Link to post Share on other sites
spirilis 1,265 Posted March 5, 2015 Author Share Posted March 5, 2015 I read in the ENRF24 code that AutoAck is not enabled when in 250kbps mode. Is that an implementation restriction or is that a hardware restriction? I don't remember reading that in the data sheet and I have run the pure C implementation of the msprf24 library and I feel like I was able to use AutoAck at that speed. But maybe I am missing something. Thanks. My understanding is it's a hardware limitation although not explicitly defined in the datasheet ... however there is a subtle wording in the datasheet that might imply it IMO. I have never seen it work correctly with my own modules, i.e. I have never sent data at 250Kbps to a receiver turned off or out of range and actually seen it "fail", the only real indicator I have as to whether or not it works. It always replies that TX succeeded. Looks like I implemented Enrf24 to prevent you from using it at 250Kbps. If you have a solid example of autoack actually working - i.e., you have sent data at 250Kbps with my msprf24 library with autoack enabled and found it to actually FAIL when the receiver isn't turned on - then maybe all my modules are some Chinese knockoff silicon (quite possible as I've read recently) and the real chip (expensive) actually implements it :-) If that's the case then I'll make a modification to allow this in Enrf24... Quote Link to post Share on other sites
Servtes 0 Posted March 6, 2015 Share Posted March 6, 2015 Hi, I Quote Link to post Share on other sites
mcafzap 2 Posted March 11, 2015 Share Posted March 11, 2015 Just a word about using this with interrupts... . Using the interrupt to trigger a receive routine saves having to check (via SPI) on the state of the input buffer of the 24L01. However, if elsewhere in your program you transmit data, an interrupt will also occur when the transmit buffer is empty. In short, your interrupt routine must check whether you are transmitting or receiving because reading the input buffer whilst transmitting really messes things up. I apologise if some find this obvious, but HTH Steve Quote Link to post Share on other sites
spirilis 1,265 Posted March 11, 2015 Author Share Posted March 11, 2015 Just a word about using this with interrupts... . Using the interrupt to trigger a receive routine saves having to check (via SPI) on the state of the input buffer of the 24L01. However, if elsewhere in your program you transmit data, an interrupt will also occur when the transmit buffer is empty. In short, your interrupt routine must check whether you are transmitting or receiving because reading the input buffer whilst transmitting really messes things up. I apologise if some find this obvious, but HTH Steve Definitely something to keep in mind if you are using the interrupt function to wake the MCU out of sleep (using wakeup() in complement to having put the chip to sleep with sleep(), sleepSeconds() or suspend() previously). Fwiw, take a look at the .available() function and its argument - you can pass it (true), e.g. radio.available(true) to have it "shortcut" check the transceiver by doing a digitalRead() on the IRQ pin, and going no further (no SPI I/O) if the IRQ pin isn't reading LOW. The default argument is false, i.e. go all the way over SPI to verify there's nothing pending. So there is no reason to employ an ISR with this library if your primary reason is to avoid extraneous SPI I/O. Quote Link to post Share on other sites
mcafzap 2 Posted March 11, 2015 Share Posted March 11, 2015 The main reason I use interrupts is to transmit many more than 32 bytes. When the device has emptied its transmit buffer the IRQ only goes low very briefly, so polling for it won't work AFAIK. Pseudo code: flag =1; radio.print(block1); radio.flush(); while (flag) ; //.. loop/repeat ad infinitum Int flag = 0; You can do a similar thing for the RX interrupt - set a flag and let the main loop handle it later. Quote Link to post Share on other sites
spirilis 1,265 Posted March 11, 2015 Author Share Posted March 11, 2015 The main reason I use interrupts is to transmit many more than 32 bytes. When the device has emptied its transmit buffer the IRQ only goes low very briefly, so polling for it won't work AFAIK. Pseudo code: flag =1; radio.print(block1); radio.flush(); while (flag) ; //.. loop/repeat ad infinitum Int flag = 0; You can do a similar thing for the RX interrupt - set a flag and let the main loop handle it later. Yeah ... Not sure though why you need to do that, flush() doesn't return until it's handled the TX interrupt. So .flush() is a blocking call. From Enrf24.cpp line 363 in Enrf24::flush(): while (digitalRead(_irqPin) == HIGH) // Wait until IRQ fires ; // IRQ fired _maintenanceHook(); // Handle/clear IRQ Quote Link to post Share on other sites
mcafzap 2 Posted March 11, 2015 Share Posted March 11, 2015 Unfortunately you are absolutely correct! My problem was caused by allowing the receive routine to be triggered by the TX buffer empty signal, hence my original post. Thank-you very much for that. Quote Link to post Share on other sites
spirilis 1,265 Posted March 11, 2015 Author Share Posted March 11, 2015 Unfortunately you are absolutely correct! My problem was caused by allowing the receive routine to be triggered by the TX buffer empty signal, hence my original post. Thank-you very much for that. Hmm, do you think there is some internal flagging I should do within the library to prevent this? Sounds like a reentrancy problem actually ... where the TX IRQ may fire an interrupt routine which may try to do some nRF24L01+ I/O that it shouldn't be doing. Quote Link to post Share on other sites
mcafzap 2 Posted March 12, 2015 Share Posted March 12, 2015 Having spent some time thinking about this, I'm undecided. Simply setting a flag before transmitting and clearing it when done, does the trick. Testing this flag in the interrupt routine prevents the reading of data. It would be unnecessary if interrupts are not used. (I needed to use interrupts to minimise power.) BTW, thanks for your efforts - it has saved me a lot of time despite my problems. Steve spirilis 1 Quote Link to post Share on other sites
ecrampton 0 Posted April 10, 2015 Share Posted April 10, 2015 Spirilis, Speaking on the use of low power and interrupts, I was curious why the energia library doesn't use the interrupts and instead polls the pins. In your C library that I have used I was able to go into a low power mode and wait for the nrf24 to wake me up. In the energia it doesn't seem to allow you do to that as easily. Is there any reason for the difference in the way you wrote the Energia library vs the C library? Quote Link to post Share on other sites
ecrampton 0 Posted April 10, 2015 Share Posted April 10, 2015 I should have read the beginning of this topic before asking the questions as it seems at the time of writing there was not a good way to handle that in Energia. I may be wrong, but now we should be able to use suspend() with wakeup() to get the same functionality as the c library. Is there any plans to rewrite any of this to better handle the IRQ from the nrf24l01? Quote Link to post Share on other sites
spirilis 1,265 Posted April 10, 2015 Author Share Posted April 10, 2015 I should have read the beginning of this topic before asking the questions as it seems at the time of writing there was not a good way to handle that in Energia. I may be wrong, but now we should be able to use suspend() with wakeup() to get the same functionality as the c library. Is there any plans to rewrite any of this to better handle the IRQ from the nrf24l01? So my position on this is - The library shouldn't handle that, the user is perfectly capable of registering the nRF24 IRQ pin with their own simple handler using attachInterrupt(). That handler can then set a flag and run wakeup() to signal your main loop to check the nRF24. More importantly, you DON'T want an IRQ ISR handler contacting the nRF24 over SPI - because what happens if your nRF24 receives a packet and fires the IRQ in the middle of you doing SPI I/O with, say, an LCD display? (a great example since LCD display writes often entail very lengthy and chatty SPI transactions and depending on the application, require periodic changes/updates, thus raising the probability of a conflict) More on this topic here - http://dorkbotpdx.org/blog/paul/spi_transactions_in_arduino Energia does not support Paul's new SPI Transaction feature, so there is no "safe" way to implement in-ISR SPI I/O. So an idiomatic way to approach this might be something like this: Enrf24 radio(5, 6, 7); void setup() { SPI.begin(); radio.begin(); radio.enableRX(); attachInterrupt(7, wake_on_rf); } volatile boolean rf_pending = false; void loop() { // blah blah do something blah blah // radio.available() won't actually run if rf_pending is false if (rf_pending && radio.available()) { // blah blah do something RF-related blah blah rf_pending = false; } // blah blah do something else blah blah // go to low-power sleep suspend(); } void wake_on_rf() { rf_pending = true; wakeup(); } kimppi 1 Quote Link to post Share on other sites
ecrampton 0 Posted April 10, 2015 Share Posted April 10, 2015 Awesome, thanks for the reply and the example code. My only thought on this would be in any type of ISR handler you should only be doing the bare minimum. I would hope no libraries would do a SPI transaction from inside an interrupt routine. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.