Problem with nRF24 module interrupt functionality

I have problem with nRF24 interrupt functionality as following I’d would be so thank you if you help me out or direct me to the proper post

My sketch pooling part is (in loop ) check the sensor value and send new update value to the client node while in interrupt event listen to new request form client for specific sensor vale and then request responded and back to loop again, but it seems interrupt handler not work as it expected and sometime it freeze and never back to loop again , maybe it because of write function instead of start write function or maybe I should mask the interrupt MASK_RX_DR Any help would really appreciated

Sensor  value [num];
Main()
{
Setting ();
Enable ACK ()
Disable dynamic payload();
Disable  Payload with ACK();
Attaché interrupt ();
}
Loop(){
Check  sensor();
Put  value  in sensor value arrey(); 
}
Interrupt  handler(){
If new request coming from client ? (RX_DR)
Stop listening ();
Send the requested sensor value ();
Start listening();
}

I never got the interrupt to work properly.

All in all, a real pain in the backside working with the NRF's

I tested quite a few from different suppliers and found some of them to be unreliable. I had a test environment and simply plugged a different NRF in and watched my traces. Transmission/receiving was unreliable with one batch - it was very slow. I would not have noticed had I not had a batch that worked considerably faster and reliably. I would have assumed my code was rubbish or that the devices simply unable to operate any faster, if it wasn't for the 'fast' batch to compare with.

The rubbish batch were almost identical to look at but the copper traces were not so 'clean' and the soldering was messy.

So be warned, perhaps your NRF is also C R A P.

Its some time ago I worked on these and will not be doing so again in the near future, if ever again, so cannot help you with anymore details. I would however suggest your code (pseudo) is too simplistic to allow someone to work out what might be going wrong. So, before you post in open forum I recommend more detail and perhaps also something about the wiring.

Good luck Alan

@mkeyno, you will need to provide your complete code if you want to get any useful assistance. The problems are often in the fine detail.

You have a single sentence in your post which runs over 4 lines of text. My brain can't manage that. Use shorter sentences. This is not meant to be an English lesson - I really don't understand what you wrote.

...R

I had a test environment and simply plugged a different NRF in and watched my traces. Transmission/receiving was unreliable with one batch - it was very slow.

How did you get to this conclusion? What tests did you made and with what equipment? I will not say nfr are perfect but they work fine in a small distance.They are a little difficult to program but that doesn't mean they are crap. I have one pair of nrf using the IRQ pin in one side to know when has some to read and works very well I write my own routines to deal it it since I found some weird things in ManiacBug lib.

Dear people thank you for your notes , my brief code just explain that, the plan is to listen to incoming package with interrupt event and manipulate sending new data in normal operation , how ever I posted my sensor code and router code as following; in router code new command send to sensor node and new update value send to upper layer node , while listening for interrupt from upper node(p1) and sensor node(p2-p5)
How ever after some interrupt my sketch freeze and stop every thing

My doubt is masking the interrupt in config registry for RX_DR TX_DS bit maybe help full and I don’t know whoever I should send the package and wait for interrupt TX_DS or just send it and wait for interrupt call

router node code

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//RF24( ce , cs );
RF24 radio(9,8);
const byte* TX={(byte*)"evreS"}; 
const byte* RX1={(byte*)"1edoN"};     
const byte* RX2={(byte*)"2Node"};
const byte* RX3={(byte*)"3Node"};
const byte* RX4={(byte*)"4Node"};
const byte* RX5={(byte*)"5Node"};
const byte* Address[]={RX1,RX2,RX3,RX4,RX5};
 
uint8_t        CSN[] = { 0,7,10,19}; //cumulative sensor node 
uint8_t       node[] = { 1,1,1,1,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4}; //cumulative sensor node 
uint8_t  sen_state[] = { 1,0,0,2,0,1,0,0,1,0,0,1,0,0,10,1,0,0,1,0}; //sensor state on this node 
uint16_t sen_value[] = { 0,1,99990,2,4532,0,1,2,4532,0,1,0,0,0,0,0,0,0,0}; //sensor value on this node 
uint8_t i;
uint8_t sen_num=sizeof(sen_state); 
uint16_t period=8000;
      
