ESP32S3 monitor shows nothing

I copied the example code from the Seeed Studio webpage and managed to compile and run it with no errors.

But I am unable to find any output that this silly program is meant to be sending to the console?

I just get this…

Writing at 0x0002d9f4... (55 %)
Writing at 0x0003457c... (66 %)
Writing at 0x0003e476... (77 %)
Writing at 0x00043b40... (88 %)
Writing at 0x0004993b... (100 %)
Wrote 237328 bytes (132047 compressed) at 0x00010000 in 1.9 seconds (effective 1005.1 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...
--- Terminal on /dev/cu.usbmodem2101 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H

None of the key combinations work either, so I don’t get a menu with ctrl-t and I cannot quit with ctrl-C.

Sample app on this page

I have also had to add setup() and loop() functions to the sample app to compile it, which might explain it. It refuses to compile if I don’t add them.

/Users/localuser/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: .pio/build/seeed_xiao_esp32s3/libFrameworkArduino.a(main.cpp.o):(.literal._Z8loopTaskPv+0x8): undefined reference to `loop()'
/Users/localuser/.platformio/packages/toolchain-xtensa-esp32s3/bin/../lib/gcc/xtensa-esp32s3-elf/8.4.0/../../../../xtensa-esp32s3-elf/bin/ld: .pio/build/seeed_xiao_esp32s3/libFrameworkArduino.a(main.cpp.o): in function `loopTask(void*)':
/Users/localuser/.platformio/packages/framework-arduinoespressif32/cores/esp32/main.cpp:48: undefined reference to `loop()'

Here is the error message if I miss loop out? I am a little pissed since nothing on the Wikipedia page works. Neither example of freeRTOS.

Let’s get back to the absolute basics.

Use this as src/main.cpp

#include <Arduino.h>

void setup() {
  Serial.begin(9600);
  while(!Serial) { }
  Serial.println("Sketch running!");
}

void loop() {
  Serial.println("Hello world!");
  delay(1000);
}

with a platformio.ini of

[env:seeed_xiao_esp32s3]
platform = espressif32@6.8.1
board = seeed_xiao_esp32s3
framework = arduino

Use the “Upload and Monitor” task. Does it output anything?

Yes, this works perfectly

So, it must either be that the sketch or platformio.ini that you’re using is wrong.

Can you upload the exact project that is failing to show output?

Sorry I don’t know how to make this look like code in this editor.

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#include "esp_log.h"

// put function declarations here:


TaskHandle_t task1,task2,task3,task4;

void taskFunction1(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task1", "Hello from task 1");
        vTaskDelay(pdMS_TO_TICKS(1000)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction2(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task2", "Hello from task 2");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction3(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task3", "Hello from task 3");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction4(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task4", "Hello from task 4");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}


void setup() {
  printf("Hello World");
} 

void loop() {

}

void app_main(void) {
    xTaskCreatePinnedToCore(
        taskFunction1, /* Function that implements the task. */
        "task_1",        /* Text name for the task. */
        configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
        NULL,            /* Parameter passed into the task. */
        tskIDLE_PRIORITY, /* Priority at which the task is created. */
        &task1,         /* Used to pass out the created task's handle. */
        0);              /* Core ID */

    xTaskCreatePinnedToCore(
        taskFunction2, /* Function that implements the task. */
        "task_2",        /* Text name for the task. */
        configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
        NULL,            /* Parameter passed into the task. */
        tskIDLE_PRIORITY, /* Priority at which the task is created. */
        &task2,         /* Used to pass out the created task's handle. */
        1);              /* Core ID */

    xTaskCreatePinnedToCore(
        taskFunction3, /* Function that implements the task. */
        "task_3",        /* Text name for the task. */
        configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
        NULL,            /* Parameter passed into the task. */
        tskIDLE_PRIORITY, /* Priority at which the task is created. */
        &task3,         /* Used to pass out the created task's handle. */
        1);              /* Core ID */

    xTaskCreatePinnedToCore(
        taskFunction4, /* Function that implements the task. */
        "task_4",        /* Text name for the task. */
        configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
        NULL,            /* Parameter passed into the task. */
        tskIDLE_PRIORITY, /* Priority at which the task is created. */
        &task4,         /* Used to pass out the created task's handle. */
        1);              /* Core ID */
}

This project won’t compile if I don’t include setup() and loop() which makes no sense; and it outputs nothing either way. I tried it on an ESP32S3 and an ESP32C3.

Neither produce any output at all.

The ini file looks like this

[env:seeed_xiao_esp32c3]
platform = espressif32@6.8.1
board = seeed_xiao_esp32c3
framework = arduino

So, yes I just tried it on a C3 as well.

Oh this makes a lot of sense. When using framework = arduino, your Arduino sketch is required to have setup() and loop(). When using framework = espidf, your ESP-IDF application code is required to have app_main() (with C linkage).

It seems to me you’re copy-pasting code intended for the ESP-IDF framework into a project setup for Arduino.

The code is taken from the seeed Wikipedia; I had to enter loop and setup to get it to compile.

Yes. But they clearly state it’s intended for the ESP-IDF framework. It’s not an Arduino sketch.

Two ways from here:

You convert that ESP-IDF app code to be an Arduino sketch. For that, copy paste the contents of the original app_main() function into setup(). At least call Serial.begin(9600); too, to initialize the USB serial. Since the Arduino framework is using ESP-IDF as the base, you can still do all these xTaskCreate() calls in an Arduino sketch. I would recommend this if you don’t want to mess with the lower-level ESP-IDF framework but want to stay in the sunshine-easy Arduino framework.

Or, you create a proper “Framework: ESP-IDF” project through the project wizard and set everything up, that includes the menuconfig, for the USB serial. PlatformIO has examples for that.

Specifically, this here should be the converted Arduino sketch:

#include <Arduino.h>

TaskHandle_t task1,task2,task3,task4;

void taskFunction1(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task1", "Hello from task 1");
        vTaskDelay(pdMS_TO_TICKS(1000)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction2(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task2", "Hello from task 2");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction3(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task3", "Hello from task 3");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction4(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task4", "Hello from task 4");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}


void setup() {
    Serial.begin(9600);
    // wait for serial init
    while(!Serial) {}
	xTaskCreatePinnedToCore(
		taskFunction1, /* Function that implements the task. */
		"task_1",        /* Text name for the task. */
		configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task1,         /* Used to pass out the created task's handle. */
		0);              /* Core ID */

	xTaskCreatePinnedToCore(
		taskFunction2, /* Function that implements the task. */
		"task_2",        /* Text name for the task. */
		configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task2,         /* Used to pass out the created task's handle. */
		1);              /* Core ID */

	xTaskCreatePinnedToCore(
		taskFunction3, /* Function that implements the task. */
		"task_3",        /* Text name for the task. */
		configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task3,         /* Used to pass out the created task's handle. */
		1);              /* Core ID */

	xTaskCreatePinnedToCore(
		taskFunction4, /* Function that implements the task. */
		"task_4",        /* Text name for the task. */
		configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task4,         /* Used to pass out the created task's handle. */
		1);              /* Core ID */
} 

void loop() { delay(1000); /* nothing */ }

Ok, now you’re making some sense, changed the ini to the espidf architecture and now I get…

Missing the pip binary!

But pip is installed?

localuser@marc-macbook-pro freeRTOS_1 % python3 -m pip --version

pip 24.2 from /Users/localuser/.espressif/python_env/idf5.4_py3.12_env/lib/python3.12/site-packages/pip (python 3.12)

localuser@marc-macbook-pro freeRTOS_1 %

You seem to be operating PlatformIO (which is itself a Python package) from within… the Python environment created by the Espressif ESP-IDF VSCode extension? That doesn’t bode well. I would recommend if you want to work with PlatformIO, to uninstall the ESP-IDF VSCode extension and reinstall the PlatformIO VSCode extension, to get a clean install in the regular Python environment.

Also, changing framework = espidf is not the only thing needed to convert the PlatformIO project to use the ESP-IDF framework. It wants its two CMakeLists.txt files, at the least.

I would heavily recommend to just try the Arduino framework converted code first. ESP-IDF is a low level framework that is hard to get into.

1 Like

Ok,

But if you read the docs, is says you don’t get a full freeRTOS environment unless you use Visual Studio Code I think with ESP-IDF. Do I use both processors if I use the arduino sketch as your suggesting?

If not why would I use Visual Studio Code?

Ok, I am going to uninstall Espressif that is installed but disabled and reinstall platformIO.

Thanks in advance for your help! I will let you know.

Primary info , this creati info level log, and this show by default nothink…

What does this mean? I just tried the arduino version and there was no output… it compiles, but again nothing on the screen.

BS.

Within an Arduino sketch / framework = arduino project, you have full access to the underlying ESP-IDF. That includes FreeRTOS. There are lots of tutorials on how to use both cores of an ESP32 chip, e.g.,

Ok. I striped down everything to the absolute minimum and it works, using the freeRTOS environment.

I will test their assertion that you don’t get the full kit Max.

Thanks for your help! You a life saver!!

Just to prove my point, the code from the tutorial is working when properly converting it to Arduino.

That does include adding Serial.setDebugOutput(true); and build_flags = -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG so that ESP_LOGI etc logs something at all. I also had to increase the tasks’ stack sizes from the measily minimal to 3 times that amount, if they’re printf’ing stuff, they need some stack memory to work with.

Reference sketch below.

#include <Arduino.h>

TaskHandle_t task1,task2,task3,task4;

void taskFunction1(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task1", "Hello from task 1");
        vTaskDelay(pdMS_TO_TICKS(1000)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction2(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task2", "Hello from task 2");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction3(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task3", "Hello from task 3");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}

void taskFunction4(void * pvParameters) {
    while (true) {
        ESP_LOGI("Task4", "Hello from task 4");
        vTaskDelay(pdMS_TO_TICKS(500)); // Add a delay to avoid overwhelming the output
    }
}


void setup() {
    Serial.begin(115200);
    Serial.setDebugOutput(true);
    // wait for serial init
    while(!Serial) {}
	xTaskCreatePinnedToCore(
		taskFunction1, /* Function that implements the task. */
		"task_1",        /* Text name for the task. */
		3*configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task1,         /* Used to pass out the created task's handle. */
		0);              /* Core ID */

	xTaskCreatePinnedToCore(
		taskFunction2, /* Function that implements the task. */
		"task_2",        /* Text name for the task. */
		3*configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task2,         /* Used to pass out the created task's handle. */
		1);              /* Core ID */

	xTaskCreatePinnedToCore(
		taskFunction3, /* Function that implements the task. */
		"task_3",        /* Text name for the task. */
		3*configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task3,         /* Used to pass out the created task's handle. */
		1);              /* Core ID */

	xTaskCreatePinnedToCore(
		taskFunction4, /* Function that implements the task. */
		"task_4",        /* Text name for the task. */
		3*configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */
		NULL,            /* Parameter passed into the task. */
		tskIDLE_PRIORITY, /* Priority at which the task is created. */
		&task4,         /* Used to pass out the created task's handle. */
		1);              /* Core ID */
} 

void loop() { delay(1000); /* nothing */ }

And equally, the unmodified code from the Seeed Wiki will work when putting it into a correctly setup ESP-IDF project. As is e.g. https://github.com/platformio/platform-espressif32/tree/develop/examples/espidf-hello-world as a good basis. But you have to configure lots of stuff yourself and deal with the CMake.

Max,

This is the text that is in the back of my mind. But it runs the way it does because it uses some libraries from the freeRTOS with the Arduino IDE.

The secret here is that .ini file that I didn’t understand at all. Your help has been invaluable! Thanks.

I want to lock a process to a processor and use a mutex to govern how they talk to each other. Hopefully tomorrow I can do some coding again…

I think the text is misleadingly written.

Yes, the Arduino-ESP32 by default only runs on Core 0, but still, one can freely call into the FreeRTOS function to run a task on the other core too… Because the underlying FreeRTOS library should be capable of that…