The difference between using elapsedMillis and delay
delay(5000) stops and waits for 5000 milli seconds.
DO SOMETHING
delay(5000);
KEEP DOING STUFF
This means the processor is doing no useful work for 5 seconds, it will recieve
data using interrups but they can overflow since your progarm is asleep and doesnt handle them
elapsedMillis objects reports the number of milliseconds since it was last reset to 0,
it doesnt stop program execution.
if (myElapsedMillisObject > 5000) {
HANDLE THE STUFF, BUT ONLY WHEN 5000 ms HAS ELAPSED
}
this means only a minute amount of processor power is used to check the time, until 5000 ms has elapsed
If your code only do one task delay can work, but it will interfere with communications.
For many active task and ongoing communications, you can keep one elapsedMillis object to track waiting for each task,
this will allow the processor to handle other tasks while waiting for 5000 millis to go by.
Hope this is an understandable explanation
EDIT
Some typos and wrong number of 0's edited