其他分享
首页 > 其他分享> > 用STM32F401和nRF24L01做无线调速小车

用STM32F401和nRF24L01做无线调速小车

作者:互联网

硬件配置

在做这个小项目前, 深入考察过STM32F103C8T6, STM32F401CCU6和STC89C52这三个MCU, 并实际跑了一些用例

最终选择的是STM32F401CCU6, 代码上的问题都不是问题, 对吗?

遥控器部分

硬件部分的说明

小车部分

硬件部分的说明

接线

遥控器部分

MCU需要的接口如下

与nRF24L01的接线

STM32 nRF24L01
PA4 SPI1_NSS N/A
PA5 SPI1_SCK SCK
PA6 SPI1_MISO MISO
PA7 SPI1_MOSI MOSI
PB13 IRQ
PB14 CE
PB15 CSN

小车部分

MCU需要的接口如下

nRF24L01接线同上.

功能实现

遥控器部分

这一块主要是通过两个ADC通道采集摇杆电压, ADC采集使用的DMA的模式, 在主循环中定时(几十到几百毫秒)去读取电压, 并转换到[0, FF]区间, 通过nRF24L01发射出去. ADC采集电压时, 每个通道使用4个u16做缓存, 输出的数值是对这个4个数值做平均, 抑制抖动.

涉及的技术名词: UART, ADC, DMA, TIMER, SPI

小车部分

小车部分的功能有几部分:

  1. nRF24L01的中断接收. 需要将nRF24L01的接收配置为中断模式, 这样只有在遥控端发出指令时, 小车才做相应的动作, 相比在循环中检测接收信息并调整输出的实现方式更及时高效.
  2. PWM输出控制小车的速度和方向.
  3. 将接收得到的X轴Y轴向量, 映射到两路电机的方向和强度.

涉及的技术名词: UART, TIMER, EXTI, SPI, PWM
以下具体说明

nRF24L01的中断接收

这部分需要在STM32上新增一个EXTI中断源, 映射到nRF24L01的IRQ PIN脚. 这个中断是低电平触发, 注意在处理完中断后, 需要清空接收缓冲, 不然下一次还会读到旧值.
中断处理的方法内根据接收到的数值调整PWM输出, 实现遥控功能.

这里还有一个定时器TIM3, 当前设置的定时时间为0.5秒, 每次中断处理时会将定时器初始化, 在定时器经过0.5秒后触发时, 会将PWM输出归零, 归零后电机都会停止. 通过这个机制, 在遥控器发出指令后小车会在当前指令下输出PWM 0.5秒, 如果持续收到指令则持续输出, 如果未收到指令, 则在0.5秒后停止输出, 体现在小车运动上, 就是每次指令下小车会移动0.5秒.

PWM输出控制速度和方向

PWM的频率选择: 48:1减速电机是淘宝上最便宜常见的减速电机, 最佳PWM频率是25Hz-50Hz. 这个频率的来源在这里, 里面有很详细的说明和实验测试结果. 我把我关心的部分内容翻译了一下, 可以看这里. 我在实际使用中观察到的结果是符合这篇文章的结论的.

这里多说几句. 关于电机的PWM频率选择, 在网上查了很久, 得到的结果大部分是错误的, 很多人文章里写的频率是6-20KHz. 这里需要注意区分一下, 如果你用的是直流有刷电机, 那么用这么高的PWM频率是会出问题的, 建议在几十到几百Hz的范围去测试.

PWM控制速度比较好理解, 但是控制方向的具体实现需要通过两个PWM配合. 尝试过通过1路PWM+1路GPIO进行方向切换, 但是无法正常工作, 最后还是要通过两路PWM. 根据方向, 设置其中一路PWM输出为0. 这里为了避免出现双高电平(网上有很多人提到双高导致L9110s烧毁), 在程序中先设置输出为0的一路PWM, 再输出另一路不为0的PWM.

X轴Y轴向量映射到左右两路电机

这一块花了我一些时间. 在网络上找到的资料看, 实现方式更多是通过Y轴计算出左右电机整体的前进后退占空比, 然后通过X轴计算左右电机占空比差值, 再将这两个结果叠加, 得到最后的左右电机占空比. 这个计算方式的问题是当工作点在Y轴区间两端的时候, 此时叠加的差值会使Y轴的值超出区间, 但是实际上这个数值是不可能的, 所以要么将两个通道的数值都往回拉, 要么就忽略Y轴超出区间的部分, 都不是很合理.

我使用的计算方式, 是先规定摇杆圆周4个方向上对应LR通道的值:

将摇杆得到的XY轴的值做成向量, 将这个向量投影为圆周上某一点, 再根据圆周上这个点两端的值计算当前点的LR值.

因为摇杆得到的XY轴空间, 实际上是一个正方形, 将其映射到圆上时, 有一个有趣的现象, 当角度位于0°到45°时, 向量的长度等于X轴的值, 而在45°到90°时, 向量长度等于Y轴的值, 这个使得计算简便了许多.

遇到的问题

L9110s发热烧毁

电源为两节18650, 电压为3.7x2=7.4V, 两路pwm输出, 当从0,0 -> 0,全速时, 电机无动作, L9110s发烫然后冒烟烧毁. 这个直接导致两个模块各烧了一片L9110s. 于是上网查相关的资料

相关的讨论

因为模块已经带了输出电容和上拉电阻, 所以
可能的原因是

  1. 电机启动电流过大导致模块烧毁. 电机静态电阻为6.5Ω, 电压7.4V时电流超过1A,
    应对方案: 串联一个5Ω的限流电阻, 可以将电流降到7.4/(6.5+5)=0.64A, 避免超出L9110s的最大电流, 运转中的电机阻抗为40Ω - 45Ω, 此时电阻上的分压不到1V, 影响不大.
  2. L9110s耐压超限. 有人说最高到6.5V.
    应对方案: 在L9110s输入电压前串联2个1N4007, 将电压降到7.4-1.4=6V, 串联2个时,启动电流1A,正向电阻0.7Ω, 空转时0.15A,正向电阻5Ω
  3. PWM频率过高. 过高的PWM频率会导致电机在低占空比时无法启动,
  4. PWM同时输出高电平

最终解决方案

  1. 串联两个1N4007将电压降到6.2V
  2. PWM频率降到100Hz

有些占空比下电机不动

在逐渐增大占空比的过程中, 有些值下电机不转, 能听到吱吱声, 如果手摸着L9110s芯片, 能感觉到此时有一阵发烫, 所以此时电流到位了, 但是没能驱动电机.

这个原因和前一个问题是一样的, 因为PWM频率过高(17.5KHz), 无法驱动电机, 在将频率降到100Hz后这个问题就没再出现.

小车在运行一段时间后中断灯常亮, 失去响应

经过检查, 是因为在处理nRF24L01接收中断时, 加入了一个延时1ms的处理, 会卡在这个延时函数上, 将这个延时处理删除后就未再出现这个情况

参考

标签:输出,摇杆,电机,nRF24L01,调速,PWM,L9110s,STM32F401
来源: https://www.cnblogs.com/milton/p/15087381.html