ESP32 multi-tasking?

Hi!

these days I have been working with new boards to include its support in the client libraries (for the upcoming 2.2.0 release), like the Arduino Nano RP2040 connect. This board includes mbed RTOS which allows, for example, creating multiple tasks. I have adapted the client library so Thinger client starts on its own Thread, leaving the loop completely free for the user. For example, a working sketch for this device is the following:

#define THINGER_SERIAL_DEBUG

#include <ThingerMbed.h>
#include <ThingerMbedOTA.h>
#include "arduino_secrets.h"

ThingerMbed thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
ThingerMbedOTA ota(thing);

void setup() {
  // configure LED_BUILTIN for output
  pinMode(LED_BUILTIN, OUTPUT);

  // open serial for debugging
  Serial.begin(115200);

  // configure wifi network
  thing.add_wifi(SSID, SSID_PASSWORD);

  // pin control example (i.e. turning on/off a light, a relay, etc)
  thing["led"] << digitalPin(LED_BUILTIN);

  // resource output example (i.e. reading a sensor value, a variable, etc)
  thing["millis"] >> outputValue(millis());

  // start thinger.io on its own thread
  thing.start();
}

void loop() {
  Serial.println("user can work freely here");
  delay(1000);
}

It even allows to start/stop thinger on demand. Since ESP32 on arduino runs using FreeRTOS, do you think it is worth to include the same approach shown here!?

Very interesting. Visually, it is simpler for the user to understand.

Also, are there any expectations to update the library so that it is possible to configure ESP32 with “WebConfig”/WiFiManager? And that the OTA update works with “WebConfig/WiFiManager”?
Apparently, WiFiManager version 2.0.4-Beta already works with ESP32.

Hi,

This multitasking is just in one core or involves both? I ask this because it could be dangerous at the moment that two processes (running simultaneously, at both cores) access at the very same moment the very same memory, for example thinger’s task uploading (or writing) variables and another task writing them, at the same time, yes maybe the probabilities are soooo low, but it is something to keep in mind.

Hi @George_Santiago, I will take a look to WifiManager for ESP32.

And yes, @ega, with mulltitasking there is a chance of multiple task using the same memory. Thinger client library already had semaphores for ESP32 (started whit the ESP32Core project) and now included Mutex for Mbed platform, so, at least, the use of the thinger client instance is ok with multiple task, i.e., the loop calling endpoints, writing buckets, etc., and the background task handling incoming messages, streams, etc.

Moreover, if the loop updates or uses variables that are used someway inside a resource definition, it is possible to acquire the lock before using them. Here it is a working example for the upcoming library version.

#define THINGER_SERIAL_DEBUG

#include <ThingerESP32.h>
#include "arduino_secrets.h"

ThingerESP32 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
int threshold = 0;

void setup() {
  Serial.begin(115200);

  pinMode(16, OUTPUT);

  thing.add_wifi(SSID, SSID_PASSWORD);

  thing["threshold"] << inputValue(threshold);
  
  thing.start();
}

void loop() {
  delay(1000);
  thing.lock();
  Serial.printf("Threshold value: %d\n", threshold);
  thing.unlock();
}

We have a new library with RTOS support for ESP32:

Example for creating a background task for Thinger.io (notice the THINGER_FREE_RTOS define to enable RTOS functionality).

#define THINGER_SERIAL_DEBUG
#define THINGER_FREE_RTOS

#include <ThingerESP32.h>
#include "arduino_secrets.h"

ThingerESP32 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

void setup() {
  // open serial for debugging
  Serial.begin(115200);

  pinMode(16, OUTPUT);

  thing.add_wifi(SSID, SSID_PASSWORD);

  // digital pin control example (i.e. turning on/off a light, a relay, configuring a parameter, etc)
  thing["GPIO_16"] << digitalPin(16);

  // resource output example (i.e. reading a sensor value)
  thing["millis"] >> outputValue(millis());

  // start thinger in its own task
  thing.start();

  // more details at http://docs.thinger.io/arduino/
}

void loop() {
  // use loop as in normal Arduino Sketch
  // use thing.lock() thing.unlock() if using variables exposed on thinger resources
}