ESP32玩具
旧玩具
这是一块两年前的小板子,因为 ESP32 足够便宜而且有方便的 wifi 功能,而且这一款甚至带有 CAN 收发器,所以购入。在 ESP 中 CAN 接口叫做 TWAI ,官方代码库(早期也叫 CAN,现在改掉了)、资料等都找不到 CAN 相关字样,应该是没交版权费,功能上是一模一样的。
两年前使用 Arduino IDE 做了一点点简单的功能-网络桥接啥的,然后因为 Arduino IDE 或者 ESP-IDF 过于简单或者过于复杂而劝退。当然也是没有什么实际需求懒得继续研究。
之前花 200 大洋咨询别人一些问题的时候,别人就力荐我全面使用 PlatformIO ,当然我完全没当回事。现在重新把玩这个玩具,发现 PlatformIO 环境虽然不符合我的开发美学,但确实有其独到之处,足够简单足够应用。虽然各种编译过程各种环境都藏着不让人看,但当我们把所有知识类的开发经验抛开,只专注于实现某种应用,这玩意可太棒了。
下面是我这两周玩出的成果。
[ 懒得录改天再说 ]
整体理解
PlatformIO 是一个集成了编译链、python环境、包管理器(他自有的)、下载算法、调试器等等所有开发所需的东西的一个平台。
因为大而全,所以基于 PlatformIO 的开发项目是相对封闭的,所有的指令或者其他操作都应该在 PlatformIO CLI 中进行,在 vscode 的蚂蚁头 PlatformIO 图标下,可以在 QUICK ACCESS->Misellaneous-> PlatformIO Core CLI 打开 PlatformIO CLI 终端,在其中打指令例如 pio --help
、which python
才是调用集成环境中的东西。
而关于在此平台下载的 Libraries,也不要想着改库,照着包的 Examples 用就好了,否则在平台更新时可能会自动将你的修改给还原导致丢失代码。必须要增改功能的包自行放在项目的 lib 文件夹中,平台会自动监测和添加编译指令。
另外都使用这样的平台了,就别想着 JTAG 单步调试了,我进行了很多尝试在这方面耗费大量的时间,但总是有这样那样的问题,另外芯片的引脚资源也不够用,完全不能支持额外的四个引脚拿来调试。
基础入门
环境配置
PlatformIO 首先需要有 vscode ,然后在 vscode 中左下角齿轮新建一个空的配置文件,建议初建是全空,甚至不要有主题插件。
在插件市场找到 PlatformIO IDE
下载即可。
安装完成后左侧会出现蚂蚁头,这就是整个 PlatformIO IDE
环境了。
点开蚂蚁头,可以在 QUICK ACCESS->PIO Home->Platforms 找到所有支持的板子平台。

其中比较常用的就是 Espressif32、Espressif8266,其他的芯片关键词都可以搜出来,只有这两个 esp32、esp8266 居然搜不到,当然一共也没几个,手动看一圈就好了。点开需要的平台,Install 就好了。
在某个 Platform 第一次下载时,他会提示你下载许多他依赖的小工具,不要担心,这些都会集合下载在他自有的文件夹中,不会影响我们自己的文件结构。如果下载过慢或者失败(顺利的话一分钟以内就完成了),需要挂 VPN。
创建项目
点开蚂蚁头,可以在 QUICK ACCESS->PIO Home->Project & Configuration 看到此平台下的所有项目,新环境是没有的,点击 Create New Project 新建一个。
Name 随便起,Board 搜索开发板或芯片开头几个字母大部分都可以搜到,Framework 推荐直接选 arduino 就好。
没有下载的 Platform 会自动下载。

