This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

IRQ not triggered even though the emission status seems ok.

Hi, 

I've been using the nRF24l01+ for some time now and am quite satisfied. I'm having a new issue that I'm unable to explain and for which I would greatly appreciate some help. 

I have two units comunicating together using the following scheme:

1: T = t0 - Module 1 sends message 1

2: T = t0 - Module 2 receives message 1

3: T = t0 + 30 ms - Module 2 sends msg 2 

4: T = t0 + 30 ms - Module 1 receives msg 2 

5: T = t0 + 40 ms - Module 1 sends msg 3

6: T = t0 + 50 ms - Module 1 sends msg 4

7: T = t0 + 100 ms - The process starts again. 

My problem is that when I send msg2 using the module 2, the tx status goes to 1, which means that the emission went well, but there is no IRQ triggered on the module 1 side. Is there a configuration where the emitting unit sees everything as normal whereas the receiving unit doesn't call an interruption ? 

The problem gets even more strange, because when I remove step 5 or step 6, so I just send one message after receiveing msg 2, then everything starts to work normally again... 

Any clue to what the problem might be ? 

Thank you all for any help you may provide, 


Regards, 

Parents Reply
  • Hi,

    Not entirely sure what is the problem no. For debugging I suggest to add some delays here between the steps (e.g. >1ms). Reason for this is to ensure that you don't send a packet from the peer device, while the other device may still be waiting for an ACK, that can create odd results. Alternatively you can add a delay after RX_DR before you switch to TX mode to ensure ACK is sent.

    I also suggest that you add a counter in your packets, this to ensure that no packets are duplicates. 

    Best regards,
    Kenneth

