├── .gitattributes ├── README.md ├── ESP32_ShowCore └── ESP32_ShowCore.ino ├── Arduino_SpeedTest └── Arduino_SpeedTest.ino ├── ESP32_MoveCore └── ESP32_MoveCore.ino ├── ESP32_Two_LED_Asynchron └── ESP32_Two_LED_Asynchron.ino ├── ESP32_TwoTasks_Template └── ESP32_TwoTasks_Template.ino ├── ESP32_SpeedTest └── ESP32_SpeedTest.ino ├── ESP32_Two_LED_Synchron └── ESP32_Two_LED_Synchron.ino └── ESP32_WhichCore └── ESP32_WhichCore.ino /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ESP32 Dual-Core 2 | 3 | 4 | YouTube video: https://www.youtube.com/watch?v=k_D_Qu0cgu8 5 | -------------------------------------------------------------------------------- /ESP32_ShowCore/ESP32_ShowCore.ino: -------------------------------------------------------------------------------- 1 | #define LED1 14 2 | 3 | void setup() { 4 | Serial.begin(115200); 5 | pinMode(LED1, OUTPUT); 6 | } 7 | 8 | // the loop function runs over and over again forever 9 | void loop() { 10 | Serial.print("This Task runs on Core: "); 11 | Serial.println(xPortGetCoreID()); 12 | 13 | digitalWrite(LED1, HIGH); // turn the LED on (HIGH is the voltage level) 14 | delay(1000); // wait for a second 15 | digitalWrite(LED1, LOW); // turn the LED off by making the voltage LOW 16 | delay(1000); // wait for a second 17 | } 18 | -------------------------------------------------------------------------------- /Arduino_SpeedTest/Arduino_SpeedTest.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This sketch runs a artificial load on both cores to measure maximum compute power of the ESP32 3 | */ 4 | 5 | 6 | unsigned long loops1 = 1000; 7 | unsigned long loops2 = 1000; 8 | 9 | 10 | float t1; 11 | int t2; 12 | int t3; 13 | 14 | 15 | 16 | unsigned long qq = 0; 17 | 18 | 19 | void artificialLoad () { 20 | for ( long i = 0; i < loops1; i++) { 21 | for (long j = 1; j < loops2; j++) { 22 | qq++; 23 | t1 = 5000.0 * i; 24 | t2 = 150 * 1234 * i; 25 | t3 = j % 554 ; 26 | } 27 | } 28 | } 29 | 30 | void setup() { 31 | Serial.begin(115200); 32 | Serial.println("Start"); 33 | } 34 | 35 | void loop() { 36 | long start = millis(); 37 | 38 | artificialLoad(); 39 | 40 | Serial.print("Finish Loop Task "); 41 | Serial.print(" Time "); 42 | Serial.println(millis() - start); 43 | delay(10); 44 | } 45 | -------------------------------------------------------------------------------- /ESP32_MoveCore/ESP32_MoveCore.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch moves the blink sketch from Core 1 in loop to Core 0 3 | */ 4 | 5 | #define LED1 14 6 | 7 | TaskHandle_t Task1; 8 | 9 | void codeForTask1( void * parameter ) 10 | { 11 | for (;;) { 12 | Serial.print("This Task runs on Core: "); 13 | Serial.println(xPortGetCoreID()); 14 | 15 | digitalWrite(LED1, HIGH); // turn the LED on (HIGH is the voltage level) 16 | delay(1000); // wait for a second 17 | digitalWrite(LED1, LOW); // turn the LED off by making the voltage LOW 18 | delay(1000); // wait for a second 19 | } 20 | } 21 | 22 | void setup() { 23 | Serial.begin(115200); 24 | pinMode(LED1, OUTPUT); 25 | 26 | xTaskCreatePinnedToCore( 27 | codeForTask1, /* Task function. */ 28 | "Task_1", /* name of task. */ 29 | 1000, /* Stack size of task */ 30 | NULL, /* parameter of the task */ 31 | 1, /* priority of the task */ 32 | &Task1, /* Task handle to keep track of created task */ 33 | 0); /* Core */ 34 | } 35 | 36 | // the loop function runs over and over again forever 37 | void loop() { 38 | delay(1000); 39 | } 40 | -------------------------------------------------------------------------------- /ESP32_Two_LED_Asynchron/ESP32_Two_LED_Asynchron.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This blinks two LEDs independently and not synchronized. Both have other blink frequencies. 3 | * The blink sketches run in two tasks and on two cores. 4 | */ 5 | 6 | #define LED1 13 7 | #define LED2 14 8 | 9 | TaskHandle_t Task1, Task2; 10 | 11 | 12 | int counter = 0; 13 | 14 | void blink(byte pin, int duration) { 15 | 16 | digitalWrite(pin, HIGH); 17 | delay(duration); 18 | digitalWrite(pin, LOW); 19 | delay(duration); 20 | } 21 | 22 | void codeForTask1( void * parameter ) 23 | { 24 | for (;;) { 25 | blink(LED1, 1000); 26 | delay(50); 27 | Serial.println("Task 1: "); 28 | } 29 | } 30 | 31 | void codeForTask2( void * parameter ) 32 | { 33 | for (;;) { 34 | blink(LED2, 1200); 35 | delay(50); 36 | Serial.println(" Task 2: "); 37 | } 38 | } 39 | 40 | // the setup function runs once when you press reset or power the board 41 | void setup() { 42 | Serial.begin(115200); 43 | // initialize digital pin LED_BUILTIN as an output. 44 | 45 | pinMode(LED1, OUTPUT); 46 | pinMode(LED2, OUTPUT); 47 | 48 | xTaskCreatePinnedToCore( 49 | codeForTask1, 50 | "led1Task", 51 | 1000, 52 | NULL, 53 | 1, 54 | &Task1, 55 | 0); 56 | delay(500); // needed to start-up task1 57 | 58 | xTaskCreatePinnedToCore( 59 | codeForTask2, 60 | "led2Task", 61 | 1000, 62 | NULL, 63 | 1, 64 | &Task2, 65 | 1); 66 | 67 | } 68 | 69 | void loop() { 70 | delay(1000); 71 | } 72 | -------------------------------------------------------------------------------- /ESP32_TwoTasks_Template/ESP32_TwoTasks_Template.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This sketch can be used as a template to create your own dual core application. 3 | You can either pot code in codeForTask1, codeForTask2, or loop. Make sure, you 4 | place a delay(1000) in all unused tasks 5 | 6 | */ 7 | long loops1 = 1000; 8 | long loops2 = 1000; 9 | long qq; 10 | float t1; 11 | int t2, t3; 12 | 13 | TaskHandle_t Task1, Task2; 14 | SemaphoreHandle_t baton; 15 | 16 | void artificialLoad () { 17 | for ( long i = 0; i < loops1; i++) { 18 | for (long j = 1; j < loops2; j++) { 19 | qq++; 20 | t1 = 5000.0 * i; 21 | t2 = 150 * 1234 * i; 22 | t3 = j % 554 ; 23 | } 24 | } 25 | } 26 | 27 | 28 | void codeForTask1( void * parameter ) 29 | { 30 | for (;;) { 31 | delay(1000); 32 | } 33 | } 34 | 35 | void codeForTask2( void * parameter ) 36 | { 37 | for (;;) { 38 | delay(1000); 39 | } 40 | } 41 | 42 | // the setup function runs once when you press reset or power the board 43 | void setup() { 44 | Serial.begin(115200); 45 | 46 | baton = xSemaphoreCreateMutex(); 47 | 48 | xTaskCreatePinnedToCore( 49 | codeForTask1, 50 | "led1Task", 51 | 1000, 52 | NULL, 53 | 1, 54 | &Task1, 55 | 1); 56 | 57 | delay(500); // needed to start-up task1 58 | 59 | xTaskCreatePinnedToCore( 60 | codeForTask2, 61 | "led2Task", 62 | 1000, 63 | NULL, 64 | 1, 65 | &Task2, 66 | 0); 67 | } 68 | 69 | 70 | void loop() { 71 | long start = millis(); 72 | 73 | artificialLoad(); 74 | 75 | Serial.print("Finish Loop Task which runs on Core "); 76 | Serial.print( xPortGetCoreID()); 77 | Serial.print(" Time "); 78 | Serial.println(millis() - start); 79 | delay(10); 80 | } 81 | -------------------------------------------------------------------------------- /ESP32_SpeedTest/ESP32_SpeedTest.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This sketch runs a artificial load on both cores to measure maximum compute power of the ESP32 3 | */ 4 | 5 | 6 | unsigned long loops1 = 1000; 7 | unsigned long loops2 = 1000; 8 | 9 | 10 | float t1; 11 | int t2; 12 | int t3; 13 | 14 | 15 | 16 | unsigned long qq = 0; 17 | 18 | TaskHandle_t Task1, Task2; 19 | 20 | 21 | void artificialLoad () { 22 | for ( long i = 0; i < loops1; i++) { 23 | for (long j = 1; j < loops2; j++) { 24 | qq++; 25 | t1 = 5000.0 * i; 26 | t2 = 150 * 1234 * i; 27 | t3 = j % 554 ; 28 | } 29 | } 30 | } 31 | 32 | void codeForTask1( void * parameter ) 33 | { 34 | unsigned long i, j; 35 | for (;;) { 36 | long start = millis(); 37 | 38 | artificialLoad(); 39 | 40 | Serial.print("Finish Task 1 which runs on Core "); 41 | Serial.print( xPortGetCoreID()); 42 | Serial.print(" Time "); 43 | Serial.println(millis() - start); 44 | delay(10); 45 | } 46 | } 47 | 48 | void codeForTask2( void * parameter ) 49 | { 50 | for (;;) { 51 | long start = millis(); 52 | 53 | artificialLoad(); 54 | 55 | Serial.print(" Finish Task 2 which runs on Core "); 56 | Serial.print( xPortGetCoreID()); 57 | Serial.print(" Time "); 58 | Serial.println(millis() - start); 59 | delay(10); 60 | } 61 | } 62 | 63 | // the setup function runs once when you press reset or power the board 64 | void setup() { 65 | Serial.begin(115200); 66 | // initialize digital pin LED_BUILTIN as an output. 67 | 68 | xTaskCreatePinnedToCore( 69 | codeForTask1, 70 | "led1Task", 71 | 1000, 72 | NULL, 73 | 1, 74 | &Task1, 75 | 0); 76 | delay(500); // needed to start-up task1 77 | 78 | xTaskCreatePinnedToCore( 79 | codeForTask2, 80 | "led2Task", 81 | 1000, 82 | NULL, 83 | 1, 84 | &Task2, 85 | 1); 86 | 87 | } 88 | 89 | void loop() { 90 | delay(1000); 91 | } 92 | -------------------------------------------------------------------------------- /ESP32_Two_LED_Synchron/ESP32_Two_LED_Synchron.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This sketch uses semaphores to synchronize two LEDs. The blink sketches run in two tasks and on two cores. 3 | As shown in hte video you can either blink them sequencially or in parallel 4 | */ 5 | #define LED1 13 6 | #define LED2 14 7 | 8 | TaskHandle_t Task1, Task2; 9 | SemaphoreHandle_t baton; 10 | 11 | int counter = 0; 12 | 13 | void blink(byte pin, int duration) { 14 | 15 | digitalWrite(pin, HIGH); 16 | delay(duration); 17 | digitalWrite(pin, LOW); 18 | delay(duration); 19 | 20 | } 21 | 22 | void codeForTask1( void * parameter ) 23 | { 24 | for (;;) { 25 | xSemaphoreTake( baton, portMAX_DELAY ); 26 | blink(LED1, 1000); 27 | xSemaphoreGive( baton ); 28 | delay(50); 29 | Serial.print("Counter in Task 1: "); 30 | Serial.println(counter); 31 | counter++; 32 | } 33 | } 34 | 35 | void codeForTask2( void * parameter ) 36 | { 37 | for (;;) { 38 | xSemaphoreTake( baton, portMAX_DELAY ); 39 | blink(LED2, 1200); 40 | xSemaphoreGive( baton ); 41 | delay(50); 42 | Serial.print(" Counter in Task 2: "); 43 | Serial.println(counter); 44 | counter++; 45 | } 46 | } 47 | 48 | // the setup function runs once when you press reset or power the board 49 | void setup() { 50 | Serial.begin(115200); 51 | // initialize digital pin LED_BUILTIN as an output. 52 | 53 | pinMode(LED1, OUTPUT); 54 | pinMode(LED2, OUTPUT); 55 | 56 | baton = xSemaphoreCreateMutex(); 57 | 58 | // A viewer suggested to use : &codeForTask1, because his ESP crashed 59 | 60 | xTaskCreatePinnedToCore( 61 | codeForTask1, 62 | "led1Task", 63 | 1000, 64 | NULL, 65 | 1, 66 | &Task1, 67 | 0); 68 | delay(500); // needed to start-up task1 69 | 70 | xTaskCreatePinnedToCore( 71 | codeForTask2, 72 | "led2Task", 73 | 1000, 74 | NULL, 75 | 1, 76 | &Task2, 77 | 1); 78 | 79 | } 80 | 81 | 82 | void loop() { 83 | 84 | delay(10); 85 | } 86 | -------------------------------------------------------------------------------- /ESP32_WhichCore/ESP32_WhichCore.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Blink 3 | 4 | Turns an LED on for one second, then off for one second, repeatedly. 5 | 6 | Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO 7 | it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to 8 | the correct LED pin independent of which board is used. 9 | If you want to know what pin the on-board LED is connected to on your Arduino 10 | model, check the Technical Specs of your board at: 11 | https://www.arduino.cc/en/Main/Products 12 | 13 | modified 8 May 2014 14 | by Scott Fitzgerald 15 | modified 2 Sep 2016 16 | by Arturo Guadalupi 17 | modified 8 Sep 2016 18 | by Colby Newman 19 | 20 | This example code is in the public domain. 21 | 22 | http://www.arduino.cc/en/Tutorial/Blink 23 | */ 24 | 25 | #define LED_BUILTIN 14 26 | 27 | TaskHandle_t Task1, Task2; 28 | 29 | 30 | void codeForTask1( void * parameter ) 31 | { 32 | for (;;); 33 | } 34 | 35 | void codeForTask2( void * parameter ) 36 | { 37 | for (;;); 38 | } 39 | 40 | // the setup function runs once when you press reset or power the board 41 | void setup() { 42 | Serial.begin(115200); 43 | // initialize digital pin LED_BUILTIN as an output. 44 | pinMode(LED_BUILTIN, OUTPUT); 45 | 46 | xTaskCreatePinnedToCore( 47 | codeForTask1, /* Task function. */ 48 | "Task1", /* name of task. */ 49 | 1000, /* Stack size of task */ 50 | NULL, /* parameter of the task */ 51 | 1, /* priority of the task */ 52 | &Task1, /* Task handle to keep track of created task */ 53 | 1); /* Core */ 54 | delay(500); 55 | 56 | xTaskCreatePinnedToCore( 57 | codeForTask2, /* Task function. */ 58 | "Task2", /* name of task. */ 59 | 1000, /* Stack size of task */ 60 | NULL, /* parameter of the task */ 61 | 1, /* priority of the task */ 62 | &Task2, /* Task handle to keep track of created task */ 63 | 1); /* Core */ /* Core */ 64 | } 65 | 66 | 67 | 68 | // the loop function runs over and over again forever 69 | void loop() { 70 | Serial.printf("Core %d\n ", xPortGetCoreID()); 71 | digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) 72 | delay(1000); // wait for a second 73 | digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW 74 | delay(1000); // wait for a second 75 | } 76 | --------------------------------------------------------------------------------