[Wokwi模拟器] ESP32无实物入门教程(零):开发环境与第一个点灯实验
Wokwi 平台入门:点亮第一个 LED
Wokwi 是一个免费的在线仿真平台,支持 Arduino、ESP32、Raspberry Pi Pico 等开发板。无需安装任何软件,只要有浏览器就能进行完整的电路模拟和代码运行,非常适合教学和入门学习。
1️⃣ 进入 Wokwi 网站
点击进入 https://wokwi.com/ 网站。 你会看到如下界面,我们接下来将以 ESP32 为例进行入门。

2️⃣ 选择 ESP32 仿真模板
往下翻,找到 Starter Templates 部分,点击 ESP32 Project,这是最基础的 ESP32 空项目模板。

3️⃣ 进入仿真编辑界面
点击后就会跳转到仿真编辑页面,左侧是代码编辑区,右侧是电路图仿真区域。

如果你想进行micropython的实验,可以点击Docs旁边,你的账户头像,点击->我的项目->NEW PROJECT->ESP32,在
Beginner templates下面,选择micropython项目,你就可以使用python来编程啦。
4️⃣ 点击 ▶️ 运行试试看!
点击左上角的绿色“播放按钮”,就能启动仿真。

如果代码没有错误,就会看到ESP32下方显示"Hello, ESP32!",表示成功运行啦!
注:这个输出字符串的界面,叫做串口监视器(Serial Monitor)
5️⃣ 添加传感器与连线
接下来,我们开始搭建自己的电路。点击右上角的“+”按钮,添加常用器件,比如 LED、按钮、I²C屏幕、旋转编码器等。

6️⃣ 放置 LED 模块
点击 LED,一个 LED 会出现在画布上。注意它有两个引脚,一个是正极(长腿,通常接GPIO),一个是负极(短腿,接GND)。

7️⃣ 查看引脚提示 & 连接
将鼠标悬停在 ESP32 的引脚上,会显示 GPIO 编号。 点击引脚,再点击 LED 的引脚,即可连线。

任意连线

8️⃣ 编写代码点亮 LED
我们将 LED 正极接到了 GPIO26,负极接到了 GPIO14。 在左侧代码区写下如下代码,让 LED 闪烁(试着自己手打一遍吧):

9️⃣ 运行并观察 LED 闪烁
点击 ▶️ 开始运行程序。等待一小段时间(免费用户可能排队,甚至编译失败,多运行几次就好了),程序编译完成后,你将看到 LED 开始一闪一闪啦!