创建后大概是这样的结构
name
├── .pio
├── .vscode
├── include
├── lib
└── src
└── main.cpp
└── test
└── platformio.ini
我们实际的 main.cpp 文件在 src
文件夹下,暂时不理会。
打开 platformio.ini
并进行一些调整。
[env:pico32]
platform = espressif32
board = pico32
framework = arduino
; 增加以下两句
build_flags = -I src
build_type = release
build_flags
是额外添加的编译标志,这里表示将 src
文件夹也加入 include path,便于我们在 src
文件夹也可以创建头文件。
build_type
是不必介绍了吧,改为发布版可以节省一些资源供我们使用,毕竟 arduino 天生就会浪费很多资源。
后续开发
首先再整理一下项目,找到 src/main.cpp 清理为如下的样子。仅保留基本的 setup 和 loop 函数,arduino 中 setup 函数会先运行一次,随后 loop 函数不断运行。
#include <Arduino.h>
void setup( )
{
}
void loop( )
{
}
在 src 下新建两个文件 McuInit.cpp 、SysTask.cpp,并且整理为如下内容。
McuInit
用于一些应用模块的初始化配置,例如示例的串口模块,在 arduino 中实际上没有外设概念,直接操作 MCU 的外设功能可能会引起冲突;
SysTask
用于一些可能有时序相关的工作,例如每 100ms 扫描一次 wifi 这种,在 loop 函数中无法精确把握时序;
而原有的 loop
函数则用于时序无关以尽可能快的速度运行的工作,例如刷新 UI。
#include <Arduino.h>
extern void McuInit(void);
extern void SysTask(void *parameter);
//
void setup( )
{
McuInit( );
xTaskCreate(SysTask, /*任务函数*/
"SysTask", /*带任务名称的字符串*/
8192, /*堆栈大小,单位为字节*/
NULL, /*作为任务输入传递的参数*/
1, /*任务的优先级*/
NULL); /*任务句柄*/
}
void loop( )
{
}
lib
文件夹塞进所有用到的外部库,平台会自动添加其中的源文件和头文件路径。
点开蚂蚁头,可以在 QUICK ACCESS->PIO Home->Libraries 找到平台推荐的一些库,点开想要使用的库,"Add to Project"可以加入项目,随后直接按照库的 Examples 使用就好,这个平台自带的库管理器添加的库,源码不太好寻,也不用在意。
鸣谢
本项目用到的库。
库本身的库管理器-
- ESP32CAN:CAN 通信收发应用的包装,越过 TWAI 进行了寄存器接管,比原生 TWAI API 方便 Demo 31: How to use Arduino ESP32 CAN interface
- SerialCommands:一个极简串行指令解析栈,方便制造自己的指令控制 ppedro74/Arduino-SerialCommands
- PubSubClient:MQTT 的极简协议栈 knolleary/pubsubclient: A client library for the Arduino Ethernet Shield that provides support for MQTT.
- CircularBuffer:方便轻量的环形 FIFO 管理 rlogiacco/CircularBuffer: Arduino circular buffer library
lib 文件夹引入的库
- u8g2:超轻量图形库,经过改造支持 128X80 分辨率。 olikraus/u8g2: U8glib library for monochrome displays, version 2
- MiaoUI:超轻量 UI 框架,结合 u8g2 方便地实现显示效果。 JFeng-Z/MiaoUI: MiaoUI 是一个基于 u8g2 的单色 OLED 菜单 UI 框架。MiaoUI使用 C 语言实现,采用双向链表结构,使用非线性动画、移植方便、内存占用较小、能够快速部署,适用于具有小型OLED屏幕的嵌入式设备。
- MultiButtonPro:超轻量按键库,单按键多事件回调用于支持相对丰富的操作。 stbanana/MultiButton: Button driver for embedded system. Expand development based on existing projects.
其他
Note
由于路由器、网络环境的限制,这些 MCU 无法直接暴露自己的公网IP(或者很麻烦和无法随处手持),建议往服务器转发方向研究,比如
MQTT
服务器中转。
搭项目框架 3~4 天,研究 JTAG 调试 2~3 天,代码填充 2~3 天,这玩意弄起来还是很快的。
在 PlatformIO CLI 中可以使用这些指令进行一些操作。
检查芯片整体设置,例如 JTAG 功能是否开启。这个指令来自 espressif 工具链。
espefuse -p COM11 summary
烧录固件,例如将 your.bin 烧录到 0x1000 处。这个指令来自 espressif 工具链。
esptool -p COM11 write_flash 0x1000 your_firmware.bin
检查所有已安装的库和包。这个指令来自 PlatformIO 平台。
pio pkg list
至于其他指令,类似 pio --help
、esptool --help
这样加上 --help
都可以层层往下查。