Skip to content

ESP32智能小车开发文档


目录

  1. 项目概述
  2. 硬件配置
  3. 通信架构
  4. CAN通信协议
  5. ESP32代码说明
  6. 调试与维护

1. 项目概述

1.1 项目简介

本项目实现了一个基于ESP32-S3的4轮智能小车,通过CAN总线与上位机(ROS2)通信,支持蓝牙手柄控制。

1.2 功能特性

功能 说明
电机控制 4个编码器电机,PWM调速
运动模式 差速转向模式
通信方式 CAN总线TWAI(主)、蓝牙手柄(本地)
传感器 MPU6050陀螺仪、QMC5883L磁力计(选配)、编码器
上报数据 电池电压、姿态角、线速度、角速度、电机转速、编码器累计值

1.3 开发指引

开发板资料

本项目使用vscode + PlatformIO 的开发环境

如之前没有接触过,可以自行B站搜索相关,很容易上手

2. 硬件配置

2.1 硬件清单

设备 型号/规格 数量 说明
主控 ESP32-S3-DevKitC-1 1 主控制器,集成电机驱动
电机电机 36-555 4 直流减速电机
编码器 霍尔编码器 4 集成在电机上
陀螺仪 MPU6050 1 内置于开发板
磁力计 QMC5883L 1 没有用到
蓝牙手柄 BLE手柄 1 本地控制
CAN收发器 USB转Can分析仪 1 接电脑端
CAN转TTL模块 Can转TTL 1 接ESP32

2.2 引脚分配

ESP32-S3 引脚资源:
├── GPIO5        : TWAI TX (CAN发送)
├── GPIO6        : TWAI RX (CAN接收)
├── GPIO2        : ADC (电池电压检测)
├── GPIO46       : LED指示
└── 编码器引脚   : 通过配置读取

2.3 CAN总线接线

ESP32-S3              CAN转TTL模块          
─────────────────     ────────────────     
GPIO5 (TX)       →      TX                  
GPIO6 (RX)       →      RX                  
3.3V             →      VCC
GND              →      GND                 

CAN转TTL模块另一头       CAN收发器              电脑
──────────────────     ──────────────      ───────────
CANH              →      CANH       ->         usb
CANL              →      CANL

2.4 CAN收发器及上位机

请查看交付目录的文件夹 《CAN收发器文档》


3. 通信架构

┌─────────────┐     USB-CAN      ┌──────────────┐    CAN总线    ┌─────────────────┐
│   ROS2 PC   │ ←──────────────→ │ USB-CAN收发器 │ ←───────────→ │ CAN转TTL模块   │
└─────────────┘                  └──────────────┘               └───────┬─────────┘
                                                                         │
                                                                         ↓
┌─────────────┐                          ┌────────────────────────────────────┐
│ 蓝牙手柄     │ ←──── BLE ──────────────→ │          ESP32-S3 (TWAI)          │
│ (本地控制)   │                          │  ┌────────────────────────────────┐│
└─────────────┘                          │  │ •  TWAI控制器(硬件处理CAN协议) ││
                                           │  │ •  蓝牙优先级最高               ││
                                           │  └────────────────────────────────┘│
                                           └───────────────────────────────────┘

4. CAN通信协议

4.1 通信参数

参数
波特率 500Kbps
帧格式 标准帧 (11位ID)
数据格式 小端序 (低字节在前)
过滤器 接收所有帧

4.2 CAN ID分配表

ID 方向 功能 数据长度
0x101 上行 姿态数据 8字节
0x102 上行 电机转速 (4电机) 8字节
0x103 上行 编码器累计值 (1-2) 8字节
0x104 上行 编码器累计值 (3-4) 8字节
0x105 上行 同步帧 (丢包检测+延迟估计) 8字节
0x201 下行 PWM模式控制 (+seq) 8字节
0x202 下行 ROS速度模式控制 (+seq) 8字节
0x203 下行 刹车指令 (+seq) 2字节

4.3 上行数据帧格式(ESP32 → 上位机)

0x101 - 姿态数据(8字节)

