【教程向】DIY方向盘模拟器制作指南

【教程向】DIY方向盘模拟器制作指南

2026-09-28 18:14:16 0点赞 0收藏 0评论

基于6.5寸平衡车轮毂电机DIY方向盘模拟器的教程

背景

8月初的时候刷到了力反馈方向盘的视频,看了下正经厂家的产品都在1k往上了,感觉价格有点偏高了。然后翻了下发现还有DIY的方案,主流有EMC、OpenFFB、FFbeast等方案。EMC项目比较老了;FFbeast教程比较完善,但是不开源,高级版还要付费;OpenFFB倒是比较新,但是相关教程比较少。

最终在FFbeast和OpenFFB之间犹豫许久,还是决定用OpenFFB,但是硬件部分尽量参考FFbeast,用6.5寸平衡车轮毂电机为主体,这主要是因为二手轮毂电机够便宜、扭矩大,做方向盘模拟器性价比高。

硬件

方向盘模拟器主体一般分为以下几个部分:

  1. 电机(6.5寸15 极对[30 极]平衡车轮毂电机,用于提供力反馈方向盘的反向旋转力)

  2. 角度编码器(用于记录电机的旋转角度,少数电机有自带编码器,但是开关信号的编码器[比如轮毂电机自带的霍尔编码器]不能用,我用的是mt6701磁性角度编码器[配置为 ABZ 增量模式])

  3. 电机驱动板(如果电机是2根线,一般是有刷电机;轮毂电机是三相线,属于无刷电机,我因为参考的FFbeast,用了可以与OpenFFB通讯的Odrive单电机驱动板)

  4. OpenFFB控制板(OpenFFB方案需要,其实如果方案集成度好一点,可以把电机驱动板和控制板合并在一起。参照B站UP关于OpenFFB的视频,用对方群内提供的STM32F407VGT6和固件,后续群内也有了不需要接上拉电阻的固件)

  5. 电源(参照电机要求,我这边电机是36V供电的,所以买的二手明纬36V 350w的开关电源,其实这种36V的轮毂电机用24V的电源也可以,其他电机可以问问AI)

  6. 其他零零散散的连接组件,比如线材、12R100w刹车电阻(Odrive控制器上用的)、SN65HVD230 CAN收发器模块(用于Odrive驱动板和OpenFFB控制板通讯)

硬件部分和选择的方案关系很大,
比如如果使用FFbeast方案,其实电路板里面只要Odrive驱动板就行,不需要[OpenFFB控制板]和[SN65HVD230 CAN收发器模块]

另外目前咸鱼上好像已经有支持驱动无刷电机的OpenFFB控制板,也相当于是[电机驱动板]和[控制板]的二合一版本(GaiFFB),理论上可以替代[Odrive单电机驱动板]、[OpenFFB控制板] 和 [SN65HVD230 CAN收发器模块],可惜我整的时候还没这个板子,没有自己测试过。

硬件连接方式

  • 电机和编码器需要被预处理组装:组装过程可以参考我在markerworld这个页面发布的模型,我这边提供的是齿轮传动方案,相较于FFbeast官网穿孔的方案更易操作,免去了在电机的钢轴上穿孔的处理(PS:钻钢轴太超纲了,一般手电钻打不动的,至少得有个大功率台钻)。

  • Odrive单电机驱动板接线说明:电机和编码器组装处理完成后,将电机供电线、编码器、12R100w刹车电阻、开关电源供电线 都按电路板的对应标识连接到[Odrive单电机驱动板]上,
    另外can通信线这块把 canH/L、3V3线连接到[SN65HVD230 CAN收发器模块],GND线连接到[OpenFFB控制板]的GND即可

Odrive单电机驱动板接线Odrive单电机驱动板接线
  • [SN65HVD230 CAN收发器模块]接线说明:

    见下图

SN65HVD230 CAN收发器模块接线SN65HVD230 CAN收发器模块接线
  • [OpenFFB控制板]的接线说明:

    注意:如果刷入的是需要上拉信号的固件,则需要把A9连一个10k电阻,再接到3V3的针脚上,控制板连接电脑才能识别;如果刷入的是不需要上拉信号的固件,则不需要接这个。

[OpenFFB控制板]接线背面[OpenFFB控制板]接线背面[OpenFFB控制板]接完后正面(需要上拉电阻版本)[OpenFFB控制板]接完后正面(需要上拉电阻版本)

软件部分

完成以上硬件部分连线后,需要设置软件部分:

Odrive清理历史配置。

注意部分Odrive驱动板发货时可能默认被设置过,直接连电机上电会让电机疯转(飞车)产生危险。因此首次设置前可以先断开电机连接线,擦除历史设置,之后再断电重新接上线,然后正常上电。在终端或命令提示符中通过python安装并运行 odrivetool,连接到驱动板之后,执行以下清理命令:

