专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
2015年全国大学生电子设计竞赛-风力摆源代码-经验交流-开发教程
2019-07-20 22:12
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
2202
13
1443
本帖最后由 zcxlyf 于 2019-6-30 22:26 编辑
2015年全国大学生电子设计竞赛风力摆源代码及开发教程
学校:海南大学 作者:刘一帆 邮箱:
zcxlyf_wy@163.com
,
liu-yifan@sjtu.edu.cn
注:本代码基于正点原子代码改编,供各位学习参考,不要用于商业用途!欢迎各位交流经验
这篇是我移植别人代码改编做的,其中有些是我根据情况变通改编的,
原帖
。理论分析我是看着这篇做的,所以理论部分我也就不说了。只是这篇代码部分有些有问题,我就改掉了。下面从硬件开始讲解我是怎么移植过来的吧!
一、硬件搭建
1.骨架。骨架我是采用PVC供水管搭的,四个方向上用相同直径的弯头用螺丝上紧,不过这样机械结构很难对称。
风力摆骨架
2,电机。上面这篇帖子并没有说电机使用的是那个型号。我从代码里面看到说电机使用12V空心杯。这点搞得很难受,因为某宝上最大的空心杯电机仅仅为5V驱动。然后我就买了小的空心杯820。结果拿回来之后绑上全速开动摆仅仅偏转5~10°左右。很失望,然后我就疯狂的搜索12V电机,结果还真有,某宝上号称12V空心杯,15块大洋一个,忍痛买了四个回来。测试一下感觉好一点点。最后做出来还是用820就够了。
12V电机
3.驱动。驱动部分我采用的时BTN791B,这个大家可以某宝搜索飞思卡尔驱动就有了,价格将近一百五大洋。起初我才用的是L298N,不过L298N是三极管构造的,发热严重,而且有压降。这款是MOS管沟道,发热微乎其微,而且可以通过的电流巨大~详细见数据手册。你要问我为啥选这个,难道L298N不行吗?当然可以,BTN791B用在这个上面真的是杀鸡用宰牛刀了。用这个主要是学院407厕所垃圾堆里捡的,对,事实就是这样。
4.传感器。传感器采用原子的MPU6050。在这里就要安利一下了,原子的东西真的很好用,搭配战舰V3开发板,只要用热熔胶固定上去就行。而且内置DMP,不用在代码里面进行卡尔曼滤波,直接读取数据就行,这块在软件方面再说。
风力摆底部
5.主控。主控采用原子的战舰V3,没办法,谁让人家做的好呢。
二、软件设计
1.电机控制。首先要做的是能控制电机,这个最基本了吧?我是利用定时器3做的输出四路脉宽波,首先做到四路占空比都可控,用示波器观察。其次要考虑频率不能太高,别超出了MOS管开关频率,我咨询老师说一般20K左右就够了,但是也别太小,太小延迟高,控制不精准。如果没问题那OK,下一步。
2.上位机使用。根据原子的教程MPU6050这一章节可以利用匿名四轴上位机做姿态显示以及绘制波形。在这点上寄存器版本有下面这行代码我觉得没什么用。我觉得原子自定义帧发送是说上位机可以收到,但是波形不能绘制,这点我请教原子哥—额—半个月过去了原子哥也没给我回复。
下面继续说波形吧,波形我们可以看到ROLL,PITCH, YAW三个角(简直太方便了有木有?)。在此期间我想到,代码要反复调节,不能说我烧一次代码测试一次吧?当然上位机能收也能发,于是我花了几天研究匿名的通信格式以及写代码测试下位机接收并且修改相应的PID三个参数,这样在上位机直接修改并且电机写入飞控就能更改PID三个参数(小得意一下哈)。
3.PID。PID源码我就不用说了吧,百度一抓一大把。关于MPU6050需要补充一句,由于采样频率为200Hz,原子例程里面仅仅是50Hz,所以我们要在MPU_Init()和DMP_Init()中修改一下参数。我这里对差值进行积分也同样进行限幅,不过幅值并不是限定在2300,而是1000,这是因为PWM波的计数重装值就是1000,采用经典PID算法不对积分进行限制容易导致干扰后恢复时间变的长。下面黄 {MOD}是目标值,灰 {MOD}是实际值。
关于PID参数整定,我也是被困在这好几天,整定出来算是偶然有了一个灵感然后就全做出来了。之前我也没有整定的经验,一直设置不好,摆摆着摆着就飞起来了,控制不住自己啊!后来想到大角度的摆不能用正弦来近似了,大角度时候重力在电机方向上的分力不能直接忽略,需要把这部分考虑进去。摆角5°左右才能用正弦近似,于是我就把幅值设定为5°。哎,对应当时的PID参数相位有点滞后,但是很稳定,干扰过后恢复能力也较强,于是我眼前一亮,这样加大D不就行了吗?然后破天荒的把D调到了一万(别问我问什么,人性,彪悍的人生不需要解释),之前最多也就到2000,而且那个时候I也比较大,大概在2~10之间。改了之后小角度跟踪的相当完美,当时是激动的不行,终于出结果了。但是接下来大角度怎么搞?把角度增大之后发现幅值达不到,于是就把D直接怼到两万一,最后细调I跟P,就这样解决啦~然后下面的题目全部都迎刃而解了。
总结经验来看,首先PID参数整定过程中对I设定值有点高,没有很好理解差值积分限幅的作用所以在代码中用经典PID算法调试。其次,虽然知道曲线存在相位差系统惯性太大需要增加D值,但参考代码里面D最高也就设置为2000,思维受限,没想着把D加到5000以上,所以一直调试不出结果。以后参数整定过程中可以步子迈的大一点。
画直线方面我的线性长度误差大概是在±3cm,稍微超出了范围,这个可以从机械结构上做文章改进。各位看客老爷们再改进吧,小编我就去琢磨其他的东东去啦~同时欢迎各位大侠指点。
下面是做完之后几个问题以及发现吧!
问题一:驱动用L298N可以吗?
当然可以,我参考的代码估计就是用L298N 做的。
问题二:需不需要进行卡尔曼滤波?
这点我又要安利一下了,原子的东西这么好,内置DMP解算数字,还给你例程,拿去直接用呗,一个函数就调用就出角度加速度了。至于为什么?怎么工作的?别问我,我也不清楚。只是不滤波偶尔还是有点错误数据的,如图所示,不过出现的比例非常低,我感觉万分之一吧。
问题三:PID整定怎么调?
这个别人总结比较好,什么什么绕大弯……。我也不太懂,但是知道P大了回复快,I为了消除静差,但是I大了不好,偏离有点多。D小了相位跟不上,惯性越大一般D越大,多调多想就能凑出来。最后说一下,由易老师提醒尝试,在这个题目里面,PI都设置为0系统依然跟得上(随动系统),只不过响应速度慢了很多,如果对于目标值是定值就不行了。
这是因为在这个题目里面仅仅是在突变处用D调节,其他两个作用不大,仅仅考虑角度差,系统不知道何时角度最大,何时最小。这里调节出来还是运气好,这样大角度的误差就大的多了。换句话说摆的目标摆动频率跟系统固有频率很接近才能成功,当差别很大根本跟踪不上。
鸣谢
首先感谢原帖作者无私的分享,其次感谢原子提供高质量的例程以及匿名科技的四轴上位机,感谢焦辰泽同学不遗余力的帮助,易家傅老师、冯尔理老师、李 鹏 翔学长的指点。完结【撒花】
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
13条回答
czw
2019-07-22 04:01
楼主,想请教一下,你是如何通过匿名上位机画出波形图的。
我看你的代码中
if(report)usart1_report_imu((short)Rol_Set_Pos,(short)Pit_Set_Pos,rol_pwm/100,pit_pwm/100,rol_i,rol_d,(int)(roll*100),(int)(pitch*100),(int)(yaw*10));
复制代码
上面的rol_i, rol_d 是什么参数
//通过串口1上报结算后的姿态数据给电脑
//aacx,aacy,aacz:x,y,z三个方向上面的加速度值
//gyrox,gyroy,gyroz:x,y,z三个方向上面的陀螺仪值
//roll:横滚角.单位0.01度。 -18000 -> 18000 对应 -180.00 -> 180.00度
//pitch:俯仰角.单位 0.01度。-9000 - 9000 对应 -90.00 -> 90.00 度
//yaw:航向角.单位为0.1度 0 -> 3600 对应 0 -> 360.0度
void usart1_report_imu(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz,short roll,short pitch,short yaw)
复制代码
和原函数介绍好像相差挺大的
加载中...
查看其它13个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
我看你的代码中
- if(report)usart1_report_imu((short)Rol_Set_Pos,(short)Pit_Set_Pos,rol_pwm/100,pit_pwm/100,rol_i,rol_d,(int)(roll*100),(int)(pitch*100),(int)(yaw*10));
复制代码上面的rol_i, rol_d 是什么参数
- //通过串口1上报结算后的姿态数据给电脑
- //aacx,aacy,aacz:x,y,z三个方向上面的加速度值
- //gyrox,gyroy,gyroz:x,y,z三个方向上面的陀螺仪值
- //roll:横滚角.单位0.01度。 -18000 -> 18000 对应 -180.00 -> 180.00度
- //pitch:俯仰角.单位 0.01度。-9000 - 9000 对应 -90.00 -> 90.00 度
- //yaw:航向角.单位为0.1度 0 -> 3600 对应 0 -> 360.0度
- void usart1_report_imu(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz,short roll,short pitch,short yaw)
复制代码和原函数介绍好像相差挺大的
一周热门 更多>