typedef struct Sensor_t{
  uint8_t SensorID;
  uint8_t NodeID;
  uint16_t Value;
  uint16_t Counter;
  byte type;
              Sensor_t():Counter(0),NodeID(0),SensorID(0),Value(0),type('S'){}
};
Sensor_t income,outcome;
/////////////////////////////////////////////////////////////////////////////
void setup(void)
{
 Serial.begin(57600);
 while(!Serial);
 printf_begin();
 Serial.printf("**************************************************\n\r");
 radio.begin();
 //listen to all pipe whereas pipe 1 listen to main node and the rest listen to related node
  radio.SendTo(TX);
  radio.ReadFrom(1,RX1);
  radio.ReadFrom(2,RX2);
  radio.ReadFrom(3,RX3);
  radio.ReadFrom(4,RX4);
  radio.ReadFrom(5,RX5);
 
 
 radio.setCRCLength(RF24_CRC_16); //RF24_CRC_DISABLED = 0, RF24_CRC_8=1, RF24_CRC_16=2
 radio.setAutoAck(1);//EN_AA Enable ‘Auto Acknowledgment’ setAutoAck(  pipe,  enable )
 radio.write_register(3,3);//SETUP_AW Setup of Address Widths 3,2,1=>5,4,3 byye
 radio.setRetries(15,15);//Auto Retransmit Delay, Auto Retransmit Count
 radio.setChannel(10);// 1--127
 radio.setDataRate(RF24_2MBPS);  //RF24_1MBPS = 0, RF24_2MBPS=1, RF24_250KBPS=2
 radio.setPALevel(RF24_PA_MAX);  //RF24_PA_MIN = 0,RF24_PA_LOW=1, RF24_PA_HIGH=2, RF24_PA_MAX=3, RF24_PA_ERROR
 radio.setPayloadSize(20); //1-32  set on reading pipe
 radio.enableDynamicPayloads();// Enable dynamic payload for all pipe EN_DPL@FEATURE & DYNPD
 radio.Set(0x1D,2,0);            //EN_DPL@FEATURE Disable dynamic payload throughout the system
 radio.enableAckPayload(); //enable ack payload and dynamic payload features (on pipes 0 & 1)
 radio.Set(0x1D,1,0); //Disable Payload with ACK
 radio.printDetails();
 Serial.printf("**************************************************\n\r");
 attachInterrupt(0, check_radio, FALLING);
 ////// initialization //////////////

}
/*******************************************************************************/
void loop(void){

for(i=0;i <sen_num; i++){
		//send new sensor value to the node
		if( sen_state[i]==2) { radio.stopListening();
							  outcome.NodeID  =node[i];
							  outcome.SensorID=i-CSN[node[i]]+1;
							  outcome.Value   =sen_value[i];
							  radio.SendTo(Address[node[i]]);
							  radio.startWrite(&outcome,sizeof(outcome));
							  radio.startListening();
							  }
		//send new sensor value to the main					  
		if( sen_state[i]==1) { radio.stopListening();
							  outcome.NodeID  =node[i];
							  outcome.SensorID=i-CSN[node[i]]+1;
							  outcome.Value   =sen_value[i];
							  radio.SendTo(TX);
							  radio.startWrite(&outcome,sizeof(outcome));
							  radio.startListening();
							  }
		}
}
/*******************************************************************************/
void check_radio(void)
{  
uint8_t status =radio.write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
   bool tx   = status & _BV(TX_DS);
   bool fail = status & _BV(MAX_RT);
   bool rx   = status & _BV(RX_DR);
uint8_t pipe = (status>>1) & B111;
if(fail) sen_state[i]=-1; //we successfully transmit the sensor value to node or main
if(tx  ) sen_state[i]=0;
if(rx){
		radio.read(&income,sizeof(income));
		if(pipe>1 && pipe<6){ // we received new update of sensor value related to nodes
		/*Store Value in router array*/  sen_value[income.SensorID+CSN[income.NodeID]-1]=income.Value;
		/*change the state sensor to 1*/ sen_state[income.SensorID+CSN[income.NodeID]-1] =1;
										// if(EnableDebug_Pin) printf("\n\r We received from node %d sensor %d value %d on pipe %\n\r",income.NodeID,income.SensorID,income.Value,pipe);
							}
							
		if(pipe==1)         { // we received new command for set sensor value of this router related nodes
		/*Store Value in router array*/  sen_value[income.SensorID+CSN[income.NodeID]-1]=income.Value;
		/*change the state sensor to 2*/ sen_state[income.SensorID+CSN[income.NodeID]-1] =2;
										// if(EnableDebug_Pin) printf("\n\r Requested came  from Main for node %d sensor %d value %d on pipe %\n\r",income.NodeID,income.SensorID,income.Value,pipe);
							}
		}
}