字节 类型 名称 单位 说明
0-1 uint16 voltage 0.01V 电池电压,如241=24.1V
2-3 int16 angleZ deg 航向角,-180~180
4-5 int16 linearX mm/s X轴线速度
6-7 int16 linearY mm/s Y轴线速度

测试示例:

场景 数据(hex) 说明
静止 F1 00 00 00 00 00 00 00 电压24.1V, 航向0°, 线速度0
向右转90° F1 00 5A 00 00 00 00 00 电压24.1V, 航向90°, 线速度0
前进中 F1 00 00 00 64 00 00 00 电压24.1V, 航向0°, X线速度100mm/s
满电前进 C8 00 00 00 64 00 00 00 电压20.0V, 航向0°, X线速度100mm/s

0x102 - 电机转速(8字节)

字节 类型 名称 单位
0-1 int16 rpm1 RPM
2-3 int16 rpm2 RPM
4-5 int16 rpm3 RPM
6-7 int16 rpm4 RPM

测试示例:

场景 数据(hex) 说明
静止 00 00 00 00 00 00 00 00 全部停止
前进 32 00 1E 00 0A 00 14 00 电机1=50, 电机2=30, 电机3=10, 电机4=20RPM
倒退 CE FF E2 FF F6 FF 0A 00 电机1=-50, 电机2=-30, 电机3=-10, 电机4=10RPM

0x103 - 编码器累计值1-2(8字节)

字节 类型 名称 说明
0-3 int32 encoder1 编码器1累计脉冲数
4-7 int32 encoder2 编码器2累计脉冲数

测试示例: [0x64 0x00 0x00 0x00 0xE8 0x03 0x00 0x00] → 编码器1=100, 编码器2=1000

0x104 - 编码器累计值3-4(8字节)

字节 类型 名称 说明
0-3 int32 encoder3 编码器3累计脉冲数
4-7 int32 encoder4 编码器4累计脉冲数

测试示例: [0x00 0x00 0x00 0x00 0x10 0x27 0x00 0x00] → 编码器3=0, 编码器4=10000

0x105 - 同步帧(8字节,ESP32 → PC,1Hz)

用于上位机实现丢包检测和延迟估计。由ESP32定期发送,携带系统运行时间和帧序号。

字节 类型 名称 说明
0-3 uint32 uptime_ms 系统运行时间(ms),可用于延迟估计
4-5 uint16 frame_seq 全局帧序号,单调递增,跳变即丢包
6 uint8 rx_seq_echo 最近收到的下行帧序号,上位机可据此计算RTT
7 uint8 reserved 保留

测试示例:

场景 数据(hex) 说明
启动1秒后 E8 03 00 00 05 00 00 00 uptime=1000ms, seq=5, rx_echo=0
运行10秒 10 27 00 00 32 00 0A 00 uptime=10000ms, seq=50, rx_echo=10

4.4 下行数据帧格式(上位机 → ESP32)

0x201 - PWM模式控制(8字节)

字节 类型 名称 范围 说明
0-1 int16 x_speed -100~100 X轴功率百分比
2-3 int16 y_speed -100~100 Y轴功率百分比
4-5 int16 z_speed -100~100 Z轴功率百分比
6 uint8 seq 0~255 帧序号,上位机递增,用于丢包检测
7 uint8 reserved - 保留

测试示例(上位机填写:CAN ID = 0x201, 数据8字节hex, 数据长度8):

场景 数据(hex 8字节) X Z 说明
前进50% 32 00 00 00 00 00 00 00 50 0 X轴50%前进
前进100% 64 00 00 00 00 00 00 00 100 0 X轴全速前进
后退50% CE FF 00 00 00 00 00 00 -50 0 X轴-50%后退
顺时针旋转50% 00 00 00 00 32 00 00 00 0 50 Z轴50%右转
逆时针旋转50% 00 00 00 00 CE FF 00 00 00 0 -50 Z轴-50%左转
停车 00 00 00 00 00 00 00 00 0 0 全部归零

注意:橡胶轮不支持横移,Y轴填0