Children
  • Thank you for your help... 

    I've cleaned my code so you can have a look at it. I work on an arduino DUE with nRF24L01+ modules. 

    There is one master device that initiates the communication and then the system follows the followin pattern : 

    Master sends message 1
    Salve answers with message 2
    Master answers with message 3 
    Master sends second answer with message 4
    And the loop starts again. 

    Here is my code : 

    #include <SPI.h>
    #include "nRF24L01.h"
    #include "RF24.h"
    #include "printf.h"
    
    // Hardware configuration
    RF24 globalRadio(57,77);                          // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
    
    class RF24Controller
    {
    	public:
    	virtual ~RF24Controller();
    
    	void			begin(int device);
    	void	        Send(byte id);
    	RF24			&_radio;
    
    
    	//protected:
    	RF24Controller(uint8_t IRQPin, uint8_t CEPin, uint8_t CSPin, RF24 & radio = globalRadio);
    	uint32_t	_timeSync;
    	
    	byte	doInterrupt();
    	bool	_isDoneTransmitting;
    	uint8_t	_IRQPin;
    };
    
    // Demonstrates another method of setting up the addresses
    byte address[][5] = { 0xCC,0xCE,0xCC,0xCE,0xCC , 0xCE,0xCC,0xCE,0xCC,0xCE};
    
    volatile uint32_t emissionTimeStamp = 0;
    volatile uint32_t receptionTimeStamp = 0;
    volatile bool failed = false;
    
    RF24Controller testRadio(55,57,77);
    
    int role = 2; //1 master - 2 slave
    /********************** Setup *********************/
    
    void setup(){
    
    	pinMode(55, INPUT);
    	delay(20);
    	
    	SerialUSB.begin(115200);
    	testRadio.begin(role);
    }
    
    
    
    /********************** Main Loop *********************/
    void loop() {
    	static uint32_t timer = 0;
    	static bool resendInfo = false;
    	static uint32_t lastSent = 0;
    	
    	if (role == 1)  {
    		if(millis() - timer > 100)
    		{
    			SerialUSB.print(F("Now sending "));
    			SerialUSB.println(timer);
    			testRadio.Send(1);
    			timer = millis();
    		}
    	}
    	
    	byte id = testRadio.doInterrupt();
    
    	if(id != 0)
    	{
    		SerialUSB.println("Received " + String(id));
    		if(id == 1)
    		testRadio.Send(2);
    		if(id == 2)
    		{
    			testRadio.Send(3);
    			resendInfo = true;
    			lastSent = millis();
    		}
    	}
    	
    	if(millis() - lastSent > 10 && resendInfo)
    	{
    		testRadio.Send(4);
    		resendInfo = false;
    	}
    }
    
    
    RF24Controller::RF24Controller(uint8_t IRQPin, uint8_t CEPin,
    uint8_t CSPin, RF24 & radio) : _radio(radio)
    {
    	_IRQPin = IRQPin;
    	_timeSync = 0;
    }
    
    RF24Controller::~RF24Controller() {}
    
    void		catchInterrupt()
    {
    	uint32_t interruptTime = micros();
    	bool tx,fail,rx;
    	
    	globalRadio.whatHappened(tx,fail,rx);
    	if ( tx || fail)
    	{
    		emissionTimeStamp = interruptTime;
    		failed = fail;
    	}
    	else if ( rx || globalRadio.available())
    	{
    		receptionTimeStamp = interruptTime;
    	}
    }
    
    byte     RF24Controller::doInterrupt()
    {
    	static uint32_t lastReceptionTime = 0;
    	static uint32_t lastEmissionTime = 0;
    	byte		tmp[32];
    	uint8_t		size;
    	
    	if (lastReceptionTime != receptionTimeStamp)
    	{
    		lastReceptionTime = receptionTimeStamp;
    
    		while (_radio.available())
    		{
    			size = _radio.getDynamicPayloadSize();
    			_radio.read(tmp, size);
    		}
    		return (tmp[0]);
    	}
    	else if (emissionTimeStamp != lastEmissionTime)
    	{
    		lastEmissionTime = emissionTimeStamp;
    		_radio.flush_tx();
    		_radio.startListening();
    		SerialUSB.println("Emission\t" + String(failed));
    	}
    	
    	return 0;
    }
    
    void		RF24Controller::begin(int device)
    {
    	pinMode(_IRQPin, INPUT);
    	byte address2[][5] = { 0xCC,0xCE,0xCC,0xCE,0xCC , 0xCE,0xCC,0xCE,0xCC,0xCE};
    	_radio.begin();
    	_radio.setPALevel(RF24_PA_MAX);
    	//globalRadio.setDataRate(RF24_250KBPS);
    	_radio.setRetries(0, 0);
    	_radio.enableDynamicPayloads();
    	//_radio.setChannel(108);
    	_radio.setAutoAck(true);
    
    	if(device == 1)
    	{
    		_radio.openReadingPipe(1, address2[1]);
    		_radio.openWritingPipe(address2[0]);
    	}
    	else if(device == 2)
    	{
    		_radio.openReadingPipe(1, address2[0]);
    		_radio.openWritingPipe(address2[1]);
    	}
    	_radio.startListening();
    	
    	delay(50);
    	attachInterrupt(digitalPinToInterrupt(_IRQPin),
    	catchInterrupt, LOW);
    }
    
    void			RF24Controller::Send(byte id)
    {
    	_radio.stopListening();
    	
    	byte buffer[30]= {0};
    	buffer[0] = id;
    	_radio.startWrite(buffer, 30, false);
    }
    

    I have defined a class that is supposed to deal with the RF24 messages. 
    Before the Setup you can define a role : 1 is master and 2 is slave. 

    I print each time i receive a message and also I print the fail status each time I send a message.
    Now when I have both devices communicating I should get the following information : 

    On the master side : 

    Now sending 54641
    Emission	0
    Received 2
    Emission	0
    Emission	0

    And on the slave side:

    Received 1
    Emission	0
    Received 3
    Received 4

    But almost every two messages, I have the "Emission 0" on the slave side (which means that the message went over and the ACK was received) but I don't have any "Received 2" on the master side. 

    And more incredibly, when I comment the "Send(4)" line everything works normally... 

    I would really appreciate your help on this matter :D 

    Regards, 

  • Hi,

    I am not familiar with Arduino, but the flow should be:

    Set in receive mode.
    Wait for packet received (RX_DR).
    If packet received (RX_DR), wait 500us to ensure ACK is sent (Are you doing this step?).
    Stop receive mode, set in transmit mode.
    Send packet.
    Wait for packet sent (TX_DS or MAX_RT).

    Best regards,
    Kenneth

     

Related