my sensor node

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//RF24( ce , cs );
RF24 radio(9,8);
const byte* server_p={(byte*)"1edoN"};// TX addresss
const byte* thispipe={(byte*)"evreS"};//RX address
uint16_t sen_value[] = { 0,1,99990,2,4532}; //sensor value on this node 
uint8_t  sen_state[] = { 1,-1,0,2,0};
uint8_t sensor_pin[] = { A0,A1,12,4};  
typedef struct Sensor_t{
  uint8_t SensorID;
  uint8_t NodeID;
  uint16_t Value;
  uint16_t Counter;
  byte type;
              Sensor_t():Counter(0),NodeID(4),SensorID(0),Value(0),type('S'){}
};
Sensor_t income,outcome;

uint16_t readSensor( uint8_t);
uint8_t i=0;

void setup(void)
{
 Serial.begin(57600);
 while(!Serial);
 printf_begin();
 Serial.printf("**************************************************\n\r");
 radio.begin();
 
 radio.SendTo(server_p);
 radio.ReadFrom(1,thispipe);
 // off the other pipe(2-5)
 radio.write_register(2,B00000011);
// radio.openWritingPipe(tx);
// radio.openReadingPipe(1,rx1);
 radio.setCRCLength(RF24_CRC_16); //RF24_CRC_DISABLED = 0, RF24_CRC_8=1, RF24_CRC_16=2
 radio.setAutoAck(0);//EN_AA Enable ‘Auto Acknowledgment’ setAutoAck(  pipe,  enable )
 radio.write_register(3,3);//SETUP_AW Setup of Address Widths 3,2,1=>5,4,3 byye
 radio.setRetries(15,15);//Auto Retransmit Delay, Auto Retransmit Count
 radio.setChannel(10);// 1--127
 radio.setDataRate(RF24_2MBPS);  //RF24_1MBPS = 0, RF24_2MBPS=1, RF24_250KBPS=2
 radio.setPALevel(RF24_PA_MAX);  //RF24_PA_MIN = 0,RF24_PA_LOW=1, RF24_PA_HIGH=2, RF24_PA_MAX=3, RF24_PA_ERROR
 radio.setPayloadSize(sizeof(outcome)); //1-32  set on reading pipe
 radio.enableDynamicPayloads();// Enable dynamic payload for all pipe EN_DPL@FEATURE & DYNPD
 radio.Set(0x1D,2,1);            //EN_DPL@FEATURE Disable dynamic payload throughout the system
 radio.enableAckPayload(); //enable ack payload and dynamic payload features (on pipes 0 & 1)
 radio.Set(0x1D,1,0); //Disable Payload with ACK
 radio.printDetails();
 Serial.printf("**************************************************\n\r");
 
   
 
 radio.startListening();
 attachInterrupt(0, request, FALLING);
  
}
void loop(void)
{
  
static uint16_t read =readSensor(A0); 
			 if(read!=sen_value[0]) {
									sen_value[1]=read;
									radio.stopListening();
									outcome.SensorID=(1);
									outcome.Value=read;
									radio.startWrite(&outcome,sizeof(outcome));
									radio.startListening();
								  }				
              if(sen_state[2]==1){
			                      radio.stopListening();
								  digitalWrite(12,sen_value[2]);
								  outcome.SensorID=(1);
								  outcome.Value=10;//digitalWrite(12,1);
								  radio.startWrite(&outcome,sizeof(outcome));
								  radio.startListening();
			                       }
 delay(10);  
}
/******************************************/
void request(void){  
uint8_t status = radio.write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
   bool tx   = status & _BV(TX_DS);
   bool fail = status & _BV(MAX_RT);
   bool rx   = status & _BV(RX_DR);
uint8_t pipe = (status>>1) & B111;
printf("\n\r%02d%02d%02d%02d",tx,fail,rx,pipe);
if(fail) sen_state[i]=-1; //we successfully transmit the sensor value to node or main
if(tx  ) sen_state[i]=0;
if(rx){
		radio.read(&income,sizeof(income));
		 // we received new update of sensor value related to nodes
		/*Store Value in router array*/  sen_value[income.SensorID]=income.Value;
		/*change the state sensor to 1*/ sen_state[income.SensorID] =1;
									//	 if(EnableDebug_Pin) printf("\n\r We received from node %d sensor %d value %d on pipe %\n\r",income.NodeID,income.SensorID,income.Value,pipe);
		}
}
						 
uint16_t readSensor( uint8_t s ){
    uint16_t total=0;
    for(int i=0;i<10;i++) total+=analogRead(s);
    return map(total/10, 0, 1023, 10, 1500);
   }

Can you describe (in English, not code) how your project is intended to work - what sends what to whom etc.

