ESP32 Arduino Framework是专门针对ESP32开发板的Arduino应用开发框架,为用户开发IOT应用、HMI应用提供一致的开发体验。 目前支持以下功能: 提供常用LCD、OLED显示屏设备的驱动
框架使用Board类及派生类来封装硬件驱动,使用Application类及派生类来实现业务逻辑处理。Board类和Application类之前通过公开方法互相访问,如下图:

这样实现有以下优点:
下面以点亮LED为例,来说明ESP32 Arduino框架的使用
#define LED_PIN 4
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH);
delay(1000);
digitalWrite(LED_PIN, LOW);
delay(1000);
}
简单到不言自明了,相信大家都写过很多次类似点亮LED的代码。
这就是面向过程的代码,这里没有LED灯对象,我们操作的是一个连接着LED灯的引脚。
第一步:实现一个自定义的Board派生类MyBoard,然后创建一个GpioLed类的实例。
在my_board.h文件中,定义MyBoard类:
class MyBoard : public Board {
private:
Led* led_ = nullptr;
public:
MyBoard();
Led* GetLed() override { return led_; }
};
在my_board.cpp文件中,创建GpioLed类实例,这里GpioLed类是Led类的一个子类:
MyBoard::MyBoard() : Board() {
Log::Info(TAG, "===== Create Board ...... =====");
Log::Info(TAG, "initial led.");
led_ = new GpioLed(BUILTIN_LED_PIN, false); // no pwm
Log::Info( TAG, "===== Board config completed. =====");
}
第二步:实现一个自定义的Application派生类MyApplication,然后实现点亮LED的代码。
在my_application.h文件中,定义MyApplication类和继承的方法:
class MyApplication : public Application {
public:
MyApplication();
const std::string& GetAppName() const override { return "Unit1-Lesson13"; }
const std::string& GetAppVersion() const override { return "1.0.0"; }
protected:
void OnInit() override;
void OnLoop() override;
};
这里我们重写父类的OnInit方法用于执行初始化的相关代码、重写OnLoop方法用于执行要重复执行的业务代码。
在my_application.cpp文件中,实现点亮LED的代码:
void MyApplication::OnInit() {
// do your init.
Log::Info(TAG, "OnInit");
}
void MyApplication::OnLoop() {
Led *led = Board::GetInstance().GetLed();
led->TurnOn();
delay(1000);
led->TurnOff();
delay(1000);
}
可以看到此处先取得Board类实例(即MyBoard类实例),再取得Led类实例变量,
然后调用Led类实例的TurnOn方法点亮LED、调用TurnOff方法熄灭LED,
这就是面向对象的代码,动作都是基于对象实例的方法来完成的。
而在TurnOn和TurnOff方法里,我们才具体调用digitalWrite方法来控制led的引脚电平。
GpioLed类的具体实现代码请参照src/framework/led/gpio_led.cpp文件
那么OnInit和OnLoop方法是在何处被调用的呢?
main.cpp是ESP32 Arduino框架的入口程序,它替代了ino文件的功能,即定义setup方法和loop方法,代码如下:
Application *app = nullptr;
void setup() {
Serial.begin(115200);
Log::Info(TAG, "application starting.");
// 创建应用实例
app = &Application::GetInstance();
app->Init();
}
void loop() {
app->Loop();
}
可以看到在setup方法里,先取得Application类实例(即MyApplication实例),然后调用Application类实例的Init方法,在loop方法里,直接调用Application类实例的Loop方法。
Init方法
void Application::Init() {
Log::Info(TAG, "Initialize...");
// 省略部分代码
OnInit();
// 省略部分代码
Log::Info(TAG, "Started.");
}
在此方法中,会做一些公共的初始化操作,然后再调用OnInit方法去执行派生类的代码。
Loop方法
void Application::Loop() {
OnLoop();
}
直接调用OnLoop方法去执行派生类的代码。
这里OnInit方法和OnLoop方法就是专门用于留给子类实现的,它们也称之为虚函数。
另外Application::GetInstance()和Board::GetInstance()使用的是静态初始方式分别调用creation_application和create_board方法来初始化的,如下代码:
文件 src/framework/app/application.h
static Application& GetInstance() {
static Application* instance = static_cast<application*>(create_application());
return *instance;
}
此方法保证全局只有一个Application子类实例和一个Board子类实例。
至此,我们已经解读基于框架的点亮LED的代码,与前面的不使用框架的代码相比,可以看到我们改变了代码的组织方式(从面向过程改变为面向对象),对具体的控制代码进行了封装,看起来变得有些复杂了,点亮LED的代码执行路径如下:
Application.Loop() -> MyApplication.OnLoop() -> GpioLed.TurnOn() -> digitalWrite()
如果只是写一个点亮LED的程序或是极小的项目,完全没必要用弄得这么复杂,
但当我们项目要接受若干种传感器数据,控制若干外设,有着复杂的业务处理逻辑时,使用开发框架和面向对象设计的优势才会体现出来。
SD卡是一种用于存储数字数据的存储卡,它是一种非易失性存储卡,可以用于移动设备、数码相机、音乐播放器、智能手机、平板电脑等各种设备。
ESPConnect是一个基于现代浏览器的管理器,在你需要快速验证、调试、管理文件、检查状态的时候,它能帮你省下大量打开和切换重型工具的时间。
本文介绍两种使用TEA5767收音机模块实现FM收音机的方案,感兴趣的朋友可在此基础上实现更丰富的功能。
GPIOViewer 是一个强大的 Arduino 库,专门为 ESP32 芯片设计,可以实时监控 ESP32 芯片上的所有 GPIO 引脚状态。它可以帮助你快速直观地了解每个引脚的当前状态,例如高电平、低电平、输入、输出、中断等等。
在音频处理领域,I2S是一种广泛使用的通信协议,它专门用于芯片之间的音频数据传输。ESP32 作为一款高性能的微控制器,不仅支持 I2S 通信,还提供了强大的硬件接口和灵活的软件库,使其成为音频项目开发的理想选择。
小鹏物联网智能浇花系统是照顾植物的好帮手,支持自动控制和手动控制两种模式,可通过电脑端和手机端查看数据和控制浇水。
Arduino开发环境下适用于ESP32芯片系列开发板的应用开发框架。
本小节主要介绍C++ 类相关的基础知识,包括类的定义、继承、多态,范围作用域等。
本讲主要介绍VSCode Arduino开发环境的搭建,及与Arduino IDE开发环境的比较。
本文主要讲解WebServer库如何来处理表单请求。