'ESP32 not updating the variable when multiple cores are used
My plan is to collect data from ESP32's CORE-1 and use ESP32's CORE-0 for all other tasks. However, I see that the variables are not updated properly when multiple cores are used. Here in this example, I see that the value of getAllData is updated only once.
const TickType_t xDelay = 1000 / portTICK_PERIOD_MS;
TaskHandle_t collectData;
bool volatile getAllData;
bool volatile dataReadyToSend;
void setup() {
Serial.begin(115200);
Serial.print("setup() is running on core ");
Serial.println(xPortGetCoreID());
xTaskCreatePinnedToCore(collectDataCode,"collectData",10000,NULL,1,&collectData,0);
delay(500);
}
void loop() {
if (Serial.available()) {
Serial.flush();
getAllData = true;
}
Serial.print("From loop: ");
Serial.println(getAllData);
if (dataReadyToSend) {
dataReadyToSend = false;
}
delay(1000);
}
void collectDataCode(void * params) {
while (1) {
Serial.print("From collectData: ");
Serial.println(getAllData);
if (getAllData) {
getAllData=0;
}
vTaskDelay( xDelay );
}
}
Output of the above code is given below. Where I typed xxx. It is observed that the variable getAllData got updated at this instance, but not changing later.
From collectData: 0
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
xxx
From loop: 1
From collectData: 1
From loop: 1
From collectData: 1
From loop: 1
From collectData: 1
From loop: 1
From collectData: 1
UPDATE
Upon suggestions, I used atomic with the following code. Still I see no success.
#ifdef __cplusplus
#include <atomic>
using namespace std;
#else
#include <stdatomic.h>
#endif
TaskHandle_t collectData;
atomic<bool> getAllData;
atomic<bool> dataReadyToSend;
#include "collectData.h"
void setup() {
Serial.begin(115200);
Serial.print("setup() is running on core ");
Serial.println(xPortGetCoreID());
xTaskCreatePinnedToCore(collectDataCode,"collectData",10000,NULL,1,&collectData,0);
delay(500);
}
void loop() {
if (Serial.available()) {
Serial.flush();
atomic_store (&getAllData, true);
}
Serial.print("From loop: ");
Serial.println(atomic_load(&getAllData));
if (dataReadyToSend) {
dataReadyToSend = false;
}
delay(1000);
}
void collectDataCode(void * params) {
while (1) {
Serial.print("From collectData: ");
Serial.println(atomic_load(&getAllData));
if (atomic_load(&getAllData)) {
atomic_store (&getAllData, false);
}
vTaskDelay( xDelay );
}
}
Solution 1:[1]
I found the answer. The problem is not with the variable itself, it is with the Arduino's Serial.flush(). From the version 1.0, arduino is using Serial.flush() to clear the outgoing serial data not the incoming serial data. So, I replaced the Serial.flush() with the following code.
while(Serial.available()) {
Serial.read();
}
With this update, my code is working good. Thanks to the comment of @PeteBecker, I am using atomic. The final code and results are given below.
#ifdef __cplusplus
#include <atomic>
using namespace std;
#else
#include <stdatomic.h>
#endif
TaskHandle_t collectData;
atomic<bool> getAllData;
atomic<bool> dataReadyToSend;
#include "collectData.h"
void setup() {
Serial.begin(115200);
Serial.print("setup() is running on core ");
Serial.println(xPortGetCoreID());
xTaskCreatePinnedToCore(collectDataCode,"collectData",10000,NULL,1,&collectData,0);
delay(500);
}
void loop() {
if (Serial.available()) {
while(Serial.available()) {
Serial.read();
}
getAllData.store(true);
Serial.println("Received data request");
}
Serial.print("From loop: ");
Serial.println(getAllData.load());
if (dataReadyToSend) {
dataReadyToSend = false;
}
delay(1000);
}
void collectDataCode(void * params) {
while (1) {
Serial.print("From collectData: ");
Serial.println(atomic_load(&getAllData));
if (getAllData.load()) {
getAllData.store(false);
}
vTaskDelay( xDelay );
}
}
Results
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
.
From loop: 0
From collectData: 0
Received data request
From loop: 1
From collectData: 1
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
From loop: 0
From collectData: 0
From loop: 0
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