恭喜你!现在你已经成功使用 Wokwi 平台完成了第一个 ESP32 仿真项目——让一个 LED 闪烁。这是学习嵌入式开发的第一步,后续我们还会继续探索串口通讯、I²C协议、编码器等更有趣的内容。
注意:由于教程调整更新,以下内容可以略过,接下来课程决定精讲这些知识
🔟 常用 ESP32 Arduino 函数补充示例
由于接下来教程一些函数可能不会用到,所以这里我们将直接实践几个常用函数,帮助你熟悉 ESP32 Arduino 编程。
✅ 实践一:数字输入(digitalRead)—— 使用按钮
步骤:
-
点击右侧
+按钮,添加Pushbutton(按钮)。 -
将按钮一端连接到 ESP32 的
GPIO15,另一端连接到 GND。连线方法查询
代码:
const int buttonPin = 15; // 按钮连接的GPIO引脚号
void setup() {
Serial.begin(115200); // 初始化串口通讯,波特率115200
pinMode(buttonPin, INPUT_PULLUP); // 设置按钮引脚为上拉输入模式
}
void loop() {
int buttonState = digitalRead(buttonPin); // 读取按钮状态(按下为LOW,未按下为HIGH)
if (buttonState == LOW) { // 按钮按下为低电平
Serial.println("Button Pressed!"); // 输出按钮按下提示
}
delay(200); // 延时200毫秒避免过快响应
}
✅ 实践二:模拟输入(analogRead)—— 使用电位器
步骤:
-
添加
Potentiometer(电位器)模块。 -
电位器三脚分别连接到 ESP32 的
3.3V、GND和模拟输入脚如GPIO34。
注:对于
3.3V、GND之类的某某引脚在哪里的问题,更推荐去网上搜索相应板子的功能引脚图查看,更加详细。关于板子型号,在diagram.json可查询,如这块ESP32型号是board-esp32-devkit-c-v4。还有最初的点灯程序,GPIO14模拟GND仅仅是在线平台演示,真实硬件最好用实际GND引脚。
代码:
const int potPin = 34; // 电位器连接的模拟输入引脚
void setup() {
Serial.begin(115200); // 初始化串口通讯
}
void loop() {
int potValue = analogRead(potPin); // 读取模拟引脚电压值(0~4095)
Serial.print("Potentiometer Value: "); // 输出提示信息
Serial.println(potValue); // 输出电位器读取值
delay(500); // 延时500毫秒
}
✅ 实践三:串口通讯(Serial)
在前两个例子中我们已经使用了串口通讯,这里重申串口通讯基础用法(这个方法在调试的时候很常用):
- 使用
Serial.begin(115200)初始化串口通信,115200为波特率。 - 使用
Serial.print()向串口输出数据但不换行。 - 使用
Serial.println()向串口输出数据并换行。
✅ 实践四:外部中断(attachInterrupt)—— 按钮触发中断
步骤:
重复实践一中按钮连接方式。
请分别运行下面两段代码,观察区别并理解中断的含义:
代码一(无中断版本):
const int buttonPin = 15;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // 按钮引脚为上拉输入
Serial.begin(115200); // 初始化串口
}
void loop() {
if (digitalRead(buttonPin) == LOW) { // 如果按钮按下
Serial.println("Button Pressed! Waiting 5 seconds...");
delay(5000); // 延时5秒(此期间按下按钮无反应)
}
}
代码二(中断版本):
volatile bool flag = false; // 中断标志位
// 中断服务函数,按钮按下即刻触发
void IRAM_ATTR handleInterrupt() {
flag = true;
}
void setup() {
pinMode(15, INPUT_PULLUP); // 按钮引脚为上拉输入
attachInterrupt(15, handleInterrupt, FALLING); // 设置下降沿触发中断
Serial.begin(115200); // 初始化串口
}
void loop() {
if (flag) { // 如果中断触发
Serial.println("Interrupt Triggered Immediately!");
flag = false; // 重置标志位
delay(5000); // 延时5秒(但按下按钮中断仍可即刻响应)
}
}
📌 中断总结与说明
通过比较以上两个代码,可以清晰看到中断的作用:
-
代码一(无中断): 按钮在
delay()延时时段无法响应。 -
代码二(有中断): 不管主程序是否延时,只要按钮触发中断,立即执行对应中断函数。
注1: 实际体验下来,代码二可能还是会有一定的延迟,因为这是在线模拟网站,算力并不等于真实ESP32算力,速度会受在线人数影响。可以尝试把两个代码的delay时间拉长来突出对比效果,也建议你后续搭建真实电路验证。
注2: 中断服务函数(ISR)要尽可能简单快速,不应包含delay()或Serial.println()等耗时操作,否则会导致ESP32崩溃。
结论:中断是一种响应紧急或实时任务的有效方式,能够确保程序迅速处理高优先级事件而不会被延时阻碍(但需要注意:频繁触发的中断也会占用较多 CPU 资源,可能会影响整体系统性能)。
✅ 实践五:模拟输出(PWM)—— LED 呼吸灯
注意:以下两个函数在新版本中已经被合并成
ledcAttach(),wokwi使用下面代码会报错
使用 PWM(脉冲宽度调制)信号,可以模拟不同亮度的效果,比如实现常见的 LED 呼吸灯效果。
步骤:
- 添加一个
LED,正极连接到 ESP32 的 GPIO18,负极连接到 GND。
代码:
const int ledPin = 18; // LED连接的GPIO引脚号
const int pwmChannel = 0; // PWM通道0
const int pwmFreq = 5000; // PWM频率5000Hz
const int pwmResolution = 8; // PWM分辨率8位,范围(0~255)
void setup() {
// 初始化PWM通道并绑定GPIO引脚
ledcSetup(pwmChannel, pwmFreq, pwmResolution);
ledcAttachPin(ledPin, pwmChannel);
}
void loop() {
// LED亮度逐渐增加(呼吸效果)
for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
ledcWrite(pwmChannel, dutyCycle); // 设置PWM占空比(亮度逐渐增大)
delay(10); // 延时10ms
}
// LED亮度逐渐减少
for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
ledcWrite(pwmChannel, dutyCycle); // 设置PWM占空比(亮度逐渐减小)
delay(10); // 延时10ms
}
}
✅ 最终总结:本节涉及的重要函数详细解释
| 函数名 | 功能简介 | 参数详细说明 |
|---|---|---|
pinMode(pin, mode) | 设置某引脚为输入(INPUT)、输出(OUTPUT)或上拉输入(INPUT_PULLUP) | pin:引脚号;mode:引脚模式(INPUT、OUTPUT、INPUT_PULLUP) |
digitalWrite(pin, val) | 将引脚输出设为高(HIGH)或低(LOW)电平 | pin:引脚号;val:电平值(HIGH或LOW) |
digitalRead(pin) | 读取引脚电平(HIGH/LOW) | pin:引脚号;返回HIGH或LOW |
delay(ms) | 延时函数,单位毫秒 | ms:延时时间(毫秒) |
Serial.begin(baud) | 初始化串口通讯 | baud:串口波特率,常用115200 |
Serial.print()/println() | 向串口输出数据,print不换行,println自动换行 | 输出的字符串或变量 |
analogRead(pin) | 读取模拟电压(返回0~4095) | pin:模拟输入引脚号;返回值范围0~4095 |
ledcSetup(channel, freq, resolution) | 配置PWM通道的频率与精度 | channel:PWM通道号;freq:PWM频率(Hz);resolution:PWM分辨率(位数) |
ledcAttachPin(pin, channel) | 将某个GPIO引脚绑定到PWM通道 | pin:GPIO引脚号;channel:PWM通道号 |
ledcWrite(channel, duty) | 输出PWM信号,占空比为duty(0~255) | channel:PWM通道号;duty:PWM占空比(0~255) |
attachInterrupt(pin, ISR, mode) | 设置中断服务函数(ISR)和触发方式(如FALLING) | pin:引脚号;ISR:中断服务函数名;mode:中断触发模式(RISING、FALLING、CHANGE) |
📌 现在立即打开你的 Wokwi,添加以上传感器并运行这些代码,亲手体验一下吧!
掌握这些基础函数后,你就能写出绝大多数简单或中等复杂度的 ESP32 控制程序啦!后续我们会继续实践更复杂的传感器通信、数据处理和系统联动。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)