Simple FOC内置通信接口学习(一):实时监控电机状态
本文参(zhao)考(chao)至官方文档https://docs.simplefoc.com/docs_chinese/monitoring
引言
在使用Simple FOC控制电机的过程中,尤其是对电机进行调试的时候,我们常常希望能在初始化和校准过程中显示电机的状态以及实时了解到电机每时每刻的状态参数。当然,强大的Simple FOC库早已为我们准备好了一切,那就是今天的主角(划重点):监控功能
和Commander接口
。Simplefoc库实现了一个简单的通信方案,借此,我们可以快速方便地对所设置的参数进行测试、调试和监控。在使用官方的SimpleFOCStudio(推荐新手使用,中文版戳这SimpleFOCStudio中文版)图形化傻瓜式调参以及监控电机之余,我们不妨来深入了解一下这套通信方式~既能增长知识,还能方便我们二次开发。
监控功能
BLDCMotor
和 StepperMotor
类支持使用 Serial
进行监控:
motor.useMonitoring(Serial);
监控有两个主要目标:
- 在初始化和校准过程中显示电机的状态
- 实时监控电机的变量
监控电机初始化过程
初始化motor.init()
和校准过程 motor.initFOC()
期间,电机将向串口输出其状态。启用此功能不会直接影响实时性能,因为在 motor.loopFOC()
和motor.move()
函数中没有预定义的实时循环监控。
这是一个电机正常初始化监控输出实例:
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor direction==CW
MOT: PP check: OK!
MOT: Zero elec. angle: 4.28
MOT: Align current sense.
MOT: Success: 2
MOT: Ready.
位置传感器导致电机初始化失败:
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: Failed to notice movement
MOT: Init FOC failed.
以及电流传感导致的电机初始化失败:
MOT: Monitor enabled!
MOT: Init
MOT: Enable driver.
MOT: Align sensor.
MOT: sensor direction==CW
MOT: PP check: OK!
MOT: Zero elec. angle: 4.28
MOT: Align current sense.
MOT: Fail!
MOT: Init FOC failed.
电机变量实时监控
监控的第二个作用是实时标签分离输出电机变量到串行终端。它是启用的,包括这行循环函数:
监控的第二个作用是将电机变量实时以选项卡分隔的方式输出到串行终端。 在loop()
中执行以下函数来启动:
motor.monitor()
监控功能可输出7种不同的电机具体变量::
target
- 当前目标值,具体到所使用的运动控制(电流、电压、速度或位置)voltage.q
- 设置 电压分量qvoltage.d
- 设置电压分量dcurrent.q
- 电流分量q的测量值(如果电流传感可用)current.d
- 电流分量d的测量值(如果电流传感可用)shaft_velocity
- 电机速度shaft_angle
- 电机位置
设置监视的首选值,可以在setup()
函数中更改 motor.monitoring_variables
参数。
motor.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE; // 默认 _MON_TARGET | _MON_VOLT_Q | _MON_VEL | _MON_ANGLE
默认情况下,监控的变量为 target
,voltage.q
,velocity
,angle
。该参数是一个7bit值,其中每个位代表 bool
标志信号,来表示变量应该输出 (1) 还是不输出 (0),。因此,我们定义了一组帮助监控常量,可以组合起来更容易地处理监控:
#define _MON_TARGET 0b1000000 // 监视器目标值
#define _MON_VOLT_Q 0b0100000 // 监视器电压q值
#define _MON_VOLT_D 0b0010000 // 监视器电压d值
#define _MON_CURR_Q 0b0001000 // 监视器电流q值 - 如有测量
#define _MON_CURR_D 0b0000100 // 监视器电流d值 - 如有测量
#define _MON_VEL 0b0000010 // 监视器速度值
#define _MON_ANGLE 0b0000001 // 监视器角度值
此外,使用motor.monitor()
函数输出实时执行变量在许多情况下会对电机性能产生负面影响,因此,应该尽可能减少对该函数的调用,特别是在低波特率时输出很多变量。你可以通过参数motor.monitor_downsample
来设置:
// 降采样
motor.monitor_downsample = 100; // 默认为10
这个变量告诉 motor.monitor()
直到计数到monitor_downsample
时才将变量输出到串行。也就是说每到一次monitor_downsample
循环才会输出一次变量。
下面是一个完整的配置代码实例:
...
void setup(){
...
Serial.begin(115200); // 越高越好
motor.useMonitoring(Serial);
//显示变量
motor.monitor_variables = _MON_TARGET | _MON_VEL | _MON_ANGLE;
// 下采样
motor.monitor_downsample = 100; // 默认为10
...
}
void loop(){
....
motor.monitor();
}
实时监控功能主要用于实时可视化,特别适用于Arduino IDE的Serial Plotter
或者在 Serial Terminal
...
voltage,target,velocity
1.17 2.00 2.29
1.23 2.00 1.96
1.30 2.00 1.65
1.28 2.00 1.80
1.20 2.00 2.20
1.07 2.00 2.70
0.91 2.00 3.22
0.69 2.00 3.74
0.40 2.00 4.34
0.18 2.00 4.57
0.09 2.00 4.38
0.06 2.00 4.04
0.08 2.00 3.58
0.11 2.00 3.14
0.18 2.00 2.65
0.27 2.00 2.13
0.37 2.00 1.65
0.47 2.00 1.26
0.55 2.00 0.99
0.64 2.00 0.77
0.71 2.00 0.67
...
执行时间障碍
这个方法的目的是在主循环函数中顺着loopFOC()和 move()函数调用。因此, motor.monitor()将会影响执行性能,降低FOC算法的采样频率,因此在运行代码时要考虑这个因素。
自定义串行终端监控
如果希望实现自己的监控功能或只是将电机变量输出到Serial
串行终端,这里有BLDCMotor
和StepperMotor
类的公共变量,可以随时访问。
// 电流目标值
float target;
// 当前电机角度
float shaft_angle;
// 当前电机速度
float shaft_velocity;
// 当前目标速度
float shaft_velocity_sp;
// 当前目标角度
float shaft_angle_sp;
// 当前设置的电机电压 (voltage.q, voltage.d)
DQVoltage_s voltage;
// 当前电机电流 (current.q, current.d) - 如有测量
DQCurrent_s current;
// 相电压
float Ua, Ub, Uc;
在此之前可以通过添加motor
来访问这些变量中的任何一个。例如:
Serial.println(motor.shaft_angle);// 打印当前电机位置至串口终端
// 或者
Serial.println(motor.Ua); // 打印相电压Ua至串口终端
监视只能在一个方向上工作,并且假设它实现用户通信。
使用电机命令实时用户通信
为了在用户和电机之间进行双向通信, Arduino SimpleFOC库 为你提供了 。