# 擦除 NVM 存储区域的所有配置

odrv0.erase_configuration()

此时板子会自动重启,等待 odrivetool 自动重新连接上 odrv0

Odrive需要先完成校准。

参考以下AI给的代码配置即可:

# === 1. 电源与制动电阻配置 ===

odrv0.config.dc_bus_undervoltage_trip_level = 10.0

odrv0.config.dc_bus_overvoltage_trip_level = 42.0

odrv0.config.brake_resistance = 12.0 # 写入 12.0 欧姆刹车电阻

# === 2. axis0 电机参数 (36V 15极对数毂电机) ===

odrv0.axis0.motor.config.motor_type = 0 # MOTOR_TYPE_HIGH_CURRENT

odrv0.axis0.motor.config.pole_pairs = 15 # 15 极对数

odrv0.axis0.motor.config.current_lim = 10.0 # 电流上限 10A

odrv0.axis0.motor.config.calibration_current = 3.0 # 标定电流 3A

odrv0.axis0.motor.config.resistance_calib_max_voltage = 4.0

# === 3. axis0 编码器参数 (MT6701 ABZ 模式,实测 2048 CPR) ===

odrv0.axis0.encoder.config.mode = 0 # ENCODER_MODE_INCREMENTAL

odrv0.axis0.encoder.config.cpr = 2048 # 实测 2048 CPR

# 使用 Z 相索引线

odrv0.axis0.encoder.config.use_index = True

# 设置寻 Z 相时的转速(单位:转/秒,设小一点,如 2 转/秒,便于准确抓取 Z 脉冲)

# 寻找 Z 相的方向(1 为顺时针,-1 为逆时针)

odrv0.axis0.config.calibration_lockin.direction = 1

odrv0.axis0.encoder.config.calib_scan_omega = 2.0 # 降低扫描速度,防止突发卡停

# === 4. 控制器安全保护 ===

odrv0.axis0.controller.config.vel_limit = 5.0 # 限制最高转速 5 turns/s

odrv0.axis0.controller.config.vel_limit_tolerance = 2.0 # 允许超过 vel_limit 的 2 倍后报 OVERSPEED 保护

# 保存基础参数

odrv0.save_configuration()

odrv0.reboot()

等待重连后,按顺序下发标定并确认标志位

# 1. 触发电机标定(听 2 秒微弱蜂鸣声)

odrv0.axis0.requested_state = AXIS_STATE_MOTOR_CALIBRATION

# 确认命令, 必须返回 True。

print(odrv0.axis0.motor.is_calibrated)

# 2. 触发寻 Z 相, 电机开始单向慢速旋转。只要 MT6701 的 Z 信号线接线正常,旋转不到一圈就会抓到 Z 脉冲并自动停止

odrv0.axis0.requested_state = AXIS_STATE_ENCODER_INDEX_SEARCH

# 停止后打印确认, 必须返回 True

print("是否找到 Z 相:", odrv0.axis0.encoder.index_found)

# 3. 触发编码器偏置标定(顺时针与逆时针各慢速转一圈)

odrv0.axis0.requested_state = AXIS_STATE_ENCODER_OFFSET_CALIBRATION

# 确认命令, 必须返回 True。

print(odrv0.axis0.encoder.is_ready)

# 确认状态均返回 True 后,锁存预标定标志位并存 Flash

# 1. 标记已被预标定

odrv0.axis0.motor.config.pre_calibrated = True

odrv0.axis0.encoder.config.pre_calibrated = True

# 2. 打印验证(此时必然成功返回 True!)

print("Motor Pre-calibrated:", odrv0.axis0.motor.config.pre_calibrated)

print("Encoder Pre-calibrated:", odrv0.axis0.encoder.config.pre_calibrated)

# 3. 保存并重启

odrv0.save_configuration()

odrv0.reboot()

配置 ODrive 开机自动寻零与自动闭环

# 1. 禁用开机电感/相阻标定与偏置扫描(已预标定,不再需要)

odrv0.axis0.config.startup_motor_calibration = False

odrv0.axis0.config.startup_encoder_offset_calibration = False

# 2. 开启开机自动寻找 Z 相 (Index Search)

odrv0.axis0.config.startup_encoder_index_search = True

# 3. 找到 Z 相后,自动切入闭环控制 (Closed Loop)

odrv0.axis0.config.startup_closed_loop_control = True

# 4. 设置安全开机默认控制模式(直驱方向盘推荐:力矩模式,初始力矩 0.0)

