简介:面向ESP32入门者与物联网项目开发者,压缩包整合了核心板及扩展板硬件原理图、ESP32中文手册和MicroPython实验例程,涵盖电路设计、传感器接入与WiFi/蓝牙通信等场景,可帮助读者从硬件到代码形成完整认知。包体共104个文件、约39.54MB,以73个py例程为主体,另有25张实验接线图、5份PDF原理图/中文资料和1张说明图;PDF包括核心板与底板原理图、两版数据手册及硬件设计指南,接线图标注了传感器与开发板的引脚关系,适合对照硬件边看边学。例程包括激光、火焰、烟雾、震动、干簧管、雨滴、光敏、声音、倾斜、触摸开关、旋转编码器、红外避障、LCD1602、BMP280、MPU6050、RFID射频卡、人体热释电等传感器实验,以及LED、蜂鸣器、继电器、电机、按键、中断、PWM、串口、ADC、RGB彩灯、数码管、RTC、DS18B20、DHT11、超声波、红外遥控、舵机、OLED、SD卡、WiFi、Socket、MQTT、蓝牙等外设与通信实验。目前已有90人学习,对课程设计、电子竞赛或物联网项目快速验证方案很有参考价值。
1. 拿到ESP32核心板原理图PDF,第一件事不是收藏而是读供电
很多工程师把原理图PDF当成一种“有了但永远不打开”的资料,直到某天点不亮、烧不进固件、引脚复用时才发现自己从来没认真看过芯片周围那十几个电阻电容。ESP32核心板及扩展开发板的硬件PDF原理图真正解决的是三个问题:确认每个引脚在板级被占用或被拉高拉低、确认供电拓扑能否支撑外设电流、确认下载与复位电路如何配合才能稳定进入烧录模式。这套资料配合中文技术手册和55个MicroPython例程,基本覆盖了从画板到写逻辑的完整闭环。适合刚接触ESP32的开发者和需要在产品原型上快速验证硬件假设的嵌入式工程师,甚至对有五年经验的人来说,重新对着原理图梳理一遍ESP32的启动时序和引脚约束,也能解释很多“明明代码没问题却跑不起来”的老问题。
2. 从ESP32核心板原理图到最小系统:不是每个电容都是摆设
2.1 最小系统里必须读懂的三个模块:供电、时钟、启动
ESP32核心板原理图第一眼看上去元件不多,但每一个都有明确作用。以常见的ESP32-WROOM-32模组为核心时,外部电路围绕三个模块展开:3.3V电源树、40MHz晶振电路、以及EN/BOOT控制逻辑。
电源部分是排查不稳定问题的第一现场。原理图上通常会用稳压芯片如AMS1117-3.3或ME6211把USB的5V降到3.3V,输出端必然有10uF和100nF的去耦电容对。这里有一个值得关注的细节:ESP32的Wi-Fi射频发射瞬间电流可以达到500mA甚至更高,如果电容容量不足或走线过长,电压跌落会直接导致模组重启或Wi-Fi连接掉线。
USB 5V -> 稳压器(如AMS1117-3.3) -> 3.3V节点 ├─ 10uF 钽电容或电解电容 -> GND ├─ 100nF 陶瓷电容 -> GND └─ 模组3V3引脚逻辑说明:稳压器负责电压转换,10uF电容应对低频纹波和大电流瞬态,100nF陶瓷电容滤除高频噪声。ESP32内部还有DCDC电路,模组手册会给出对输入电源的内阻要求,实操中应该用示波器在Wi-Fi持续发包时观察3.3V波形。
时钟部分虽然元件少但直接影响射频性能。原理图上如果使用PCB天线模组,晶振通常封装在屏蔽罩内部,外部看不到。如果你的核心板用的是ESP32-WROVER模组,原理图会多一片PSRAM(通常是8MB),这不影响MicroPython代码编写,但会决定你能否跑较大的模型或缓冲区操作。
启动配置是原理图信息量最集中的区域。ESP32有三种启动模式:SPI Boot、Download Boot、SDIO Boot。核心板原理图上体现在GPIO0和EN引脚的上拉下拉电阻。GPIO0被拉高则正常从Flash启动,GPIO0被拉低则进入下载模式。
2.2 从原理图反推GPIO占用:哪些引脚是“看起来可用,实际上被征用”的
一张好的ESP32核心板原理图,排针部分会标注每个引脚的复用功能。但坑在于:很多引脚在板级就已经被占用。典型的有GPIO1和GPIO3接到UART0作为下载串口,GPIO2连接板载LED,GPIO6到GPIO11连接模组内置Flash。
| 引脚 | 板载占用 | 注意事项 |
|---|---|---|
| GPIO1 (TX0) | 串口下载/日志输出 | 避免用作普通IO,会影响烧录 |
| GPIO3 (RX0) | 串口下载/日志输出 | 同上 |
| GPIO2 | 板载LED | 外部使用时需考虑跳线 |
| GPIO12 | MTDI/内部上拉 | 影响启动电压,悬空或下拉需谨慎 |
| GPIO15 | 调试/内部上拉 | 部分板子连接RTC电源 |
| GPIO6-11 | Flash连接 | 绝对不可复用 |
逻辑说明:下载串口被占用是核心板最常见的资源冲突。多数开发板的USB转串口芯片(如CP2102或CH340)在原理图上直接接到UART0,这时GPIO1和GPIO3被占用。如果你用MicroPython初始化这两个引脚做其他用途,轻则日志缺失,重则下次连接时无法识别设备。
2.2.1 判断“这个引脚能不能直接用”的清单
拿到任何一张ESP32核心板原理图后,我会按以下顺序快速检查。第一看原理图上的排针网络标签,搜索GPIO字符串,看哪些网络名是直接连到模组引脚的。第二看每个网络是纯连接还是带有上拉或下拉电阻,例如GPIO0有没有10k上拉到3.3V,GPIO12有没有下拉电阻,这决定了外部电路是否需要额外处理。第三看是否有引脚被硬性连接到外设芯片,例如SD卡槽会占用SPI引脚,MPU6050可能占用I2C引脚。做完这三步,再写MicroPython代码就不会踩复用坑。
3. 吃透ESP32中文技术资料后配置MicroPython:固件下载、烧录与引脚映射验证
3.1 先确认固件与硬件匹配:不是所有MicroPython固件都能直接刷
ESP32的中文技术资料里最容易被跳过的是Flash大小和PSRAM类型章节。MicroPython固件分两种:标准版和SPIRAM版。如果你的核心板模组是ESP32-WROVER系列,原理图上能找到一个标为PSRAM的芯片,这时应该下载带SPIRAM的固件,否则多出来的PSRAM不会被启用。
# 安装esptool pip install esptool # 擦除Flash(首次烧录前强烈建议执行) esptool.py --port /dev/ttyUSB0 --baud 460800 erase_flash # 烧录MicroPython固件 esptool.py --port /dev/ttyUSB0 --baud 460800 --before default_reset \ --after hard_reset --chip esp32 write_flash --flash_mode dio \ --flash_size detect 0x1000 ESP32_GENERIC_SPIRAM-20240602-v1.23.0.bin逻辑说明:erase_flash清空旧数据避免残留分区表冲突;--chip esp32指定芯片型号,ESP32-S3对应需改为esp32s3;--flash_mode dio是多数模组的默认模式,如果你的原理图上Flash采用QIO模式可以改成qio,但DIO兼容性最好;0x1000是引导加载程序的固定偏移地址,MicroPython官方文档和压缩包内附的烧录说明里都有这个值。使用--flash_size detect让工具自动读取Flash容量,省去手动指定出错的麻烦。
3.2 从原理图推导MicroPython引脚编号:字母编号和数字编号的换算
ESP32的中文技术资料里有一张引脚总表,但MicroPython中引脚命名方式和原理图上的排针丝印不同。原理图上印的多为GPIO + 数字,MicroPython则使用Pin(数字)或Pin("GPIO数字")。这里的关键是:ESP32的GPIO编号和芯片物理引脚号是两套系统,MicroPython里用的是GPIO数字。
from machine import Pin, ADC # 原理图上标注GPIO34对应的触摸/ADC引脚 # 在MicroPython中直接使用数字编号 adc_pin = ADC(Pin(34)) adc_pin.atten(ADC.ATTN_11DB) # 量程约0~3.6V voltage = adc_pin.read() * 3.6 / 4095 print("电压值:", voltage)逻辑说明:Pin(34)对应原理图网络标签GPIO34,atten(ADC.ATTN_11DB)设置输入衰减使量程扩展到3.6V。注意GPIO34到GPIO39在ESP32上属于只输入引脚,原理图上如果标注这些引脚连接了ADC设备,MicroPython中不应配置为输出模式。同样地,DAC功能仅在GPIO25和GPIO26上可用。
3.3 验证引脚映射是否正确的两个最小实验
烧录完MicroPython之后,不要急于跑大程序。先做两个硬件实验,花五分钟确认原理图理解无误。
第一个实验是LED点亮:
from machine import Pin from time import sleep led = Pin(2, Pin.OUT) # 假设原理图上LED接在GPIO2 while True: led.value(1) sleep(0.5) led.value(0) sleep(0.5)逻辑说明:遍历核心板原理图上标注为LED的引脚编号,逐一替换Pin(2)。如果LED不亮,不要怀疑引脚编号,先测一下这个引脚在原理图上是否经过三极管或MOS管驱动。很多扩展板上LED通过三极管受控,此时需要同时置位控制引脚为高电平,LED才会导通。
第二个实验是读取板载按键:
from machine import Pin btn = Pin(0, Pin.IN, Pin.PULL_UP) while True: if btn.value() == 0: print("按键按下") else: print("按键释放")逻辑说明:Pin.PULL_UP启用内部上拉电阻,按键一端接GPIO0另一端接GND时,按下为低电平。GPIO0就是下载模式引脚,在运行时作为普通输入完全没问题。
4. 55个MicroPython实验例程源码怎么读:先分类再动手,别一个文件一个文件刷
4.1 例程源码的功能分类
拿到压缩包里55个MicroPython例程后,如果按文件名逐个打开会非常低效。我先按外设类型和功能把它们分为传感器读取类、网络通信类、执行器控制类、屏幕显示类、系统功能类五组。
| 类别 | 典型例程 | 涉及模块 |
|---|---|---|
| 传感器读取 | DHT11/DHT22温湿度、DS18B20、BMP280 | dht、onewire |
| 网络通信 | MQTT发布订阅、HTTP请求、NTP时间同步 | network、umqtt、urequests |
| 执行器控制 | PWM调速、舵机控制、步进电机 | machine.PWM |
| 屏幕显示 | OLED显示、LCD1602 | ssd1306、machine.I2C |
| 系统功能 | 定时器、中断、RTC、深度睡眠 | machine.Timer |
| OTA升级 | 在线更新固件 | hashlib、network |
这些例程的代码风格通常是面向过程式的,每个文件里有一个main()或独立运行的顶层代码段,引脚定义集中在文件最上方。如果你在ESP32中文技术资料里查到某个外设的接线方式与例程不一致,优先改例程头部的引脚常量。
4.2 挑三个例程拆开看看:思路比能跑更重要
4.2.1 DHT11例程:时序敏感型外设的典型模式
from machine import Pin import dht sensor = dht.DHT11(Pin(4)) # 原理图上DHT11数据线接GPIO4 sensor.measure() print(sensor.temperature(), "°C") print(sensor.humidity(), "%")逻辑说明:这个例程只有三行有效代码,但measure()内部实现了一整套时序协议,包含拉低信号线、等待从机响应、读取40位数据、校验和数据八大步骤。调用间隔必须大于1秒,连续读取DHT11会出现校验失败。从源码角度讲,这个例程展示的是:MicroPython已经把时序敏感的协议封装成库,用户不需要关心总线级别的delay,但必须遵守器件本身的最小测量周期。
4.2.2 MQTT发布例程:网络连接状态机的正确写法
import network import time from umqtt.simple import MQTTClient def connect_wifi(ssid, pwd): wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.connect(ssid, pwd) for _ in range(20): if wlan.isconnected(): break time.sleep(0.5) return wlan.isconnected() def mqtt_publish(topic, message): client = MQTTClient("esp32_client", "192.168.1.100", 1883) client.connect() client.publish(topic, message) client.disconnect() connect_wifi("your-ssid", "your-password") mqtt_publish("esp32/data", "hello from micropython")逻辑说明:网络例程的核心在于Wi-Fi连接超时重试机制。wlan.connect()是非阻塞调用,例程里通过循环轮询isconnected()实现最多10秒等待。MQTT部分需要确认broker地址和端口,如果需要认证则MQTTClient构造参数里还需传入user和password字段。
4.2.3 PWM舵机例程:占空比换算不是自由发挥
from machine import Pin, PWM servo = PWM(Pin(13), freq=50) # 50Hz对应20ms周期 # 换算0度:0.5ms高电平占空比 duty_0deg = int(0.5 / 20 * 1024) # 换算180度:2.5ms高电平占空比 duty_180deg = int(2.5 / 20 * 1024) servo.duty(duty_0deg) time.sleep(0.5) servo.duty(duty_180deg)逻辑说明:MicroPython的PWM.duty()在ESP32上是10位分辨率,取值范围0到1023,对应0%到100%占空比。舵机控制信号要求50Hz周期内高电平1.5ms为中间位置,直接算:占空比值 = 高电平时间(ms) / 20ms周期 * 1024。舵机例程源码里如果有类似的注释,说明作者理解了换算逻辑;如果只是硬编码一个值,换舵机型号后还得重新调。
4.3 例程跑不通时看什么:源码排错的三板斧
第一板斧是看串口输出。所有MicroPython例程的排错信息都通过print()输出到UART0,对应核心板原理图上标有TX/RX的引脚。第二板斧是逐行缩小范围:传感器例程先注释掉读取部分确认总线线序,网络例程先ping路由器确认连接。第三板斧是回到原理图确认上拉电阻。
5. 从原理图挖掘进阶信息:引脚复用避坑与OTA升级路径
到这里,原理图的价值从“看懂板子”延伸到“设计产品”。ESP32中文技术资料里最容易被忽略的是引脚复用矩阵表格,它列出了每个GPIO可切换至哪些外设信号。以GPIO12为例,它同时对应MTDI信号和ADC2_CH5,如果板级原理图上没有额外处理,启动阶段这个引脚的电位会影响Flash电压选择。所以当你用GPIO12驱动继电器或者LED时,要确认原理图上的外部电路不会在启动阶段产生不可控电平翻转。
OTA升级是55个例程里价值最高的一个方向,因为它要求你在硬件上没有预留烧录口的情况下也能更新固件。ESP32支持通过MicroPython实现应用级OTA,原理是下载新版固件到独立的OTA分区,然后将启动标志切换到新分区。
import requests import hashlib import os # 从HTTP服务器下载新固件 fw_url = "http://192.168.1.100/firmware/ESP32_GENERIC-ota.bin" fw_data = requests.get(fw_url).content # 计算MD5校验,防止烧入损坏固件 md5 = hashlib.md5(fw_data).hexdigest() print("固件校验值:", md5) # 写入OTA分区(示意,实际需结合具体OTA例程) with open("/next.bin", "wb") as f: f.write(fw_data)OTA操作前,需要确认两件事。第一是MicroPython固件本身支持OTA,编译时被拆分为factory和OTA两个app分区;第二是ESP32的Flash布局里预留了足够的空间存放下载的固件。具体到操作上:先检查分区表,再引入esp32模块的OTA类,设置下载分区、写入、校验、切换启动分区。
import esp32 # 创建OTA对象并指向OTA数据分区 ota = esp32.OTA("ota_0") with open("/next.bin", "rb") as f: ota.write(f.read()) ota.switch() # 标记新分区为启动分区 machine.reset()逻辑说明:esp32.OTA在MicroPython 1.23版本之后支持分区级写入。写入完成后必须调用switch()切换启动分区,然后复位。如果新固件无法启动,ESP32会因看门狗超时回滚到旧分区,前提是硬件上bootloader支持这种回退机制。这个功能对部署在设备内部、没有物理按键的ESP32产品非常实用。
另一个容易被忽视的进阶点是ADC校准。原理图上的ADC引脚如果外接了电阻分压电路,MicroPython里不能直接把读数乘以固定系数。正确做法是先测分压电路在0V和满量程时的实际电压值,再建立线性映射:
from machine import ADC, Pin adc = ADC(Pin(34)) adc.atten(ADC.ATTN_11DB) raw_min, raw_max = 100, 3800 voltage_min, voltage_max = 0.0, 3.3 def read_scaled(): raw = adc.read() voltage = (raw - raw_min) / (raw_max - raw_min) * (voltage_max - voltage_min) return voltage这个校准方法在原理图上有分压电阻的扩展板上尤其实用,比如电池电压检测电路。直接读原始值会因为分压比例导致电压虚高,而自行标定后能获得接近真实值的测量结果。ESP32技术资料中没有直接给出这个逻辑,但结合原理图的输入网络,推导出线性方程并不困难。
写代码前读原理图,遇到问题读原理图,做产品设计更要先读原理图。ESP32烧录失败时重点查EN引脚和BOOT引脚的时序,外设不工作时查排针网络名与代码引脚号是否对应,MicroPython内存溢出时查模组型号是WROOM还是WROVER。原理图PDF可以当作硬件的文档来查,但最终还是要靠反复对着它调试出经验来。
本文还有配套的精品资源,点击获取