0x202 - ROS速度模式控制(8字节)

字节 类型 名称 单位 说明
0-1 int16 x_speed mm/s X轴线速度
2-3 int16 y_speed mm/s Y轴线速度
4-5 int16 z_speed deg/s Z轴角速度
6 uint8 seq 0~255 帧序号,上位机递增,用于丢包检测
7 uint8 reserved - 保留

测试示例(上位机填写:CAN ID = 0x202, 数据8字节hex, 数据长度8):

场景 数据(hex 8字节) X(mm/s) Z(deg/s) 说明
前进0.2m/s C8 00 00 00 00 00 00 00 200 0 约0.2m/s前进
前进0.8m/s 20 03 00 00 00 00 00 00 800 0 约0.8m/s前进
后退0.2m/s 38 FF 00 00 00 00 00 00 -200 0 约0.2m/s后退
旋转90°/s 00 00 00 00 5A 00 00 00 0 90 90°/s顺时针旋转
停车 00 00 00 00 00 00 00 00 0 0 全部归零

0x203 - 刹车指令(2字节)

字节 类型 名称 范围 说明
0 uint8 brakeForce 0~100 刹车力度,0=滑行停车,1~100=主动刹车+驻车保持
1 uint8 seq 0~255 帧序号,上位机递增,用于丢包检测
  • brakeForce = 0:滑行停车(电机释放,自由减速至停止)
  • brakeForce > 0:主动刹车 → 电机短接制动至停稳 → 自动进入驻车位置保持(编码器闭环反推,抵抗外力推移)

测试示例(上位机填写:CAN ID = 0x203, 数据长度2):

场景 数据(hex) 说明
滑行停车 00 刹车力0,释放电机自由停止
轻柔刹车 30 30%刹车力度制动,停稳后驻车保持
紧急刹车 64 100%全力刹车,停稳后驻车保持

5. ESP32代码说明

5.1 代码结构

cust20/
├── src/
│   ├── main.cpp          # 主程序入口
│   └── main.h            # 全局变量和函数声明
├── lib/
│   ├── CanBus/           # CAN通信模块
│   │   ├── CanBus.h/cpp      # MCP2515方案(参考)
│   │   ├── CanBusTTL.h/cpp   # CAN转TTL方案(参考)
│   │   └── CanBusTWAI.h/cpp  # TWAI方案(当前使用)
│   ├── Config/            # 配置存储
│   ├── ControlStick/      # 蓝牙手柄
│   ├── encoder/           # 编码器驱动
│   ├── motor/            # 电机驱动
│   ├── Pid/              # PID控制
│   ├── protocal/         # 通信协议定义
│   └── Head.h            # 硬件参数配置
└── platformio.ini        # 项目配置

5.2 核心类说明

CanBusTWAI 类

使用ESP32-S3内置TWAI控制器,通过硬件自动处理CAN协议。

class CanBusTWAI
{
public:
    // 初始化TWAI控制器
    bool begin(CanRxCallback callback);

    // 发送原始CAN帧
    bool sendFrame(uint16_t canId, const uint8_t* data, uint8_t len);

    // 发送姿态数据帧
    bool sendPoseData(float voltage, int16_t angleZ, ...);

    // 发送电机转速帧
    bool sendMotorRpm(int16_t rpm1, int16_t rpm2, int16_t rpm3);

    // 发送编码器累计值帧
    bool sendEncoderTicks(int32_t tick1, int32_t tick2, ...);
};

handleCanFrame 回调函数

解析上位机发送的CAN指令:

  • 0x201 PWM模式 → 调用 controlEMotors()
  • 0x202 ROS模式 → 单位转换后调用 controlEMotors()
  • 0x203 刹车指令 → 调用 stop()

5.3 多任务架构

ESP32-S3双核处理器,任务分配如下:

任务 核心 说明
loop() Core 1 主循环
xCore_task Core 0 电机控制、传感器采集
twaiTask Core 0 CAN帧接收(独立任务)

5.4 关键参数(必须自行调整)

