Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

Hi, Some help needed (tips, tricks, example code for a absolute beginner on FreeRTOS and ESP32) I have some working example code from my Arduino setup (working with ESP32) but I would love to understand the real FreeRTOS code, that does exactly the same thing for me on the ESP32 Can I post code here (Arduino code – setup() / loop() ) and ask for help, or is that “not done” on this forum I dont need a whole project to be translated, just some tips and explanation of the way FreeRTOS does the same work as the example code I would like to post. edit : my working platform : Windows 7, Visual Studio Code and Platformio installed and working fine. Arduino IDE with the ESP32 toolchain and working fine. Two ESP32 dev boards : NodeMCU-32S and Wemos LOLINS ESP32, both working well Tried some pure ESP32-IDF FreeRTOS examples and some Arduin ESP32 Toolchain examples (Wifi, Interrupts, ….) all working well Grtz Yves

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

I’m not so familiar with Arduino, but you can try posting the code as long as there is not too much to read through. Make sure you use the markup tags for pre-formatted code though, otherwise the SourceForge forum will interpret special characters within the code as markup – which you will not notice until after hitting the ‘post’ button.

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

Hi,
I’m not so familiar with Arduino, but you can try posting the code as long as there is not too much to read through <
I do not need pure arduino code, more something like : “i do this routine with arduino – how can obtain the same result with FreeRTOS” Is that OK for this forum Grtz, Yves

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

Sure.

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

so here we go with a first example: this code runs perfectly on a NodeMCU-32S. my goal would be to use both ESP cores – one for the logic (monitoring the interrupts) and one for the output (serial monitor). so one way or another a certain signal will be needed to attend core 2 it has some output to work with 🙂 first we have to declare a pin for a interrupt, a volatile integer for the counter and a last a integer for counting the number of times the interrupt fired (and to restart the system for example) ~~~ /* let the system know we are on Arduino framework */

include <Arduino.h>

/* pin where the interrupt will be monitored*/ const byte interruptPin = 25; /* a overall accessible variable to flag a interrupt */ volatile int interruptCounter = 0; /* var used for counting */ int numberOfInterrupts = 0; /* var used for a timestamp */ volatile long interruptFiredTime = 0; ~~~ then we have to set the setup() function, who runs one time on (re-)startup. here we define the serial communication with the monitor, and set the interrupt pin to input and give it a pull-up status. we also have to decide what function will run, once the interrupt gets fired. ~~~ void setup() { /* communication speed with the serial monitor */ Serial.begin(115200); /* draw some text, so the user knows setup() did run */ Serial.println(“Monitoring interrupts: “); /* set the pinnumber for the interrupt and set the resistor to Pull-up */ pinMode(interruptPin, INPUT_PULLUP); */ setup what function has to be called when the interrupt gets fired – “handleInterrupt” – on a falling edge signal */ attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING); } ~~~ then make a ISR function ~~~ /* normaly i would make the ISR as compact as possible and use a flag, but this is to demonstrate / void handleInterrupt() { interruptCounter++; / set the flag to 1 / interruptFiredTime = micros(); / capture a timestamp / } ~~~ we need the loop() function to make this run, in this case it can be used to restart the Mcu, this is a endless loop in Arduino ~~~ void loop(){ if(interruptCounter>0){ / reset the ISR flag to 0 */ interruptCounter–;
   /* counter goes one up */
   numberOfInterrupts++;

   /* display results */
   Serial.print("An interrupt has occurred. Total: ");
   Serial.print(numberOfInterrupts);
   Serial.print("at : ");
   Serial.println(interruptFiredTime);

   /* reset system once we get to 25 */
   if(numberOfInterrupts > 25){
   Serial.println("System restart");
   esp_restart();
   }
 }
} ~~~ So, basicaly there are two things to learn here for me, how to use the 2 cores (xTaskCreatePinnedToCore) and how to make a ISR funtcion that gets information from the interrupt (like a timestamp) and passes it to a function in Core 2 to display this information on the serial monitor

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

ESP has some code in github. Also did you see this http://blob.tomerweller.com/esp32-first-steps

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

