Purpose
This project series is to study the capablilities of the ESP32 MCU family, with emphasise on C3 and S3 chips. The development environment is VS Code with the ESP-IDF extension. OOP approach based on C++ will be used as far as possible.
P01 Objectives
- ESP32-S3 Developement Board
- Model YD-ESP32-S3 N16R8, which is compatible with Expressif ESP32-S3-DevKitC-1 board.
- OOP approach based on C++
- Set up components to contain required classes.
- HW connections:
- LED -> GPIO_38
- Btn 1 -> GPIO_7
- Btn 2 -> GPIO_10
- LED blinks at 1200 ms interval
- Button 1 – press to change blink interval to 600 ms.
- Button 2 – press to change blink interval to 300 ms.
Resources
- VCC-GND Studio – Hardware Info
- Tutorial: ESP32 with ESP-IDF and C++ in Windows
- ESP32 之 ESP-IDF 教学(五(2))——使用C++的工程
Convert C Project to C++
Create a new project using the idf template and rename the project to gpio_button. See this post for the ways to renaming projects.
Connect the LED circuit to GPIO38 and flash with a firmware to blink the LED.
Convert this C project to C++ by following this article: ESP32 之 ESP-IDF 教学(五(2))——使用C++的工程
Open CMakeLists.txt and check its content with reference to the example below.
cmake_minimum_required(VERSION 3.8)
set(CMAKE_CXX_STANDARD 17)
set(EXTRA_COMPONENT_DIRS components)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(gpio_button)
Cmake minimum version is 3.8 in order to support C++ standard 17.
Convert led_blink( ) function to a C++ component
After successfully converted the project to C++, its time to wrap the led_blink( ) function to a C++ component.
The general approach to create a C++ component
- access ESP-IDF: Create new ESP-IDF Component
- under the ‘include’ directory, create .h header file.
- inside the header file, create the required class with attributes, constructor, and declare necessary methods.
- rename the “.c” file to “.cpp” for the concerned component.
- inside the cpp file, define the methods which are declared in the header file.
- inside the main.cpp, add the #include line for the header file.
- check the content of the component CMakeLists.txt with reference to the example below.
idf_component_register(SRCS "sayhello.cpp"
INCLUDE_DIRS "include")
Folder Structure

main/main.cpp
#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "sayhello.h"
#include "flash_led.h"
extern "C" void app_main(void)
{
SayHello SH("Chairman");
SH.toSay();
vTaskDelay(3000 / portTICK_PERIOD_MS);
flashLED LED38(GPIO_NUM_38);
LED38.toFlash(1200);
}
main/CmakeLists.txt
idf_component_register(SRCS "main.cpp"
INCLUDE_DIRS ".")
components/flash_led/flash_led.cpp
#include "flash_led.h"
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
void flashLED::toFlash(int millisec)
{
gpio_pad_select_gpio(LED_PIN);
gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
gpio_pad_select_gpio(Btn1_PIN); // btn 1
gpio_pad_select_gpio(Btn2_PIN); // btn 2
gpio_set_direction(Btn1_PIN, GPIO_MODE_INPUT);
gpio_set_direction(Btn2_PIN, GPIO_MODE_INPUT);
gpio_set_pull_mode(Btn1_PIN, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(Btn2_PIN, GPIO_PULLUP_ONLY);
while (1)
{
int interv = millisec;
if (! gpio_get_level(Btn1_PIN))
interv = 600;
if (! gpio_get_level(Btn2_PIN))
interv = 300;
gpio_set_level(LED_PIN, 0);
printf("LED off...\n");
vTaskDelay(interv / portTICK_RATE_MS);
gpio_set_level(LED_PIN, 1);
printf("LED on.......\n");
vTaskDelay(interv / portTICK_RATE_MS);
} // while()
} // toFlash()
components/flash_led/CMakeLists.txt
idf_component_register(SRCS "flash_led.cpp"
INCLUDE_DIRS "include")
components/flash_led/include/flash_led.h
#ifndef FLASH_LED_H
#define FLASH_LED_H
#include <driver/gpio.h>
class flashLED {
private:
gpio_num_t LED_PIN;
gpio_num_t Btn1_PIN = GPIO_NUM_7;
gpio_num_t Btn2_PIN = GPIO_NUM_10;
int msInterval;
public:
flashLED(gpio_num_t pin) {
LED_PIN = pin;
}
void toFlash(int millisec);
}; // end class
#endif
S3 Dev Bd Layout