I don't understand the purpose of your interrupts. I have a wireless project with a Master and several slaves and no interrupts.

If you do need interrupts I would take all the code out of them except something like

void request() {
   interruptTriggered = true;
}

and then do all the other stuff in an ordinary function when it sees that interruptTriggered is true.

...R

Tnx robin

I want to create the tree network of sensor with three node type, Main node Router node And sensor node which is some sensor connected to the last one.

In sensor node part constantly sensor valve evaluate in loop function and when ever changes recorded then quickly send to router node Also sensor node as server listens to the request (if there is request) from router node (upper level) by interrupt event and when received the request to set sensor value (for example off the relay pin) or sending the value of specific sensor (for example pass the temp value) it quickly reply back in interrupt handler

In router node same scenario happened. each pipe considered for one sensor node and in loop function new update data for all sensor related to this node send it to the main node in upper level and such as server listens to the request (if there is request) from main node (upper level) by interrupt event and when received the request to set sensor value (for example off the relay pin ) or sending the value of specific sensor (for example pass the temp value ) it quickly assemble new package and send to the sensor node which is must go And so on

Occasionally All node must listen to the request event which is trigged by upper level

I don't see any reason to use interrupts in that situation, and using them introduces a lot of complexity and potential issues to be addressed.

Just design your application logic to be non-blocking, and include regular polling for incoming messages in your processing loop.

You mention 3 nodes but I think you are only using 2 Arduinos - it's a bit confusing.

Also, you are still writing huge sentences that my brain can't manage. Short sentences please.

Suppose (for discussion) there are two Arduinos A and B. Arduino A has the sensors connected to it and, when data is read from the sensor it sends data to Arduino B.

If Arduino B has no other task than to receive messages it can just listen continually without needing any interrupts.

Similarly, if Arduino A has nothing to do except receive data from a sensor it can easily spend all its time checking if the sensor has data available without needing to use interrupts.

How often does the sensor provide data? What causes it to produce data?

...R

HugoPT:

I had a test environment and simply plugged a different NRF in and watched my traces. Transmission/receiving was unreliable with one batch - it was very slow.

How did you get to this conclusion?
What tests did you made and with what equipment?
I will not say nfr are perfect but they work fine in a small distance.They are a little difficult to program but that doesn’t mean they are crap.
I have one pair of nrf using the IRQ pin in one side to know when has some to read and works very well
I write my own routines to deal it it since I found some weird things in ManiacBug lib.

The attached photo shows my test setup and some of the NRFs standing by waiting to be plugged in.

I wrote debug code to be output to the Serial monitor and had all three going into the same laptop (different COM ports obviously). Whilst I had timing figures in the output it was possible to see the difference in performance just by watching how fast, or not, the lines shot by (each event, send, receive and acknowledge making its own output line).

I wonder why you ask? Please tell us.

Also I stand by my comments about CRAP NRFs and if you read my message again you’ll see I say some may be crap and not all are crap. It would be hard for someone unfamiliar with the device to know if they were performing properly or not unless you did what I did and purchase a number from different suppliers and do back to back tests.

Hi @acboother,

Can you tell us what type nRF24L01 modules you tested? (Update, finally downloaded that photo and see details)

Have you ever tested modules with Power Amplifier and Low-Noise receiver preamp like THIS:

I have seen units with bad build quality. The ones from rfinchina.com (Their blue sticker on back) seem good. I do not recognize the Logo on the ones you show in the photo. What was the supplier?

I also see many people with problems due to long wire jumpers and poor 3.3V supply. adding a .1uF to 10 uF (MicroFarad) capacitor directly on the module from +3.3V to Gnd seems to make things much more reliable.

What did you plug the units into? Did it have close bypassing of +3.3V and Ground?

Could the "slow" units be doing lots of retries? Otherwise I'd just expect total failure.

I'm trying to help people use these with the information on the ArduinoInfo.Info WIKI HERE:

Any suggestions appreciated!

DISCLAIMER: Mentioned stuff from my own shop...

Thank you all again dear participants

Sorry for my poor explanation but I try my best

I think when occasionally external signal come to your microcontroller, it should interrupt handler applied for serve this occasional event

Actually in my original plan, each node (nRF+ Arduino) must continually gather the data from salve devices and send it to upper level master device (pooling) While serve the occasionally request on data from upper master device (interrupt handler)

But however I don’t know, just using pooling method could handle occasional request Maybe just like maniacbug RF network library, need to write the update network function in beginning the loop and check what's going on ( is RX buffer full or empty? , is RX_DS asserted ?)

