当前位置: 首页 > news >正文

【simpleFOC】一个电机如何模拟不同旋钮的手感反馈?

原文链接:https://mp.weixin.qq.com/s?__biz=MzU1NjEwMTY0Mw==&mid=2247597033&idx=2&sn=e92f8f1dec8b363aa209788354f8fa64&chksm=fad1130bfafd0b9af53b0f110e354d8772f6c5a0d98735690d1c0c75d0c3c75785ea1041ea1a&scene=27

 

概述

simpleFOC可以实现对各种电机的精确控制,并且提供闭环扭矩反馈控制。那我们是否可以利用这种特性,用一个电机来模拟不同旋钮的手感反馈呢,答案是,当然可以!!而且网上也有不少开源的案例,例如最开始的smartknob,还有国内各种适配,修改的版本,这里就不一一列举了。

 

而本篇将使用2808电机,arduino和simplefocshielf,模拟不同旋钮的旋转手感,而不会将目光放在旋钮的交互上。

 

图片

 

 

初始化设置

 

再开始之前,我们需要在arduino的初始化函数当中设置一些电机和驱动的参数。

 

配置位置传感器,使用i2c与arduino进行通信:

MagneticSensorI2C sensor = MagneticSensorI2C(AS5600_I2C);

 

配置电机和驱动:

BLDCMotor motor = BLDCMotor(7);BLDCDriver3PWM driver = BLDCDriver3PWM(9, 5, 6, 8);

 

设置驱动输入电压为24v,并初始化驱动:

driver.voltage_power_supply = 24;driver.init();

 

设置控制模式(这里我们使用力矩控制模式)

motor.controller = MotionControlType::torque;

 

完整初始化代码如下:

void setup() { // 设置串口波特率  Serial.begin(9600);  // enable more verbose output for debugging  // comment out if not needed  SimpleFOCDebug::enable(&Serial); // initialise magnetic sensor hardware  sensor.init();  // link the motor to the sensor  motor.linkSensor(&sensor); // 设置驱动输入电压为24v  driver.voltage_power_supply = 24;  driver.init();  motor.linkDriver(&driver); // aligning voltage   motor.voltage_sensor_align = 3;  // motor.voltage_limit = 5;  // choose FOC modulation (optional)  motor.foc_modulation = FOCModulationType::SpaceVectorPWM;  // set motion control loop to be used  motor.controller = MotionControlType::torque; // comment out if not needed  motor.useMonitoring(Serial); // initialize motor  motor.init();  // align sensor and start FOC  motor.initFOC(); // add target command T  Serial.println(F("Motor ready."));  Serial.println(F("Set the target voltage using serial terminal:"));  _delay(1000);}

 

 

一、无阻力手感

 

在力矩控制模式下,只要将期望力矩设置为0,即可实现无阻力手感,该模式下,电机模块相当于一个数值传感器,无任何手感反馈,这里就不做演示了

 

 

二、阻尼手感

 

在许多应用中,比如高端音响设备、工业控制面板或者游戏控制器,阻尼手感旋钮提供了一种直观且具有反馈感的用户交互方式。这种旋钮通常会给人一种平滑而有阻力的感觉,使用户在操作时能够更加精准地控制。通俗解释,就是有一股作用力来阻止我们旋转电机。这实际上是一种负反馈控制,我们使用电机速度作为反馈信号,其公式如下:

 

图片

写成代码就是:

tau = Kd * sensor.getVelocity()

 

接下来就是调kd了,kd越大,给的阻力就越大,我们先给个0.05,

过大的KD会导致电机疯狂抖动,建议从一个较小的值开始尝试

float Kd = 0.1;void loop() {  motor.loopFOC();  float tau = -Kd * sensor.getVelocity();  motor.move(tau);}

 

效果演示:

 

图片

 

 

三、顺滑手感

 

顺滑手感旋钮的关键在于实现旋钮在转动时的平滑响应。这意味着旋钮在转动过程中不会有任何卡顿或突兀的感觉。与上一章相反,要电机顺滑转动,需要正反馈,同样使用电机速度作为反馈信号,有以下:

 

图片

 

其中Kd需要是一个很小的值。

float tau = Kd * sensor.getVelocity();motor.move(tau);

 

因为是正反馈,如果Kd过大,会造成电机一致转下去。

float Kd = 0.04;void loop() {  motor.loopFOC();  float tau = -Kd * sensor.getVelocity();  motor.move(tau);}

 

效果如下:

 

图片

 

 

四、档位手感

还有一种旋钮是具有档位的,一圈会成好几个小段,每旋转过一段会产生顿挫感。而这种顿挫感,我们同样可以利用foc来实现。实际上,与上两节不一样,该手感是来自位置反馈,参考灯哥开源里面的原理解释。

 

图片

 

主循环代码如下,设置Kp为5,档位数量为4:

float Kp = 5;void loop() {    motor.loopFOC();  float num = 4; // 档位数量  float attractor_distance = 360/num * 3.1415926 / 180.0; // 转换为弧度制  float target = round(sensor.getAngle() / attractor_distance) * attractor_distance;  motor.move(Kp * (target - sensor.getAngle()));}

 

Kd值越大,档位的顿挫感就越强,效果如下:

 

图片

 

 

总结

根据力的反馈,我们可以利用电机来模拟各种各样的旋钮反馈手感,如果加上一些底层交互逻辑,我们就可以实现智能旋钮,用来控制智能家居等设备。

http://www.wxhsa.cn/company.asp?id=4073

相关文章:

  • 第一周作业2
  • 第一次课堂作业
  • [高可用/负载均衡] Ribbon LoadBalancer: 开源的客户端式负载均衡框架
  • 梦话周记
  • 【电机控制】无刷电机结构阐述---磁极数、槽数
  • 金刚怒目是我哭
  • nginx使用默认端口80作为服务端口
  • 机器学习和推荐算法顶级会议和期刊
  • java使用mysql
  • 2025年医疗行业API安全最佳实践与深度案例分析:从理论到全面落地
  • 2026 NOI 做题记录(二)
  • lc1027-最长等差数列
  • 13
  • np.zeros函数
  • Langchain之让LLM拥有记忆
  • 25.9.14
  • .net PublishSingleFile 打包程序提取
  • 实用指南:Java类加载机制
  • C 语言注释
  • 扫描线
  • C语言中的查找与排序算法整理
  • k8s练习
  • css-2
  • AtCoder Beginner Contest 423 ABCDEF 题目解析
  • numpy中的shape属性
  • mac 查看fat32磁盘
  • 使用Smart-Doc为Java项目生成gRPC API文档
  • 数字时钟用的什么字体
  • Python数据分析零基础完整课程大纲(详细版)【202509第1版】 - 指南
  • 详细介绍:uni-app 根据用户不同身份显示不同的tabBar