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
  • Hi,

    Are you using Auto acknowledgement (TX_DS is asserted when the packet is transmitted, if Auto_ack is activated this bit is set high only when ACK is received)? Auto Retransmisssion (ARD)? What is the ARD delay? and what is the baudrate and packet size?

  • Hi, 


    Thank you for your answer. 
    I'm using a specefic library to communicate with my device. This library states that the Auto ACK is enabled by default so I suppose I'm using the Auto ACK. 
    I have disables the ARD so I'm sending the message once. 

    The buadrate is 250 Kbps and the packet size is 32 bytes. I'm using the dynamic payload option. 

    To add some extra details, it really looks like the devices are communicating because the TX_DS is only asserted when Module 1 is powered. But it looks like Module 1 isn't receiving the information from the device. 

    I hope it clarifies a bit my previous message.

    Thanks in advance for your help, 

    Regards

  • Could you also make sure you are checking the status register and that you are actually getting a TX_DS interrupt and not the MAX_RT interrupt?

  • Sorry for the delay, I was quite busy with another project. 
    I can confirm that it is indeed a TX_DS interrupt that I get. 

    I'm continuing the investigation on my side as well and so far I've been able to extract only the "RF24" part of my code and send dummy messages. Like that it seems to work normally so it might be related to something else in my code. But still it doesn't seem to depend on the payload I send because changing the payload doesn't change the behaviour... 

    Is there anything in the nRF24 that might explain a correclty sent ACK but not a interruption ? 

    I'll keep you updated if I find something new. 

    Regards, 

  • 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

  • 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

     

Reply Children
No Data
Related