Hi MEdwards, Yes i did read that article. Last night I tried some ESP-IDF examples with the VSCode and platformio setup. They all worked well. But i can not figure out how to set a Task (from interrupt input – a simple button press) on Core 0 to send a signal to Core 1 where another Task has to do some output to the serial monitor.

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

Hi, I’ve been adapting a example, and i must say it came to work: ~~~

include <stdio.h>

include <string.h>

include <stdlib.h>

include “sdkconfig.h”

include “esp_system.h”

include “espheapalloc_caps.h”

include “freertos/FreeRTOS.h”

include “freertos/task.h”

include “freertos/queue.h”

include “freertos/heap_regions.h”

define outputCore 1

define logicCore 0

xQueueHandle demo_queue; void txtask1(void *arg) { uint32t txpos=0; uint32_t myCore = xPortGetCoreID(); printf(“TX1 from Core : %un”,myCore);
while (1) {
    if(xQueueSendToBack(demo_queue,&txpos,1000/portTICK_RATE_MS)!=pdTRUE) {
        printf("tx_task1 can not transfer %dn",txpos);
    }
    vTaskDelay(7000 / portTICK_RATE_MS); // delay 7s
    txpos++;
}
} void txtask2(void *arg) { uint32t txpos=0; uint32t myCore = xPortGetCoreID(); printf(“TX2 from Core :%un”,myCore); while (1) { if(xQueueSendToBack(demoqueue,&txpos,1000/portTICKRATEMS)!=pdTRUE) { printf(“txtask2 can not transfer %dn”,txpos); } vTaskDelay(10000 / portTICKRATE_MS); // delay 10s txpos++; } } void rxtask(void *arg) { uint32t rxpos; uint32t myCore = xPortGetCoreID(); printf(“This is the receiving Task : rxtaskn”); while (1) { printf(“rxtask queue yield”); if(xQueueReceive(demoqueue,&rxpos,60000/portTICKRATEMS)!=pdTRUE) { // max wait 60s printf(“nothing received!n”); } else { printf(“rxtask received a value %dn”,rxpos); printf(“Active core : %un”,myCore); } if (uxQueueMessagesWaiting(demoqueue)==0) { // no message? take a break printf(“nothing to do, take a nap :-)n”); vTaskDelay(15000 / portTICKRATEMS); // delay 15s } } } void appmain() { printf(“constructing & starting ESP32 tasksn”); printf(“free DRAM %u IRAM %un”,espgetfreeheapsize(),xPortGetFreeHeapSizeTagged(MALLOCCAP_32BIT));
demo_queue = xQueueCreate(10, sizeof(uint32_t));

printf("free DRAM %u IRAM %un",esp_get_free_heap_size(),xPortGetFreeHeapSizeTagged(MALLOC_CAP_32BIT));

printf("created three tasksn");
xTaskCreatePinnedToCore(tx_task1, "tx_task1", CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE, NULL, 5, NULL,logicCore);
xTaskCreatePinnedToCore(tx_task2, "tx_task2", CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE, NULL, 5, NULL,logicCore);
xTaskCreatePinnedToCore(rx_task, "rx_task", CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE, NULL, 5, NULL,outputCore);

printf("end of mainn");
} ~~~ i have the following question now : can i create a ISR task and let that be pinned to a core? the goal is to trap a signal from a button by interrupt, and do some output on the other core… ah, i have a additional question : in arduino we have something like millis() or micros() who return a timestamp from since the Mcu started after a (re-)boot – is there a similar function in IDF? Grtz, Yves

Help (on ESP32 and FreeRTOS — migration from Arduino to IDF)

Sorry for brevity – didn’t read all the code but to your two questions:
can i create a ISR task and let that be pinned to a core? the goal is to trap a signal from a button by interrupt, and do some output on the other core…
That functionality was added by whoever wrote the FreeRTOS version for the ESP – so sorry I’m not sure.
ah, i have a additional question : in arduino we have something like millis() or micros() who return a timestamp from since the Mcu started after a (re-)boot – is there a similar function in IDF?
You can get the tick count using xTaskGetTickCount(). The frequency is set by your configTICKRATEHZ setting in FreeRTOSConfig.h.