/**Head.h*/
// 根据实际情况修改参数配置
const int maxRpm = 110;              // 电机最大转速RPM
const int gear = 90;                 // 减速比
const float wheelCircumference = PI * 80;  // 轮子周长(mm)
const int wheelSpacing = 220;        // 轮间距(mm)
const int wheelBase = 200;           // 轴距(mm)
/**main.h*/
// 可以根据实际情况修改参数配置
const int gapNotice = 100;  // 定时发送状态的间隔,单位毫秒
const int outPutCountLimit = 10; // 电机满负荷运行多少次后降低速度
const float maxDe = 0.3;    // 电机如果超负荷运行,最大降速比例
/**pid.h*/
// 必须根据实际情况修改参数配置,例如下行数据的频率,影响到电机的转速
double kp = 0.25;  // 比例系数
double ki = 0.02;  // 积分系数
double kd = 0.5;  // 微分系数

5.5 数据上报周期

  • 姿态数据:100ms (10Hz)
  • 电机转速:100ms (10Hz)
  • 编码器:100ms (10Hz)

6. 调试与维护

6.1 调试方法

串口监视

波特率115200,可查看:

  • TWAI初始化状态

  • 接收到的指令

  • 电机转速反馈

  • 错误信息

6.2 联系方式

如有问题,请联系技术 15827639032


附录

A. CAN帧测试快速参考表

下行测试(PC上位机 → ESP32,用USB-CAN分析仪发送)

操作 CAN ID 数据(hex 8字节) 数据长度
50%功率前进 0x201 32 00 00 00 00 00 01 00 8
100%功率前进 0x201 64 00 00 00 00 00 02 00 8
50%功率后退 0x201 CE FF 00 00 00 00 03 00 8
50%顺时针旋转 0x201 00 00 00 00 32 00 04 00 8
50%逆时针旋转 0x201 00 00 00 00 CE FF 05 00 8
停车 0x201 00 00 00 00 00 00 06 00 8
前进0.2m/s 0x202 C8 00 00 00 00 00 01 00 8
前进0.8m/s 0x202 20 03 00 00 00 00 02 00 8
后退0.2m/s 0x202 38 FF 00 00 00 00 03 00 8
旋转90°/s 0x202 00 00 00 00 5A 00 04 00 8
停车 0x202 00 00 00 00 00 00 05 00 8
滑行停车 0x203 00 01 00 00 00 00 00 00 2
轻柔刹车+驻车 0x203 1E 02 00 00 00 00 00 00 2
紧急刹车+驻车 0x203 64 03 00 00 00 00 00 00 2

上行测试(ESP32 → PC上位机,用USB-CAN分析仪接收)

数据含义 CAN ID 数据(hex 8字节)
电压24.1V, 静止 0x101 F1 00 00 00 00 00 00 00
电压24.1V, 航向90° 0x101 F1 00 5A 00 00 00 00 00
电压24.1V, X线速度100mm/s 0x101 F1 00 00 00 64 00 00 00
电机1=50, 2=30, 3=10, 4=20RPM 0x102 32 00 1E 00 0A 00 14 00
编码器1=100, 编码器2=1000 0x103 64 00 00 00 E8 03 00 00
编码器3=0, 编码器4=10000 0x104 00 00 00 00 10 27 00 00
同步: uptime=1000ms, seq=5 0x105 E8 03 00 00 05 00 00 00

USB-CAN分析仪上位机操作步骤

  1. 接线如下图:杜邦线接esp2,usb插电脑

Img

  1. 按资料包中的文档安装驱动和上位机

  2. esp32代码上传至开发板

  3. 打开上位机,会自动弹窗connect,如没有则手动连接

Img

  1. 自行设置测试包

Img

B. 修订历史

版本 日期 修改内容
1.0 2026-05-12 初始版本
1.1 2026-05-14 改用TWAI方案,增加CAN收发器接线说明
1.2 2026-05-27 增加各CAN ID完整测试数据表及USB-CAN上位机操作说明
1.3 2026-06-26 新增0x105同步帧;0x201/0x202/0x203增加seq序号;0x102扩展为4电机8字节