尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Arduino ESP32 核心 2.x 到 3.0 迁移指南:API 破坏性变更与升级实战

Arduino ESP32 核心 2.x 到 3.0 迁移指南:API 破坏性变更与升级实战 Arduino ESP32 核心 2.x 到 3.0 迁移指南API 破坏性变更与升级实战【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32导读本指南以 docs/en/migration_guides/2.x_to_3.0.rst 为骨架系统梳理 Arduino ESP32 核心从 2.x基于 ESP-IDF 4.4升级到 3.0基于 ESP-IDF 5.1过程中所有破坏性变更Breaking Changes涵盖构建系统编译标志、ADC/BLE/Hall Sensor/I2S/LEDC/RMT/SigmaDelta/Timer/UART/Wi-Fi 等模块的 API 增删改。读者学完后将能够对照清单逐项排查存量工程把旧代码改造成 3.0 新 API并规避默认引脚变化、flush()语义变化等隐蔽的兼容性问题。本文涉及的新 API 签名均以当前仓库源码为验证依据当前仓库版本为 3.3.x见 esp_arduino_version.h 中ESP_ARDUINO_VERSION_MAJOR 3。说明3.0.0 版本发布时仓库内所有示例均已更新为新 API。2.x 及更早版本的旧示例无法在 3.0.0 及更新版本上直接编译运行迁移是必经之路。一、升级背景从 ESP-IDF 4.4 到 ESP-IDF 5.1Arduino ESP32 核心 2.x 构建在乐鑫 ESP-IDF 4.4 之上而 3.0 全面切换到ESP-IDF 5.1。由于底层 IDF 驱动 API 大规模重构例如 RMT、LEDC、I2S、SigmaDelta、Timer 驱动均改用了新的 IDF 驱动层接口Arduino 层 API 也相应发生了破坏性变化主要体现为API 删除一批旧函数被直接移除编译期即报未定义错误API 重命名/签名变更函数名、参数类型与顺序变化行为语义变化如flush()、available()、begin()引脚处理逻辑等运行期行为改变默认引脚变更部分 SoC 的 UART 默认引脚调整以避开外设冲突外设通道自动分配LEDC 通道、SigmaDelta 通道不再由用户手动指定而是由 Peripheral Manager外围管理器自动分配。迁移的核心思路是先编译定位所有未声明/未定义错误再对照本指南逐条替换为新 API随后通过运行期行为清单如 UART 引脚、Wi-Fiflush()排查隐蔽问题。二、构建系统变更编译标志的覆盖规则2.1 破坏性变化从 3.0 开始如果项目在platform.txt层面或 IDE 的编译选项向编译过程注入额外编译标志extra flags这些额外标志将覆盖部分必需的默认标志。受影响的关键位置是platform.txt中 C/C 编译命令模板见 platform.txt 与 recipe.c.o.pattern、recipe.cpp.o.pattern。默认的 C/C 编译标志中包含-MMD -ccompiler.c.flags-MMD -c {compiler.sdk.path}/flags/c_flags {compiler.warning_flags} {compiler.optimization_flags} {compiler.common_werror_flags} compiler.cpp.flags-MMD -c {compiler.sdk.path}/flags/cpp_flags {compiler.warning_flags} {compiler.optimization_flags} {compiler.common_werror_flags}-MMD用于生成头文件依赖文件.d-c表示只编译不链接两者是构建系统正确工作的基础。2.2 迁移动作如果你通过compiler.c.extra_flags/compiler.cpp.extra_flags见 platform.txt或 IDE 的编译选项注入了自定义标志必须保证自定义标志中包含-MMD -c例如compiler.cpp.extra_flags-MMD -c -O2 -stdgnu17否则项目可能出现依赖跟踪失效增量编译不更新、链接阶段符号缺失等难以排查的构建问题。三、ADC 模块三个 API 被移除3.1 移除清单3.0 移除了以下三个 APIanalogSetClockDivadcAttachPinanalogSetVRefPin从 esp32-hal-adc.h 的当前接口看ADC 模块保留的常用接口为uint16_t analogRead(uint8_t pin); uint32_t analogReadMilliVolts(uint8_t pin); void analogReadResolution(uint8_t bits); // 默认 12 位0~4096 void analogSetAttenuation(adc_attenuation_t attenuation); void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation); void analogSetWidth(uint8_t bits);3.2 迁移方式旧代码中手动设置 ADC 时钟分频analogSetClockDiv的需求在新版中已由驱动层自动管理直接删除调用即可adcAttachPin的引脚使能/初始化在 3.0 中由analogRead/analogSetPinAttenuation等调用自动完成analogSetVRefPin用于内部参考电压校准的引脚选择已不再需要删除即可。若代码中出现上述三个函数名3.0 编译会直接报错函数未声明删除相关行即可通过编译。四、BLE 模块类型体系向 Arduino 风格靠拢3.0 的 BLE 库在类型层面做了三个方向的改动涉及 libraries/BLE 下的头文件实现4.1 字符串类型std::string→String涉及 BLE 的 API 中返回值和参数类型从 C 标准库的std::string改为 Arduino 风格的String。影响面包括BLEDevice、BLECharacteristic、BLEService、BLEAdvertisedDevice等类的描述、名称、值读写等接口。迁移要点接收返回值时String与std::string之间的隐式转换在多数场景下仍可工作但显式适配更稳妥如果你持有指向std::string的指针或引用去接收返回值需要改为String涉及.c_str()、.length()的调用链一般无需改动String同样提供这些方法。4.2 UUID 类型uint16_t→BLEUUIDUUID 相关 API 的数据类型从uint16_t改为BLEUUID类。BLEUUID可承载 16 位、32 位和 128 位 UUID构造时可传入uint16_t、uint32_t、字符串形式的 UUID 或BLEUUID实例。迁移要点// 旧写法2.x uint16_t serviceUUID 0x180D; // 新写法3.0 BLEUUID serviceUUID((uint16_t)0x180D); // 或直接使用 BLEUUID 对象 BLEUUID serviceUUID BLEUUID((uint16_t)0x180D);由于BLEUUID支持从uint16_t隐式构造多数传参场景可以直接替换类型声明。4.3 扫描结果指针化BLEScanResults→BLEScanResults*BLEScan::start和BLEScan::getResults的返回类型从值类型BLEScanResults改为指针BLEScanResults*。源码验证见 BLEScan.hBLEScanResults *start(uint32_t duration, bool is_continue false); BLEScanResults *getResults();迁移要点// 旧写法2.x BLEScanResults results BLEScan.start(5, false); int count results.getCount(); // 新写法3.0 BLEScanResults *results BLEScan.start(5, false); int count results-getCount(); // 注意getResults() 现在返回指针切勿对同一指针重复 deleteBLEScanResults*指针由 BLE 库内部管理迁移时只需把.改为-不要自行释放内存。五、Hall Sensor已移除无替代Hall 传感器霍尔传感器在 3.0 中不再支持hallReadAPI 被删除。原使用场景利用 ESP32 内部霍尔传感器测量磁场在 3.0 及更新版本中无法实现需删除对hallRead的调用或改用外部传感器方案。六、I2S驱动完全重写3.0 的 I2S 驱动被完全重新设计与重构以使用新的 ESP-IDF I2S 驱动。这意味着旧版i2s_*系列 Arduino API如i2s_install、i2s_start等全部失效且旧 API 没有一一对应的迁移映射属于推倒重写型变更。迁移时应直接学习新版 I2S API详见仓库文档 docs/en/api/i2s.rst其核心变化是以i2s_init/i2s_deinit替代旧的安装/卸载流程通过i2s_set_pin显式配置引脚读写使用i2s_write/i2s_read并提供i2s_write_async等异步接口时钟、采样率等参数在初始化时统一配置。旧工程若使用 I2S建议直接参考仓库 ESP_I2S 示例 与 i2s.rst 按新驱动重写初始化与数据收发部分。七、LEDC引入 Peripheral Manager通道自动分配7.1 设计动机LEDC API 的改动是为了支持Peripheral Manager外设管理器并简化使用LEDC 通道现在根据引脚自动分配用户不再需要关心用第几个通道。这消除了通道分配冲突和通道数量管理的负担。7.2 移除的 APIledcSetup原来负责设置通道频率与分辨率ledcAttachPin原来负责把通道绑定到引脚这两个函数合并为了新的ledcAttach。7.3 新增的 API源码验证见 esp32-hal-ledc.hbool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution); bool ledcOutputInvert(uint8_t pin, bool out_invert); bool ledcFade(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms); bool ledcFadeWithInterrupt(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void)); bool ledcFadeWithInterruptArg(uint8_t pin, uint32_t start_duty, uint32_t target_duty, int max_fade_time_ms, void (*userFunc)(void *), void *arg);各函数作用签名定义见 esp32-hal-ledc.h实现见 esp32-hal-ledc.cledcAttach(pin, freq, resolution)合并了原ledcSetupledcAttachPin一步完成引脚与通道的绑定、频率与分辨率配置。freq为 PWM 频率Hzresolution为占空比位宽如 8 表示 0~25513 表示 0~8191ledcOutputInvert(pin, out_invert)反转指定引脚的 PWM 输出电平极性ledcFade(pin, start_duty, target_duty, max_fade_time_ms)在指定时间内把占空比从start_duty渐变到target_duty阻塞式渐变ledcFadeWithInterrupt(pin, start_duty, target_duty, max_fade_time_ms, userFunc)渐变并在完成后触发中断回调userFuncledcFadeWithInterruptArg(pin, start_duty, target_duty, max_fade_time_ms, userFunc, arg)带参数的渐变中断版本回调可接收自定义参数arg。此外底层还提供了ledcFadeGamma系列支持 Gamma 曲线渐变与ledcAttachChannel显式指定通道见 esp32-hal-ledc.h供高级场景使用。7.4 重命名的 APIledcDetachPin改名为ledcDetach签名见 esp32-hal-ledc.hbool ledcDetach(uint8_t pin);所有函数的输入参数channel改为pin即现在一切以引脚为中心不再传通道号。7.5 迁移示例// 旧写法2.x ledcSetup(0, 5000, 8); // 通道0, 5kHz, 8位 ledcAttachPin(25, 0); // 通道0 - GPIO25 ledcWrite(0, 128); // 新写法3.0 ledcAttach(25, 5000, 8); // 引脚25, 5kHz, 8位通道自动分配 ledcWrite(25, 128); // 注意参数从通道号改为引脚 ledcDetach(25); // 原 ledcDetachPin注意新 API 中ledcWrite的第一个参数也是pin见 esp32-hal-ledc.h迁移时凡是传通道号的地方都要改为传引脚号。详细参考 docs/en/api/ledc.rst 与 ESP32 库示例。八、RMT全面重构方向枚举与频率参数化RMT 驱动同样基于新 ESP-IDF 驱动全面重构旧对象式句柄rmt_obj_t*全部替换为引脚号int pin。完整新 API 说明见 docs/en/api/rmt.rst。8.1 移除的 API_rmtDumpStatusrmtSetTick设置 tick 频率由新rmtInit的frequency_Hz参数取代rmtWriteBlocking合并进rmtWritermtEnd由rmtDeinit取代rmtBeginReceivermtReadData8.2 新增的 API源码验证见 esp32-hal-rmt.crmtSetEOT(pin, EOT_Level)设置发送结束信号End of Transmission的电平见 L187rmtWriteAsync(pin, data, num_rmt_symbols)异步发送不阻塞见 L435rmtTransmitCompleted(pin)查询 TX 是否发送完成基于事件组标志见 L464rmtSetRxMinThreshold(pin, filter_pulse_ticks)设置 RX 最小脉宽滤波阈值单位 tick低于该宽度的脉冲被过滤可用于抗干扰见 L228另外源码还提供rmtWriteRepeated固定次数循环发送见 L445与rmtReceiveCompleted查询 RX 是否完成见 L488等补充接口。8.3 签名变更明细函数2.x 旧签名3.0 新签名rmtInitbool rmtInit(rmt_obj_t* rmt, bool tx_not_rx, uint32_t mem_size)bool rmtInit(int pin, rmt_ch_dir_t channel_direction, rmt_reserve_memsize_t mem_size, uint32_t frequency_Hz)rmtWritebool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t num)bool rmtWrite(int pin, rmt_data_t* data, size_t num_rmt_symbols, uint32_t timeout_ms)rmtRead旧参数bool rmtRead(int pin, rmt_data_t* data, size_t* num_rmt_symbols, uint32_t timeout_ms)rmtReadAsync旧参数bool rmtReadAsync(int pin, rmt_data_t* data, size_t* num_rmt_symbols)rmtLoop旧名改名为rmtWriteLooping(pin, data, num_rmt_symbols)rmtSetRxThresholduint32_t value改名为rmtSetRxMaxThreshold(pin, uint16_t idle_thres_ticks)rmtSetCarrieruint32_t low, uint32_t highrmtSetCarrier(pin, bool carrier_en, bool carrier_level, uint32_t frequency_Hz, float duty_percent)各新签名见 esp32-hal-rmt.c 与 esp32-hal-rmt.h头文件为公开接口声明。8.4 关键行为变化rmtWrite现在为阻塞模式只有数据全部发送完成或超时后才返回新增timeout_ms参数用于超时控制需要非阻塞请使用rmtWriteAsyncrmtInit的bool tx_not_rx改为rmt_ch_dir_t channel_direction枚举RMT_TX_MODE/RMT_RX_MODE同时新增frequency_Hz参数替代被移除的rmtSetTick用于设置通道 tick 频率rmtSetCarrier的载波参数从高低电平时长改为频率占空比frequency_Hz为载波频率duty_percent为 0~1 的浮点占空比源码在 esp32-hal-rmt.c 中会校验大于 1 时强制重置为 0.5 并打印警告。8.5 迁移示例TX 场景// 旧写法2.x rmt_obj_t* rmt rmtInit(4, true, RMT_MEM_64); rmtSetTick(rmt, 100); // 100 Hz tick rmtWrite(rmt, data, len); // 阻塞 // 新写法3.0 bool ok rmtInit(4, RMT_TX_MODE, RMT_MEM_64, 100); // 方向枚举 频率 rmtWrite(4, data, len, 1000); // 阻塞1 秒超时 // 异步发送用rmtWriteAsync(4, data, len); // 循环发送用rmtWriteLooping(4, data, len);九、SigmaDelta同样改为引脚中心 通道自动分配SigmaDelta 模块重构到新 ESP-IDF 驱动通道同样由系统自动分配。9.1 移除的 APIsigmaDeltaSetup原用于设置通道与频率sigmaDeltaRead9.2 新增 / 重命名 API源码验证见 esp32-hal-sigmadelta.csigmaDeltaAttach(pin, freq)设置 SigmaDelta 引脚通道自动获取freq有效范围约 1220~312500 Hz见 L27 注释sigmaDeltaDetach(pin)原名sigmaDeltaDetachPin重命名而来见 L87sigmaDeltaWrite(pin, duty)输入参数由channel改为pinduty为 8 位占空比0~255见 L66 注释。完整 API 见 docs/en/api/sigmadelta.rst。9.3 迁移示例// 旧写法2.x sigmaDeltaSetup(0, 312500); // 通道0, 频率 sigmaDeltaAttachPin(26, 0); // 通道0 - GPIO26 sigmaDeltaWrite(0, 128); // 新写法3.0 sigmaDeltaAttach(26, 312500); // 引脚26, 频率通道自动分配 sigmaDeltaWrite(26, 128); // 参数从通道号改为引脚 sigmaDeltaDetach(26);十、TimerAPI 大幅简化只保留一个参数Timer 模块重构到新 ESP-IDF 驱动API 被大幅精简详见 docs/en/api/timer.rst。10.1 移除的 API共 17 个timerGetConfig、timerSetConfig、timerSetDivider、timerSetCountUp、timerSetAutoReload、timerGetDivider、timerGetCountUp、timerGetAutoReload、timerAlarmEnable、timerAlarmDisable、timerAlarmWrite、timerAlarmEnabled、timerAlarmRead、timerAlarmReadMicros、timerAlarmReadSeconds、timerAttachInterruptFlag。这些细粒度配置-使能类接口全部收敛为更少的组合式接口。10.2 新增 / 变更的 API当前 esp32-hal-timer.h 公开接口如下hw_timer_t *timerBegin(uint32_t frequency); // 仅 1 个参数 void timerEnd(hw_timer_t *timer); void timerStart(hw_timer_t *timer); void timerStop(hw_timer_t *timer); void timerRestart(hw_timer_t *timer); void timerWrite(hw_timer_t *timer, uint64_t val); uint64_t timerRead(hw_timer_t *timer); uint64_t timerReadMicros(hw_timer_t *timer); uint64_t timerReadMillis(hw_timer_t *timer); double timerReadSeconds(hw_timer_t *timer); uint32_t timerGetFrequency(hw_timer_t *timer); // 新增获取实际频率 void timerAttachInterrupt(hw_timer_t *timer, void (*userFunc)(void)); // 仅 2 个参数 void timerAttachInterruptArg(hw_timer_t *timer, void (*userFunc)(void *), void *arg); // 新增 void timerDetachInterrupt(hw_timer_t *timer); void timerAlarm(hw_timer_t *timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count); // 新增关键变更点timerBegin现在只有 1 个参数frequency分频系数由驱动根据所选时钟源自动计算以尽量接近目标频率timerAttachInterrupt现在只有 2 个参数原来第 3 个参数edge边沿触发方式被移除中断触发行为由驱动统一管理timerAlarm(timer, alarm_value, autoreload, reload_count)合并了原timerAlarmWrite与timerAlarmEnable设置闹钟值并自动使能autoreload控制是否自动重载reload_count为重载次数timerGetFrequency读取定时器实际频率因分频自动计算实际频率可能与目标略有偏差timerAttachInterruptArg支持带参数的中断回调。10.3 迁移示例// 旧写法2.x hw_timer_t *t timerBegin(0, 80, true); // 定时器0, 分频80, 向上计数 timerAttachInterrupt(t, onTimer, true); // 边沿触发 timerAlarmWrite(t, 1000000, true); // 1M 计数 timerAlarmEnable(t); // 新写法3.0 hw_timer_t *t timerBegin(1000000); // 目标 1MHz分频自动计算 timerAttachInterrupt(t, onTimer); // 边沿参数已移除 timerAlarm(t, 1000000, true, 0); // 设置闹钟并自动使能自动重载 // 需要带参数的回调timerAttachInterruptArg(t, onTimerArg, myArg);十一、UARTHardwareSerial模式枚举化与引脚管理行为变化11.1 API 类型变更uint8_t模式改为强类型枚举setHwFlowCtrlMode的输入参数uint8_t mode改为SerialHwFlowCtrl modesetMode的输入参数uint8_t mode改为SerialMode mode。源码验证见 HardwareSerial.htypedef uart_mode_t SerialMode; typedef uart_hw_flowcontrol_t SerialHwFlowCtrl;即新枚举类型直接复用 IDF 的uart_mode_t如UART_MODE_UART、UART_MODE_IRDA与uart_hw_flowcontrol_t如UART_HW_FLOWCTRL_CTS_RTS、UART_HW_FLOWCTRL_DIS迁移时把传0/1等魔法数字改为具名枚举即可例如setHwFlowCtrlMode(UART_HW_FLOWCTRL_CTS_RTS, 64)64 为半 FIFO 长度阈值见 HardwareSerial.h 注释。11.2 默认引脚变更为避免与其他外设冲突部分 SoC 的 UART 默认引脚调整如下SoC串口2.x 默认 RX / TX3.0 默认 RX / TXESP32UART1GPIO9 / GPIO10GPIO26 / GPIO27ESP32UART2GPIO16 / GPIO17GPIO4 / GPIO25ESP32-S2UART1旧值GPIO4 / GPIO5若旧工程依赖这些默认引脚升级后串口可能接到错误引脚上建议所有工程显式调用begin(baud, rx, tx)指定引脚避免依赖默认值。11.3 引脚管理行为变化重点3.0 起begin()/setPins()的引脚管理语义更精细逐条说明如下对应 HardwareSerial.h 的setPins声明end()可解绑 UART0 引脚即使之前没有调用过begin()直接调用end()也能把启动时绑定的控制台 RX0/TX0 解绑setPins()调用时机自由可以在begin()之前或之后任意顺序调用setPins()会解绑此前变更过的引脚即再次调用时会先释放旧的绑定关系begin(baud, rx, tx)会解绑此前绑定的引脚首次调用setPins()或begin(baud, rx, tx)时会解绑启动阶段绑定的控制台 RX0/TX0-1表示不改动begin()或setPins()中任何设为-1的引脚都不会被改变或解绑begin(baud)单参数不会改变此前通过begin(baud, rx, tx)或setPins()设置的引脚只使用单方向时只改对应引脚begin(baud, -1, tx)或begin(baud, rx)只修改传入的引脚另一方向保持原样。这些规则的实际效果是串口引脚配置具有记忆性与按需释放特性适合在运行时动态切换串口引脚例如外接传感器共用 UART迁移时请检查工程中所有begin/setPins调用是否与新语义一致。十二、Wi-Fi 网络flush()语义修正与WiFiServer清理12.1flush()不再清空接收缓冲区在 Arduino及其他框架语义中flush()的职责是把发送缓冲区的内容送出而不是清空接收缓冲区。2.x 中WiFiClient/WiFiUDP的flush()会连带清空接收缓冲区3.0 修正了这一点WiFiClient、WiFiClientSecure、WiFiUDP的flush()现在什么都不做发送侧本身无待刷缓存新增clear()方法用于清空接收缓冲区。迁移要点// 旧写法2.x—— 清空接收缓冲 client.flush(); // 新写法3.0—— 清空接收缓冲 client.clear();如果旧代码依赖flush()清空接收缓冲来丢弃脏数据迁移后必须改为clear()否则脏数据会继续留在缓冲区。12.2WiFiServeravailable()弃用未实现方法移除WiFiServer::available()已弃用其功能与accept()完全重复。在 Arduino 语义中available()应承担不同职责因此被标记为 deprecated。迁移后统一使用accept()接受新连接移除了WiFiServer从Print继承但从未实现的 write 系列方法以及未实现的stopAll()。这些方法之所以被移除是因为WiFiServer并不管理已连接的WiFiClient对象无法实现向所有客户端广播打印的功能。迁移要点如果代码中调用了server.available()改用server.accept()如果依赖向所有客户端广播写入server.write(...)/server.print(...)需要自行维护客户端列表并逐个调用client.write/client.print。十三、迁移检查清单Checklist迁移完成后建议按以下清单逐项自检构建层面自定义 extra flags 中包含-MMD -c全部旧示例/库已更新到 3.0 API2.x 示例无法直接编译。API 替换删除analogSetClockDiv/adcAttachPin/analogSetVRefPinBLEstd::string→String、uint16_t→BLEUUID、BLEScanResults→BLEScanResults*.→-删除hallReadI2S按新驱动重写参考 docs/en/api/i2s.rstLEDCledcSetupledcAttachPin→ledcAttach所有channel参数改pinledcDetachPin→ledcDetachRMTrmt_obj_t*→int pinrmtInit使用rmt_ch_dir_tfrequency_HzrmtWrite增加timeout_ms阻塞/异步用rmtWrite/rmtWriteAsync区分rmtLoop→rmtWriteLoopingrmtSetCarrier改用频率占空比SigmaDeltasigmaDeltaSetup→sigmaDeltaAttachsigmaDeltaWrite参数改pinsigmaDeltaDetachPin→sigmaDeltaDetachTimertimerBegin单参数、timerAttachInterrupt双参数、timerAlarmWritetimerAlarmEnable→timerAlarm。行为语义UART核对新默认引脚ESP32 UART1 GPIO26/27UART2 GPIO4/25ESP32-S2 UART1 GPIO4/5显式指定引脚更稳妥UART确认begin/setPins的解绑-保留语义符合预期-1表示不改动Wi-Fiflush()清空接收缓冲的代码改为clear()WiFiServeravailable()→accept()广播写入需自行维护客户端列表。结语从 2.x 升级到 3.0 本质上是一次以引脚为中心、以自动分配为默认的 API 范式迁移LEDC/SigmaDelta 通道自动分配、RMT/Timer/I2S 全面对接新 ESP-IDF 驱动、UART 引脚管理更精细、网络行为向标准 Arduino 语义靠拢。建议迁移时先跑一遍编译以定位全部硬性 API 错误再按本清单逐项核对行为语义变化。对于每个模块的完整新 API 用法可继续查阅仓库对应文档ledc.rst、rmt.rst、sigmadelta.rst、timer.rst、i2s.rst、serial.rst。【免费下载链接】arduino-esp32Arduino core for the ESP32 family of SoCs项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表