找回密码
 立即注册

QQ登录

只需一步,快速开始

打印 上一主题 下一主题
开启左侧

无感FOC代码: 调试简单,起转顺利

  [复制链接]
81#
 楼主| Angus 发表于 2024-9-16 09:00:34 | 只看该作者
积分抗饱和运算

如果电机转速已到最大,而设定转速仍比实际转速大,转速 PI 的积分计算仍一直增加电流设定值,最终电流设定值加到上限,可能比电流实际值大很多倍。如下图电流设定值一直加到了高位 =0x0019,十进制的25,比电流实际值 Iq_Measure 的高位= 2,大了12倍多。

这时如果设定转速 RPM_Set 调到 4767 以下,电流设定值要很久才能降到电流实际值以下,而这期间转速不会下降,这就是积分饱和引起的调节滞后,不好的使用体验。




假如本次转速误差 Err_Spd =K,K>0,  
下次 PI 运算时前 Err_Spd_Last = Err_Spd = K ; 到时候若转速设定值与转速实际值一样,即 Err_Spd = 0 ;  则转速 PI 运算就是
temp32 = (Err_Spd - Err_Spd_Last)*Kp_Speed +Err_Spd*Ki_Speed = -K * Kp_Speed ;   
如果下次刚好能让“电流设定值 = 电流实际值”, 那么就不会积分饱和。

即本次转速 PI 计算的电流值若等于下式,下次转速 PI 运算就可以把增量减去,不会积分饱和


本次电流设定值 =  K * Kp_Speed + 电流实际值 = Err_Spd * Kp_Speed + 电流实际值 ;  // 这个是本次电流设定值的上限


K 值取多少呢? 因转速控制精度1%以下,可取转速最大值的 1/64。所以有以下积分抗饱和运算代码:



这段代码的执行效果如下图,电流设定值只增加到实际值的 2.7 倍,这是下次能一次把电流误差回调到 0 的值。




回复 支持 反对

使用道具 举报

82#
 楼主| Angus 发表于 2024-9-17 11:00:43 | 只看该作者
本帖最后由 Angus 于 2024-10-2 21:11 编辑

电机启动流程

更新转速设定值 RPM_Set ,不是一个很紧急的事件,在 main() 主循环中,按旋钮 ADC 值确定转速设定值 RPM_Set 是多少。

在main() 主循环代码中,电机可能在同步转,也可能未在同步转。分别做如下处理:



一,如果电机在同步转(Motor_Status 的 bit4 非0),下图318行,做以下事情:
如果 RPM_Set  <= 0,  说明电机已在停转降速中,这时需判断一下,若转速已降到最小值以下,就去状态 1 刹车停转。
如果 RPM_Set >0,  这里不需要做什么。电流大小由SysTick 中断里、转速 PI 计算结果决定;电压角度和 PWM 输出占空比,由 ADC 中断里计算、输出。

二,如果电机未在同步转, 下图327 行,要么不需要起动(RPM_Set <= 0),要么需要启动(RPM_Set >0)。



1>,如果不需要起动(RPM_Set <= 0),又已在起动流程(状态3,4,5,6),则直接刹车停转(335行, 去状态1)、或关功率管(去状态0)就行了。
       如果未在启动流程,未转、也未在启转,就判断是否取消故障状态,转向开关是否变了,等等。

2>,如果需要起动、又未在启动流程,执行到 362 行,先调用函数 Test_Period() 判断是否已顺风吹转,若是则跳转到状态6,顺风起转。若未顺风转,跳转到状态 2 先给自举电容充电,充电结束后,在状态 2,按宏定义决定跳转到状态 3 开始 V/F 起转、还是跳转到状态 5 ( 再跳转到状态4)  开始 I/F 起动。

     若需要启动,又已在启动流程,这里就不需要做什么了,ADC 中断里、启动代码会变换状态。





回复 支持 反对

使用道具 举报

83#
 楼主| Angus 发表于 2024-9-23 11:33:55 | 只看该作者
本帖最后由 Angus 于 2024-10-2 21:09 编辑

代码的总体架构就是main() 里的主循环 + 两个中断,这里介绍一下这三部分之间的关系或相互之间的数据通信



每个PWM 周期产生一次 ADC 中断,转电机的代码主要在 ADC 中断里,包括电流 PI 计算。"电流 PI 运算"的电流设定值来至 SysTick 中断里"转速 PI 计算"的计算结果(同步转时), 或ADC 中断里自己决定电流设定值大小(启动时)。

