# ESP32S3-FFB **Repository Path**: uitcis/ESP32S3-FFB ## Basic Information - **Project Name**: ESP32S3-FFB - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-13 - **Last Updated**: 2026-10-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ESP32S3-FFB 无刷电机力反馈方向盘项目 基于 ESP32-S3,综合四个开源项目实现的 DirectInput 兼容无刷电机 FFB(力反馈)方向盘固件。 ## 综合的开源项目来源 | 项目 | 来源路径 | 整合的核心功能 | |------|----------|----------------| | **esp-ffb** | `../esp-ffb/` | USB HID FFB 协议栈、效果引擎架构、NVS 参数管理、ForceController 桌面效果、FreeRTOS 多任务划分 | | **realTiX-ffb-wheel** | `../realTiX-ffb-wheel/` | FOC 算法实现参考 (ltx_foc1 SVPWM + PI 控制器)、MT6701 编码器驱动、FFB 效果报告结构 | | **foc-wheel-legged-robot** | `../foc-wheel-legged-robot/stm32-foc/` | SimpleFOC 移植版完整 FOC 流程:电机初始化、编码器对齐校准(zero_electric_angle)、Clarke/Park/SVPWM 接口 | | **Arduino-FFB-wheel-250rev3** | `../Arduino-FFB-wheel-250rev3/` | 完整 FFB 条件效果(弹簧/阻尼/惯性/摩擦)算法、恒力/斜坡/周期波计算、包络攻击衰减 | ## 硬件平台 - **MCU**: ESP32-S3-WROOM-1 / DevKitC-1 (240MHz 双核, 512KB SRAM) - **电机**: 任意三相无刷电机(2804/4010/5010/外转子等,适配极对数 7/11/14/15...) - **驱动** (config.h 中 `MOTOR_TYPE` 三选一,当前默认 3-PWM): - **MS8313**(DRV8313 pin 兼容,内置 MOSFET,1.75A/相):`MOTOR_TYPE_3PWM` — IN1-3 接 GPIO 1/3/5,EN1-3 接 GPIO 2/4/6,nSLEEP 接 GPIO 7,可选 nRESET/nFAULT(`MS8313_NRESET_GPIO` / `MS8313_NFAULT_GPIO`,nFAULT 接入后 FOC 环路自动检测故障关断) - 三相半桥栅极驱动(DRV8301/DRV8323/IR2101 + MOSFET):`MOTOR_TYPE_BLDC` 6-PWM 互补 + 死区 - 有刷 H 桥:`MOTOR_TYPE_DC` - **编码器** (`ENCODER_TYPE` 选择,当前默认 MT6701): - **MT6701** (SSI 三线 CSN/CLK/DO, 14bit):单次 25bit 事务读取 24bit 全帧(14bit 角度 + 4bit 磁场状态 + 6bit CRC),CRC 校验自动锁定帧对齐;磁场异常/失锁告警;错误计数见 `g_encoder.crc_error_count` / `g_encoder.mag_status` - AS5600 (I2C, 12bit) - MT6816 (SPI, 14bit) - **USB**: 板载 USB-OTG 直连 PC (TinyUSB HID) ## 构建方式 使用 **PlatformIO + ESP-IDF 5.x**(推荐)或原生 ESP-IDF。 ### PlatformIO 快速编译 ```bash # 本项目目录 cd ESP32S3-FFB # 安装 PlatformIO Core 或 VS Code 插件后 pio run # 编译 pio run --target upload # 烧录(USB 串口连接 ESP32-S3) pio device monitor # 打开串口监视器(115200) ``` ### 或使用 ESP-IDF 原生 ```bash get_idf # 加载 ESP-IDF 环境 idf.py build # 编译 idf.py flash # 烧录 idf.py monitor # 监视 ``` ## 目录结构 ``` ESP32S3-FFB/ ├── platformio.ini # PlatformIO 配置 ├── CMakeLists.txt # ESP-IDF 顶层 CMake ├── sdkconfig.defaults # 默认 SDK 配置 (TinyUSB HID, 240MHz, 优化) ├── partition.csv # 分区表(含 NVS) ├── include/ │ └── config.h # ★ 总配置:引脚、轴数、按钮数、FOC/编码器参数 ├── src/ │ ├── main.c # 主入口:任务创建 + 调度 │ ├── usb_descriptors.c # TinyUSB 设备/HID/配置描述符 + 回调 │ ├── CMakeLists.txt │ └── idf_component.yml ├── components/ │ ├── foc/ # FOC:三角函数表、Clarke/Park/SVPWM、PID/LPF、BLDCMotor │ ├── motor_driver/ # ESP32-S3 MCPWM 三相 PWM + 死区 + 使能 │ ├── encoder/ # AS5600 (I2C) / MT6701/MT6816 (SPI) 通用驱动 │ ├── usb_ffb/ # USB HID FFB 报告描述符 + 效果引擎(分配/播放/计算) │ ├── force_controller/ # 力后处理:增益、软限位、桌面弹簧/阻尼/摩擦、输出 LPF、slew-rate │ └── param_manager/ # NVS 参数加载/保存 + 上位机串口协议 (0xAA55) └── docs/ ``` ## 工作流程(数据流) ``` [PC DirectInput 游戏] │ USB HID OUT Report (SetEffect / Op / Constant / Condition ...) ▼ ┌──────────────────────────────────────────────────────────────┐ │ TinyUSB → tud_hid_set_report_cb → ffb_handle_output_report │ │ · 效果块池 g_ram_pool (MAX_EFFECTS_NUM=12) │ │ · 播放列表 g_playing_mgr │ │ · 1ms 定时器 ffb_tick_timer_cb → ffb_tick_1ms() 更新时间轴 │ └───────────────────────────────┬──────────────────────────────┘ │ ffb_calculate_output() 1kHz ▼ 归一化 [-32767, 32767] ┌──────────────────────────────────────────────────────────────┐ │ force_controller_process() 每个轴 │ │ · FFB Gain × 归一化 → N·m │ │ · 软限位 Soft-Limit (超限增益二次曲线) │ │ · 桌面弹簧回中 / 阻尼 / 摩擦 Coulomb │ │ · 轴反向 ±1 / 扭矩 slew-rate 限制 / 一阶 LPF │ └───────────────┬──────────────────────────────────────────────┘ ▼ 目标扭矩 N·m motor_set_torque() ▼ ┌──────────────────────────────────────────────────────────────┐ │ FOC Loop 10kHz (Core 1, 最高优先级) │ │ 1. encoder_update() → counts→角度/速度 (AS5600/MT6701) │ │ 2. shaft_angle × pole_pairs - zero_electric_angle │ │ 3. 扭矩→电压简化映射: Uq = T × kV │ │ 4. 逆 Park + SVPWM → 三相占空比 [0,1] │ │ 5. MCPWM (带死区互补) 输出到半桥栅极 │ └──────────────────────────────────────────────────────────────┘ ▲ │ 同步读取 编码器/电机 同时 100Hz → Joystick 输入报告(角度映射到 X 轴 ±32767 + 按钮) ``` ## Windows 驱动 ESP32S3-FFB 作为标准 USB HID PID 设备,Windows 自带 HID 驱动可识别。 要让 DirectInput 游戏识别为力反馈设备,需要导入注册表或安装 INF(参考 esp-ffb `reg/` 目录中的方法)。 ## 引脚参考 (config.h 可改) | 功能 | GPIO | |------|------| | I2C SCL (AS5600) | 9 | | I2C SDA (AS5600) | 8 | | SPI MOSI / MISO / CLK / CS (MT6701 SSI: DO/CLK/CSN) | 11 / 13 / 12 / 10 | | MCPWM UH/UL (3PWM: IN1/EN1) | 1 / 2 | | MCPWM VH/VL (3PWM: IN2/EN2) | 3 / 4 | | MCPWM WH/WL (3PWM: IN3/EN3) | 5 / 6 | | Motor EN (MS8313: nSLEEP) | 7 | | MS8313 nRESET(可选,默认未接 -1) / nFAULT(默认 47) | config.h 配置 | | Shift paddle Left / Right | 14 / 15 | | Button matrix ROW0/ROW1 | 16 / 17 | | Button matrix COL0/COL1 | 18 / 21 | | WS2812 RGB | 48 | | USB D+/D- | 19 / 20 (ESP32-S3 板载 USB-OTG) | | UART0 TX/RX (日志+协议) | 43 / 44 (默认) | > 引脚可用性约束(改脚前必看):GPIO 33/34 在 ESP32-S3-WROOM-1 模组上**未引出焊盘**; > 型号含 R8(八线 PSRAM)的模组**内部占用 GPIO 35/36/37**;**GPIO 38 = DevKitC-1 v1.1 板载 RGB LED**(初版为 48); > GPIO 19/20 为原生 USB、43/44 为 UART0、45/46 为 strapping 脚,均不应改作他用。 > 完整接线说明见 `docs/接线方案.html`。 ## 上位机协议 (UART0 115200bps,帧头 0xAA55) | 命令 | 值 | 说明 | |------|----|------| | CMD_GET_ALL_PARAMS | 0x07 | 读取所有参数 | | CMD_SAVE_PARAMS | 0x04 | 保存到 Flash | | CMD_SET_WHEEL_RANGE | 0x18 | 设置总角度范围 (uint16 LE) | | CMD_SET_FFB_GAIN | 0x19 | 设置 FFB 全局增益 (0~255) | | CMD_SET_AXIS_X_INVERT | 0x3C | 0/1 | | CMD_SET_OUTPUT_FILTER_ENABLE/ALPHA | 0x40/0x41 | 输出滤波 | ## 校准流程 首次上电: 1. NVS 无校准参数 → 自动触发 `motor_align_sensor()`: - 以固定电压将转子定位一个电周期,判断方向 CW/CCW - 估算极对数 - 将转子固定到电角度 `3π/2`,读取编码器值计算 `zero_electric_angle` 2. 完成后将 **PP / sensor_direction / zero_electric_angle** 缓存在 g_para_list 3. 手动通过 CMD_SAVE_PARAMS 保存(避免反复写入 Flash) 设置方向盘中点:CMD_SET_WHEEL_CENTER → encoder_set_zero_here() ## 开发提示 - 修改 GPIO 或轴数 → 编辑 `include/config.h` - FFB 力度偏弱/偏强 → `components/force_controller/force_controller.c` 中 `FORCE_MAX_TORQUE_NM` 或调节 motor_set_torque 的 `TORQUE_TO_VOLTAGE_SCALE` - FOC 异常抖动 → 降低 `FOC_LOOP_FREQUENCY_HZ` 或调 PID 参数 - Windows 游戏无法检测 FFB → 检查 HID 报告描述符 PID State 的 Input 报告格式或导入注册表 PID 配置 ## TODO / 可改进 - [ ] 电角度零点保存到 NVS 触发 CMD_SAVE - [ ] 电流采样 + FOC Current 闭环 (dq PI) - [ ] 双电机/双 FFB 轴(方向盘 + 排挡阻尼轴) - [ ] WS2812 状态灯 - [ ] Wi-Fi / BLE OTA 升级 ## 许可证 按各源项目许可:esp-ffb (MIT), realTiX (CERN OHL-S 非商用), SimpleFOC (MIT), Arduino-FFB-wheel (可自由使用)。