Notifications
Clear all

Everything you wanted to know about ESP32 but were too afraid to ask!  

  RSS

Pugwash
(@pugwash)
Prominent Member
Joined: 1 year ago
Posts: 994
2020-08-23 1:40 pm  

NO, NOT REALLY!

But there is definitely something that users of ESP32s should at least know about, namely FreeRTOS and multitasking. The ESP32 costs about the same as a Nano, but where performance is concerned it is like comparing a Lamborghini to a Citroen Deux Chevaux.

Here is some simple boilerplate code to get started (no bells and whistles here).

 

#include "Arduino.h" //delete if using Arduino IDE

// all #includes, #defines and global variables go here
// NOTE: declare all global variables here as "volatiles"

TaskHandle_t Task0;
TaskHandle_t Task1;

void loop0(void * parameter) {

  //declare local variables here
  
  for (;;) {

    // your sketch 1 code goes here
    
  }
}

void loop1(void * parameter) {

  //declare local variables here
  
  for (;;) {

    // your sketch 2 code goes here
    
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println("Setup started.");
  
  xTaskCreatePinnedToCore(
      loop0, /* Function to implement the task */
      "Task0", /* Name of the task */
      1000, /* Stack size in words */
      NULL, /* Task input parameter */
      0, /* Priority of the task */
      &Task0, /* Task handle. */
      1); /* Core where the task should run */

  xTaskCreatePinnedToCore(
      loop1, /* Function to implement the task */
      "Task1", /* Name of the task */
      1000, /* Stack size in words */
      NULL, /* Task input parameter */
      0, /* Priority of the task */
      &Task1, /* Task handle. */
      1); /* Core where the task should run */
  Serial.println("Setup completed.");
}

void loop()
{
  delay(0); //just for compilation
}

 

 And here is a simple demo showing two sketches(tasks) running simultaneously, using the semaphore flag to invoke the second sketch(task).

All that is required is one ESP32 and two LEDs attached to GPIO pins 25 and 27.

 

#include "Arduino.h"

TaskHandle_t Task0;
TaskHandle_t Task1;

SemaphoreHandle_t semaphore;

#define LED0 27
#define LED1 25

void loop0(void * parameter) {
  int limit = 10;
  for (;;) {
    for(int n = 0; n < limit; n++){     
      if(n == 5){
        xSemaphoreGive(semaphore); //set the semaphore flag
      }
      
      digitalWrite(LED0, HIGH);
      delay(1000);
      digitalWrite(LED0, LOW);
      delay(1000);
    }
    
  }
}

void loop1(void * parameter) {
  int limit = 5;
  for (;;) {    
    xSemaphoreTake(semaphore, portMAX_DELAY); //wait for semaphore flag to be set
    
    for(int n = 0; n < limit; n++){      
      digitalWrite(LED1, HIGH);
      delay(1000);
      digitalWrite(LED1, LOW);
      delay(1000);
    }
    
  }
}

void setup()
{
  Serial.begin(115200);
  Serial.println("Setup started.");

  pinMode(LED0, OUTPUT);
  pinMode(LED1, OUTPUT);

  semaphore = xSemaphoreCreateBinary();

  xTaskCreatePinnedToCore(
      loop0, /* Function to implement the task */
      "Task0", /* Name of the task */
      1000, /* Stack size in words */
      NULL, /* Task input parameter */
      0, /* Priority of the task */
      &Task0, /* Task handle. */
      1); /* Core where the task should run */

  xTaskCreatePinnedToCore(
      loop1, /* Function to implement the task */
      "Task1", /* Name of the task */
      1000, /* Stack size in words */
      NULL, /* Task input parameter */
      0, /* Priority of the task */
      &Task1, /* Task handle. */
      1); /* Core where the task should run */
      
  Serial.println("Setup completed.");
}

void loop()
{
  vTaskDelete(NULL); //helps with compiling
}

 

Have fun!! I have only skimmed the surface of FreeRTOS, maybe Dronebot could make an instructional video on this subject.


Quote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-08-23 6:22 pm  

@pugwash

The post caught my eye as I've just finished of a bit of soldering on my 'nest' style clever thermostat project that has an esp32 at its core.   I'm using micropython which can also multitask on the ESP32 though not as quick a freeRTS I would think.

But along the lines of your post, I remembered a video I perused recently on passing values between tasks on ESP32 in C++ which may be of more interest than micropython to folks here, so I add it to your 'Everything you may want to know' post in case its of interest.

I get the impression that Bill is more a hardware guru than a software bod so I would not hold out much hope of a DroneBots article (though happy for Bill to put me in my place and to produce such an article 😀)  But if you have the time to contribute a write up it could be an interesting read.


ReplyQuote
Pugwash
(@pugwash)
Prominent Member
Joined: 1 year ago
Posts: 994
2020-08-24 12:14 pm  

@byron

My primary motivation for the above post was just to make those starting out with the ESP32 aware that FreeRTOS exists.

I bought some ESP32s initially because of the higher ADC resolution and after working with the ESP32 for a couple of months, just stumbled across FreeRTOS. Then I started running multiple tasks, just for fun!

It was one of those "Gosh, I didn't know you could do that!" moments. Something that happens every now and then.

After giving it some more thought, I was postulating whether I could replace six Nanos with one ESP32, which would save about $30 on µcontrollers, a lot of I2C wiring and coding, and about 100 mA power consumption.

I have watched a few Youtube videos on the subject, most are quite superficial but that is hardly surprising as the API documentation at FreeRTOS.org website is quite daunting.


ReplyQuote
mariog
(@mariog)
New Member
Joined: 2 months ago
Posts: 4
2020-08-24 12:47 pm  

For those put off by the complexity of FreeRTOS there is a simpler, and easier to get started with multi-tasking operating system called Helios.

Helios project

 

Took me about 3 minutes to get started with it.


ReplyQuote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-08-24 1:23 pm  

@pugwash

Another daunting aspect would be the use of existing libraries I think.  Here I quote PaulStoffregen who makes the Teensy range of boards and this was in relation to the Teensy 4 board, but I would think this also applies to the ESP32

"But the honest reality of "supported", meaning at least some reasonably large subset of the code you'll find for Teensy actually works with FreeRTOS, or meaning that you'll get good answers from us here on this forum, then no. Hardly any of the existing libraries and non-trivial programs are thread safe, not to mentioned designed to integrate well with multi-threaded FreeRTOS projects. Hardly anyone here really uses FreeRTOS. So while there may be ports that can at least do some trivial things, for all practical purposes FreeRTOS isn't really a viable path, unless you want your project to largely about fiddling with FreeRTOS."

And mentioning the Teensy 4, its more than 6 times faster than the ESP32 (which is 250 time faster than to Uno) for similar money.  So with some of these more recent microcontrollers I would think you could replace your 6 Nanos as long as theres enough gpio pins for your project. (best go for the Teensy 4.1 for more pins in that case).   I'm holding off the Teensy 4 at the moment as there currently isn't any micropython support and the ESP32 is quite fast enough for my current project needs.  Of course you could multitask in micropython or python without any python libraries issues but that is probably a route you don't want to go down. 😎 


ReplyQuote
Pugwash
(@pugwash)
Prominent Member
Joined: 1 year ago
Posts: 994
2020-08-24 2:03 pm  

@byron

I will have to look up the Teensy boards, thanks for the tip!

In practice, you tend to stick with the stuff you already have in your workshop.

I am not too sure whether this "need for speed" is so important as most hobbyists don't even get their Unos and Nanos up to the 16MHz limit. In fact, I find that my µcontrollers are idle most of the time.


ReplyQuote
Pugwash
(@pugwash)
Prominent Member
Joined: 1 year ago
Posts: 994
2020-08-25 1:25 pm  

@byron

I picked up the following benchmark sketch from Ralph Bacon's GitHub repository and was wondering if you would run it on the Teensy board and let me know how it performs.

The results I got from my boards were as follows.

Nano -> 9885mS

ESP8266 -> 1080mS

ESP32 -> 61mS

 

#define maxPrime 501
int i, j;
bool b[maxPrime];

void setup() {
  Serial.begin(115200);
  Serial.println("Setup complete");
}

void loop() {
  Serial.println("Running loop.");
  unsigned long runTime = millis();

  // Calculate all prime numbers up to X
  for (i = 2; i < maxPrime; i++) {
    b[i] = true;
  }
  for (i = 1; i < maxPrime; i++) {
    if (b[i]) {
      //Serial.print(i); Serial.print(" "); Serial.flush();
      for (float i = 0.0; i < 9000; i++) {
        for (long j = 1; j < 9000; j++) {
          float temp = i * 0.05;
          long temp2 = (long)temp % j;
        }
      }
      for (j = i * 2; j < maxPrime; j += i)
        b[j] = false;
    }
  }

  Serial.println("\n--- Prime numbers completed ---\n");
  Serial.print(millis() - runTime); Serial.println(" milliseconds");
  delay(5000);
}

 

After looking at the Teensy 4.1, the price is a bit steep at $27, compared to the $6-7 for an ESP32, but is certainly a lot cheaper than the new range of original Arduino Nanos.


ReplyQuote
byron
(@byron)
Reputable Member
Joined: 1 year ago
Posts: 353
2020-08-25 5:22 pm  

@pugwash

The teensy 4 (like the 4.1 but with less pins took 13 ms

To give it a bit more of a bash I upped the maxprime from 501 to 100,000 and then it took 1297ms

I agree with you that speed is not usually important and I've certainly never got anywhere near stressing my various microprocessors.  However it may come more into play when asking a single microprocessor to take on the tasks of several, maybe handling several 12c, CAN and serial serial busses, whilst sending and receiving over an IP network and calculating a bearing from GPS co-ordinates 😲 - well maybe.

This post was modified 2 months ago 2 times by byron

ReplyQuote