I am trying to get a 30 minutes repetitive task to send data over MQTT in a project of mine but I cannot get it to even reach 10 minutes (600000 milliseconds) without the device being reset and data never sent.
Hardware is an ESP32 WROOM dev board and I use Arduino IDE to program it.
Here is the code that gives me a headache as I cannot find an example for long delays/pauses on the internet so far.
void TaskIOADA(void *pvParameters) { // This is a task.
(void)pvParameters;
TickType_t xLastWakeTime;
const TickType_t xFrequency = 300000; //5 minutes cannot reach 10 minutes (600000) ==> reset and data never sent
// Initialise the xLastWakeTime variable with the current time.
xLastWakeTime = xTaskGetTickCount();
for (;;){
vTaskDelayUntil( &xLastWakeTime, xFrequency/ portTICK_PERIOD_MS );
io.run();
.... Other stuff being done there....
If someone knows how to get this task to run every 30 minutes, I would be grateful!
It has to be a task as I am running multiple different task on this device like blinking an LED + reading an analog sensor which could trigger the LED to get solid and stop readings for an extended period of time after closing a timed valve then reopening the timed valve + reading periodically 2 other sensors + sending data over MQTT every 30 minutes.
Understood, but you are using a task that 'never ends' you call it once and then it executes stay dormant and executes again...
You can simply call the task that executes an then exits, after the 30 minuts period you recall that task.... ( this way if you need to change the period... )
If I may add ( its a personal preference/consideration... ) the mqtt task has his reasons ( you could bind the task to a core different from the one used by sensor and so on ), as it may you may need to rejoing the net, the server, something unexpected...
...but a task for a 'simple task' as flashing a led or operating a valve it seems an unnecessary complication ( simply wondering how do these task communicate each other ) this can be simply done in the main task ( the loop ) using as many finite machine as needed each state machine do a simple task an then returns immediately, advancing to a different state when necessary ( you could add as many as needed of states machines and of states )
Believe me I have tried millis and it is just not feasible with my project, all examples you find everywhere are blinking LEDs only which is not helping at all. Operating a valve in a task makes a lot of sense since it will have to be actuated one way (open or closed) for a specific amount of time then switched off, then triggered according to external events, the valve status will be indicated by the LED.
Why a task to blink an LED? To not interfere with the other tasks as this LED will change state according to different status.
I agree with the task recall but I have yet to grasp the concept, all examples are too vague for me.
So I do understand that everything lies in the number of ticks that seems to overflow something but I don't understand how to get around. I have tried your example with success using 5 minutes but any value above 5 minutes crashes the device and resets.
The delay() function blocks everything else when called. All my libraries and boards up to date. This is the portion of the code which is the problem. Any value above 5 minutes resets the device.
No, not when Arduino is on top of FreeRTOS or Mbed. The multitasking system keeps on running.
In my post #11 I gave a link the the source code of delay() on a ESP32 and even the code itself.
We have a saying on this forum: "The problem is in the part that you are not showing".
I made up "Koepel's law": "Fifty percent chance that the problem is in the section that was ignored from the beginning, because you thought that the problem could not be caused by that section"
There is a website for snippets: https://snippets-r-us.com/
Then some of us look at the code and your results and that is an indication that the problem is probably somewhere else.
I just follow my feeling, my feeling says that you have to prove that there is problem with a sketch that we can try.
It has been answered now but here is an ESP32 RTOS traffic light application using delay() statements where a counter in one task is running during delay() statements in another task.
To be clear, as the name implies, uxTaskGetStackHighWaterMark returns the least amount of stack remaining over the lifetime of the task. Once the number goes down, it never goes back up. You can use this for "can I shrink this task's stack" if the stack usage is predictable, but you didn't know up front exactly how much it was going to be. "I allocated 2048, but there's always at least 640 remaining, so I will shrink it by 512 because memory is tight."
I don't have any specific knowledge of ESP32 registers, but a naive reading of the backtrace at those initial crashes -- looking at the number to the right of the colon -- comparing the top frame to the bottom
All-a5 is not a valid stack pointer (it's an odd number) -- the fact that a pointer has that value indicates something has gone horribly wrong. And it's not directly because you've waited too long, but because something that's happening while you're waiting is corrupting the stack; or in the earlier case, causing a bunch of nested function calls to exceed the stack space, once it resumes.
You can make the stack bigger to avoid crashing, but that doesn't solve the actual problem.