SysTick 中断代码里,用转速设定值和实际值,做转速 PI 计算求出电流设定值 Iq_set_f12,Id_set_f12 由 ADC 中断代码用。既然这个全局变量,只有在同步转时 ADC 中断代码才用到,不同步时,就不做这个转速 PI 计算了,详见 SysTick 中断代码。

在 ADC 中断里,状态机的转变如下图,状态0(关功率管停转状态)不会变成其它状态,如果需要启动(转速设定值 RPM_Set >0) 要在 main() 主循环里判断,转变为状态2(静止状态启动)或状态6(顺风转时启动)



main() 主循环里,除了启动前判断一下是否已顺风转,还会做一件事:判断如果启动时出现 RPM_Set <=0, 就是又不想启动了,那就直接变状态1、立即停止启动,不必再等超时了。
回复 支持 反对

使用道具 举报

84#
 楼主| Angus 发表于 2025-1-13 11:18:13 | 只看该作者

回复 支持 反对

使用道具 举报

85#
 楼主| Angus 发表于 2025-3-5 15:02:04 | 只看该作者
本帖最后由 Angus 于 2025-3-17 22:11 编辑

转速控制 ,涉及到以下几个变量

RpmMechanical_Set : UART转速指令、或由旋钮获得的机械转速值

RPM_Command :  转速指令对应的电转速,但是,若Stop_Runing 非0(有异常)此值等0

RPM_Set_Target : 控制加减速的转速设定值,此变量慢慢增加或慢慢减小,直到等于RPM_Command,范围 0~Max

RPM_Set   :   此变量基本= RPM_Set_Target,  只是范围 Min ~ Max,停转时此值是负值,是为了加快转速PI 运算结果的电流值下降

停转时,若想降速受控,慢慢降速,就让 RPM_Command =0,电流慢慢下降。降速过程保持着同步。
停转时,若让RPM_Set_Target=0,则电流立即=0,风机会自由降速,降速过程仍保持着同步。水泵降速很快。
若让状态变量 Motor_Status =0,下个PWM 周期就关功率管,电机自由停转,降速过程不保持同步。
回复 支持 反对

使用道具 举报

86#
 楼主| Angus 发表于 2025-3-12 16:58:47 | 只看该作者
缺相时,电流等于0,似乎缺相不难检测出,可做起来并不容易。
正常转动时,角度=0或180度时,相电流等于0,所以不能检测到电流=0就认为是缺相。如果检测到电流=0持续一段时间才认为是缺相,则在确定缺相前,电机已无法正常转动,可能已关功率管了。

启动期间三相的电流差异较大,缺相的条件很难确定。长时间电流较小, 检测多长时间合适也不容易确定。

实际测试还发现,断线的那相,电流ADC 数据异常波动,波动幅度已超过了轻载、低速转动的电流。 如果设置一个电流门限,低于此门限就认为是缺相,电流判断门限若设置高了,轻载低速时会误判为缺相。若门限低了,真缺相又会判断不出来




我们最终确定的办法是,启动前在 240 度通电,通电时间参考 L/R,一般几个毫秒就可以。这时电流经 C 相流向 AB 相, 三相都有电流,AB 相电流是 C 相的一半。如果有一相电流比设定电流小一半以上, 置位一个标志,可能缺相了。 继续启动, 如果后面启动成功了,就不认为是缺相,清除标志(310行)。如果后面启动失败了,才确定是缺相(285行),这样就减少了误判。





回复 支持 反对

使用道具 举报

87#
匿名  发表于 2025-3-14 08:34:14
Angus 发表于 2025-3-12 16:58
缺相时,电流等于0,似乎缺相不难检测出,可做起来并不容易。
正常转动时,角度=0或180度时,相电流等于0, ...

思路好。不过有另外的问题,假如没有缺相,启动失败也发生了,那这时怎么判断是什么故障?
回复 支持 反对

使用道具

88#
 楼主| Angus 发表于 2025-3-14 09:16:23 | 只看该作者
本帖最后由 Angus 于 2025-3-17 22:02 编辑
游客 58.49.24.x 发表于 2025-3-14 08:34
思路好。不过有另外的问题,假如没有缺相,启动失败也发生了,那这时怎么判断是什么故障? ...

如果没缺相,标志 TempFlag_Open 不会写成非0,一次启动失败,会停一秒左右,再次启动。如果电机卡住了根本转不动,FailCnt 失败计数,多次失败就不再启动了(上图中 286行),需人工干预,不会报缺相故障,报多次启动失败故障。

正常情况一次就能启动成功。若负载较重,偶尔失败一次,第二次能启动成功。
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则

新唐MCU