Also I might add terryking228 reefer to the good point, cause in my first step I had problem to read module with Arduino 5vcc pin, and I thing just using 3.3 v regulator is not enough for robust communication

terryking228:
Hi @acboother,

Can you tell us what type nRF24L01 modules you tested? (Update, finally downloaded that photo and see details)

Have you ever tested modules with Power Amplifier and Low-Noise receiver preamp like THIS:

I have seen units with bad build quality. The ones from rfinchina.com (Their blue sticker on back) seem good. I do not recognize the Logo on the ones you show in the photo. What was the supplier?

I also see many people with problems due to long wire jumpers and poor 3.3V supply. adding a .1uF to 10 uF (MicroFarad) capacitor directly on the module from +3.3V to Gnd seems to make things much more reliable.

What did you plug the units into? Did it have close bypassing of +3.3V and Ground?

Could the “slow” units be doing lots of retries? Otherwise I’d just expect total failure.

I’m trying to help people use these with the information on the ArduinoInfo.Info WIKI HERE:

Any suggestions appreciated!

DISCLAIMER: Mentioned stuff from my own shop…

Have not tried with an amplifier.

Used low power versions with the zigzag aerial. Can’t be sure what the cause was. Many retries sounds possible as they did not suffer from total failure. I was on the track to find out if it was poor sending and the receive was fine, good sending and poor reception or both. Hacked into ManicBugs code and made more of the functions public and added more debug code but didn’t find anything that would help. Also looked at the link you supplied and what seems like a good handful of others (some were a little bit ‘faulty’ - if you know what I mean). After a while I realised I had a life elsewhere and decided not to work this through to its final conclusion…

Both suppliers are on eBay (UK). I will not name them though. However the one supplying the slow units did offer to return my money as well having sent more units to test. He was unaware of any problems but then he said he had no way to check and just assumed they worked. And to be fair they did in so much as they had the same s/w interface and hardware as the spec sheet.

As for the electrical wiring I can’t remember exactly what I did and would have to refer to the photo but here is another photo with it in place. You can see it is very squeezed in due to the project requirements for a small project box and a lot of kit! Never the less all the tests were done on the same configuration.

Thanks for the information. I'm glad you tested that much.. I am trying to find out what might help others (And me when I use these!).

The photo shows a resistor connected to the Vcc pin:

Is that supplying power, or is it feeding it somewhere else?? Vcc problems seem to be a common problem with these.

terryking228: Thanks for the information. I'm glad you tested that much.. I am trying to find out what might help others (And me when I use these!).

The photo shows a resistor connected to the Vcc pin:

Is that supplying power, or is it feeding it somewhere else?? Vcc problems seem to be a common problem with these.

Its gong off to a small LED embedded in the project box to serve as a power on light.

acboother: I have seen units with bad build quality.

I bought a batch from China that had about a 20% failure rate, and a close inspection of the SMD soldering showed it was pretty mediocre and appeared to have been fixed manually in several places. I wouldn't be surprised if the components were suffering from thermal stress before they were even powered on. On the other hand I can't imagine how they even covered the postage at that price, let alone made them.

PeterH:

acboother: I have seen units with bad build quality.

I bought a batch from China that had about a 20% failure rate, and a close inspection of the SMD soldering showed it was pretty mediocre and appeared to have been fixed manually in several places. I wouldn't be surprised if the components were suffering from thermal stress before they were even powered on. On the other hand I can't imagine how they even covered the postage at that price, let alone made them.

Actually that was TerryKing that wrote that...

Actually that was TerryKing that wrote that…

I have sold about 1000 of these, and we are careful with the suppliers and check every batch for build quality. Not that they are cellphone quality at $2.45 retail. There are items like this in the China market that are priced at the 100,000+ quantity level because they are used in a million RF remotes etc… Another example is the little stepper motor that is used in every room air conditioner to move the little air-direction flaps: Like THIS: So I can sell a (small) stepper motor AND driver board for $4.75 and more importantly supply them as part of an Educational kit that 1000+ students used last year. Universities want “Students to have hands-on experience with Stepper motors because they are used in so much CNC equipment, 3-D printers etc etc.” (Quote from one of the professors).

The challenge is to make this low-cost stuff reliable and well documented for those who are not familiar with them.

It’s a good era because of this and all the experienced guys who are applying 100s of hours of “Lab Time” on them. If anyone wants to do some more reliability tests let me know and I’ll send you 4 or so…

And critique of THIS: and comments / suggestions for content there would be appreciated.

DISCLAIMER: Mentioned stuff from my own shop…