odrv0.axis0.controller.config.control_mode = 1 # 1: TORQUE_CONTROL

odrv0.axis0.controller.config.input_mode = 1 # 1: PASSTHROUGH

odrv0.axis0.controller.input_torque = 0.0 # 初始输出力矩归零,安全待命

# 5. 配置 CAN 通讯参数 (Axis0 Node ID = 0)

odrv0.config.enable_can_a = True

odrv0.axis0.config.can_node_id = 0

# 打印当前 CAN 总线配置参数,CAN 总线波特率默认250000,且不允许更改

print(odrv0.can.config)

# 打印 Axis0 的 CAN 配置参数

print(odrv0.axis0.config.can)

# 5. 保存并重启

odrv0.save_configuration()

odrv0.reboot()

离线上电物理效果验证

完成上述配置后,可以拔掉Odrive的 USB 数据线(完全离线):

  1. 切断 36V 母线电源,等待 ODrive 板上指示灯熄灭。

  2. 重新接通 36V 电源。

  3. 观察物理现象:

    上电瞬间,电机自动单向慢速转动不到一圈(触发 MT6701 Z 脉冲)。

    抓到 Z 脉冲后,电机瞬间停止旋转。

    此时 ODrive 已自动切入闭环锁死状态(state == 8),电机力矩待命,无需电脑和 USB 干预!

先断开Odrive电源,再开始openFFB设置。

OpenFFBoard Configurator 上位机软件, 从 github这边 获取

将 OpenFFBoard (STM32F407) 通过 USB 插上电脑,打开 OpenFFBoard Configurator。

  1. 点击左侧导航栏的 Axis 0(主轴设置)-Motor Driver(电机驱动):下拉菜单选择 ODrive (CAN)。

  2. CAN Baudrate(波特率):选择 250k(必须与 ODrive 端一致)。

  3. Node ID:填入 0(匹配 axis0.config.can_node_id = 0)。

  4. 点击右下角 Save to Flash 保存设置。

  5. 断开Odrive和openFFB电源。

初始化联调。

启动与通电顺序

由于系统使用带 Z 相的增量式编码器,启动顺序极度严格,必须绝对遵守以避免正反馈飞车甩盘:

  • 切断 Odrive 和 OpenFFBoard: 确保 Odrive 和 STM32F407 的 USB 未插电脑,未供电。

  • 飞车预警: 注意由于我们使用了2:1的齿轮,所以打一圈方向会有2个 Z 脉冲点位,默认上电回中操作会找最近的一个 Z 脉冲点位,但是openffb只识别这2个点位的其中一个,如果恰好上电后是停在另一个点位,会导致方向盘疯转,进入飞车状态。针对这个问题,可以重新全部断电,然后将方向盘转到另一个 Z 脉冲点位附近,然后重复下面的步骤。

  •  ODrive 动力上电: 保障电机周围没有障碍物,开启 ODrive 的 36V 动力电源。
        现象: 电机通电后会自动缓慢旋转一小段距离,捕获到 Z 脉冲后瞬间停顿锁死。

  •  连接 OpenFFBoard: 在电机完全静止后,再插入 OpenFFBoard 的 USB 连接线,小心,此时有可能方向盘疯转,进入飞车状态。
    飞车处理: 如果出现飞车,一般有2种可能:

    一是上面说的Z 脉冲点位问题;

    另一个是OpenFFBoard下发反向了,可以尝试OpenFFBoard Configurator的Axis 0配置里找到 Invert Motor Direction(或者 Invert Axis/Driver),更改其当前状态(勾选变取消,取消变勾选)

  • 正常表现现象: 方向盘呈现带有平顺回中力或阻尼手感的状态。

游戏配置

软件设置完成后方向盘能自动回中openFFB接入就完成了,后续每次重新上电都参考上面第5部分的启动与通电顺序即可。

剩余部分就是参数调整和游戏配置了。

参数调整 和 游戏适配性 请自行参考openFFB的github页面

这边说下我玩过的几个游戏配置:

  1. ACC(神力科莎:竞速)的游戏配置,ACC里面默认识别不到方向盘,转向的绑定需要大幅度打OpenFFB盘子的方向才能识别盘子。

  2. 欧卡2:这个比较方便,选项——控制 里面能自动识别到FFBoard,选择 键盘+FFBoard 就行

作者声明本文无利益相关,欢迎值友理性交流,和谐讨论~

展开 收起
0评论

当前文章无评论,是时候发表评论了
提示信息

取消
确认
评论举报

相关文章推荐

更多精彩文章
更多精彩文章

爱好灵车产品

关注 打赏
最新文章 热门文章
相关兴趣推荐
0
扫一下,分享更方便,购买更轻松