1

I have 2 Arduinos communicating with each other. My problem is that one sends packets every 1.5-2 seconds but the other Arduino does sensor reading and data uploading with a Wifi module, which may take up to 5 seconds until the next time the nRF24L01+ is available to receive data.

This results in about 4 packet losses and if I am lucky sometimes 2. Is there any way that when the nRF24L01+ sends data, the other Arduino stops everything to get the data? Like a communication between these two Arduinos that will be open 24/7, so that the other Arduino can multitask (reading sensors and upload the data through wifi).

I am using the code from this tutorial. Here is a my problem in an image (I hope this helps you understand it). Thanks in advance. enter image description here

4
  • Are you using software serial for WiFi module?
    – KIIV
    Commented Aug 4, 2016 at 9:16
  • Yes and I am communicating using AT commands.
    – Oluderi
    Commented Aug 4, 2016 at 14:35
  • The NRF24L01 has a RX FIFO buffer of 3 packets. So I don't see how you could miss 4 packets. My guess is that something else is going wrong. Could you post some minimal code that still produces that error.
    – Gerben
    Commented Aug 4, 2016 at 15:19
  • It's not clear right now if the reason you are missing packets is because you are operating the wifi in a blocking way, or if it is because the wifi radio is interfering with the nRF24 one in the same general frequency range. Both are potential issues. Could you have your nodes number each reading and send it at multiple points in time? So a given transmission might include readings 1345, 1346, and 1347 while the next transmission would have 1346, 1347 and 1348, etc. Commented Jan 31, 2017 at 22:27

2 Answers 2

1

You need to re-factor your program somewhat (I would imagine). The nRF needs to be read at the same time as doing other things. That means interleaving it with your other operations.

There is a concept called a finite state machine which is the best way of writing a complex program like this. The idea is that nothing ever blocks, it just changes states. And all the time other things can be happening, such as reading the nRF24L01+ module.

I have a little tutorial on the Finite State Machine here:

If you use the Finite State Machine concept to run the reading of your sensors and the writing of data to the WiFi the nRF can then be polled constantly outside of the FSM constantly - maybe with an FSM of its own to deal with reception etc.

Things to remember:

  • Avoid delay(), certainly for anything longer than a couple of ms.
  • Avoid while(), for(), etc except for very short loops that finish quickly.
  • Any operation that takes more than a few ms to complete should be broken down into a number of sub-operations and coded as separate states of the FSM.
1

I see this is an old thread, but thought I'd chime in.

For an example implementation of a finite state machine, there are libraries built for this or you can use simple loop timers with if statements to "poll" sections of code instead of using ANY delays. Delays stop execution and waste your MCU time, preventing it from doing anything else, as already mentioned. Checking for wifi or serial messages can then execute with higher priority. An example pseudo-code would look like:

int update_ms = 500;
int last_update_ms;

setup{

last_update_ms = millis(); // or 0, to execute immediately

}

loop{

if(millis() - last_update_ms >= update_ms){ 
    last_update_ms = millis();
    execute_thing();}

check_for_wifi_msg();

}

There are libraries that do this essential behavior for you with more eloquence, as well, such as PollingTimer. I'm often surprised this isn't given as tool early on when people learn Arduino/ MCU programming, or in example codes. It is easy and so powerful.

You could accomplish the same "finite state machine" functionality with a real-time operating system built for microcontrollers. I can recommend FreeRTOS as a user-friendly entry to this. This makes your single core machine work like a multi-core machine, with a task scheduler. You can define several continually running while loops that the RTOS thread handler then interleaves for consistent execution. You could have 1 thread for your RF and 1 thread for your WiFi, with set execution rates, and RTOS handles the rest, e.g. it will try to fit RF reads inside of the Wifi loop whenever it can find downtime. This will likely make your Wifi loop somewhat longer as a sacrifice.

You can get started with these: FreeRTOS Kernel Quick Start Guide The FreeRTOS Reference Manual

Other solutions, which I won't elaborate on here include using a multi-core chip, like a ESP32, or to make use of WiFi interrupts to break out of other execution. Though, I do not know if this is specifically supported on the nRF24L01+.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.