Skip to content

Commit 94b787e

Browse files
committed
Dual Core ESP32
1 parent 2dc4dc8 commit 94b787e

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed
501 KB
Loading

content/hardware/03.nano/boards/nano-esp32/tutorials/cheat-sheet/cheat-sheet.md

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,126 @@ Further reading:
450450
- [I2S API docs (Espressif)](https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/api/i2s.html)
451451
- [I2S Reference (Espressif)](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/i2s.html)
452452

453+
## Dual Core
453454

455+
The ESP32-S3 is based on the dual-core XTensa LX7, which can run code separately on two cores. This is enabled through FreeRTOS, by setting up tasks that run on each core (similarly to how `void loop()` is implemented). The cores available are `0` and `1`.
456+
457+
The example below is a modified version of the [BasicMultiThreading](https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading) example found in the Arduino ESP32 core, and demonstrates how to use two common operations simulatenously:
458+
- Blink an LED using one task on a specific core (0),
459+
- Read an analog pin using a second task on a specific core (1).
460+
461+
```arduino
462+
/* Basic Multi Threading Arduino Example
463+
464+
Modified 16th October 2023 by Karl Söderby
465+
466+
Set up two tasks that run on each core of a Nano ESP32 (ESP32-S3 XTensa LX7 MCU),
467+
one that blinks an LED, one that reads an analog signal.
468+
469+
These tasks will execute infinitely.
470+
471+
This example code is in the Public Domain (or CC0 licensed, at your option.)
472+
Unless required by applicable law or agreed to in writing, this
473+
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
474+
CONDITIONS OF ANY KIND, either express or implied.
475+
*/
476+
477+
// Define the cores
478+
#define CORE_0 0
479+
#define CORE_1 1
480+
481+
#define ANALOG_INPUT_PIN A0 //Specify analog pin
482+
#define LED_BUILTIN 13 // Specify the on which is your LED
483+
484+
485+
int counter = 0;
486+
// Define two tasks for Blink & AnalogRead.
487+
void TaskBlink(void *pvParameters);
488+
void TaskAnalogRead(void *pvParameters);
489+
TaskHandle_t analog_read_task_handle; // You can (don't have to) use this to be able to manipulate a task from somewhere else.
490+
491+
void setup() {
492+
Serial.begin(115200);
493+
uint32_t blink_delay = 1000; // Delay between changing state on LED pin
494+
495+
//create task for blinking an LED
496+
xTaskCreatePinnedToCore(
497+
TaskBlink, "Task Blink" // A name just for humans
498+
,
499+
2048 // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);`
500+
,
501+
(void *)&blink_delay // Task parameter which can modify the task behavior. This must be passed as pointer to void.
502+
,
503+
2 // Priority
504+
,
505+
NULL // Task handle is not used here - simply pass NULL
506+
,
507+
CORE_0 // Core on which the task will run
508+
);
509+
510+
//create a task for reading analog signals
511+
xTaskCreatePinnedToCore(
512+
TaskAnalogRead, "Analog Read", 2048 // Stack size
513+
,
514+
NULL // When no parameter is used, simply pass NULL
515+
,
516+
1 // Priority
517+
,
518+
&analog_read_task_handle // With task handle we will be able to manipulate with this task.
519+
,
520+
CORE_1 // Core on which the task will run
521+
);
522+
}
523+
524+
void loop() {
525+
//loop is empty, the tasks are instead looped infinitely
526+
}
527+
528+
void TaskBlink(void *pvParameters) { // This is a task.
529+
uint32_t blink_delay = *((uint32_t *)pvParameters);
530+
531+
pinMode(LED_BUILTIN, OUTPUT);
532+
533+
for (;;) { // A Task shall never return or exit.
534+
counter++;
535+
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
536+
537+
delay(1000);
538+
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
539+
540+
delay(1000);
541+
Serial.print("Core ");
542+
Serial.print(CORE_0);
543+
Serial.print(": Blink task complete. Times run: ");
544+
Serial.println(counter);
545+
}
546+
}
547+
548+
void TaskAnalogRead(void *pvParameters) { // This is a task.
549+
(void)pvParameters;
550+
551+
for (;;) {
552+
// read the input on analog pin:
553+
int sensorValue = analogRead(ANALOG_INPUT_PIN);
554+
// print out the value you read:
555+
Serial.print("Core ");
556+
Serial.print(CORE_1);
557+
Serial.print(": Analog reading task, value is: ");
558+
Serial.println(sensorValue);
559+
delay(500); // 100ms delay
560+
}
561+
}
562+
```
563+
564+
When running this example, open the Serial Monitor tool and you will see what happens on each core.
565+
566+
![Dual core example.](assets/nano-esp32-dualcore.png)
567+
568+
- The task is created in the `xTaskCreatePinnedToCore()`,
569+
- inside `xTaskCreatePinnedToCore()` we specifiy a number of parameters, most importantly what **core** and what **function** to run,
570+
- code inside task functions are placed inside the `for (;;){}` statement, that will loop infinitely.
571+
572+
***More information about dual-core on the ESP32 along with a detailed explanation of the example is available at [Basic Multi Threading Example](https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/FreeRTOS/BasicMultiThreading).***
454573

455574
## IO Mux & GPIO Matrix
456575

0 commit comments

Comments
 (0)