当前位置:   article > 正文

esp-12f单片机无线控制无刷电机,解锁BLHeli_S电调电机保护,BLHeli_S电调建立Keil工程。

blheli_s

由于项目上需要用到无刷电机,一般的无刷电机驱动器又大又不方便,所以最后选择了航模上使用的无刷电调,当时只是刚好看到BLHeli_S电调,就直接下单了。

使用电调控制无刷电机,最大的问题就是电机保护和油门行程校准。第一,单片机在控制电调驱动无刷电机的时候就需要跳过电机保护;第二,油门行程校准由于不同的协议没有具体的介绍,手上又没有遥控器和飞控,光靠单片机算法模拟一个值一个值来试是很难的。

一开始我是用单片机定时器试,后面买了个pwm测试电调的模块,完全适配BLHeli_S电调,用示波器发现调速很简单,就是50hz的1ms高电平3s左右就解锁电机保护,1-2ms高电平代表最小油门和最大油门。

 

一、让BLHeli_S电调控制无刷电机动起来

使用单片机连接BLHeli_S电调,白色PWM信号线,黑色为信号端接地校准。

电调连接电池和无刷电机,电调买的时候会介绍支持的电池,我的支持2S-6S(1S代表串联一块3.7V电池),我用的3S电池(11.1V),红接电池正极,黑接电池负极,无刷电机三相没有顺序随便接到电调。

 因为需要用到无线功能,单片机我使用的是esp-12F和Arduino开发,代码如下,记得改WIFI名字和密码。其他的单片机也是一样的,都是模拟遥控器关闭电机保护控制电机。这里用的是定时器,换成20ms循环delayMicroseconds( us );//微秒级延时函数电机控制会更平滑,这主要是analogWrite(pin,i)//i在0-255之间,高电平时间对应数字大小从低到高,对于1-2ms需要千分度的油门来说调节精度不够,但是如果想单片机控制无刷电机又要做其他事情,就只能用这个定时器了。

  1. #include <ESP8266WiFi.h>
  2. #include <WiFiUdp.h>
  3. #define motor0 2 //GPIO2
  4. const char ssid[] = "Redmi K40"; // your network SSID (name)
  5. const char pass[] = "12345679"; // your network password
  6. WiFiUDP Udp;
  7. unsigned int localPort = 2380;
  8. char incomingPacket[255];
  9. float rd = 0;
  10. int Data_length;
  11. void setup()
  12. {
  13. Wire.begin();
  14. Serial.begin(115200);
  15. WiFi.begin(ssid, pass);
  16. while (WiFi.status() != WL_CONNECTED)
  17. {
  18. delay(500);
  19. Serial.print(".");
  20. }
  21. Serial.println(WiFi.localIP());
  22. Udp.begin(localPort);//启动UDP监听本地端口
  23. pinMode(motor0, OUTPUT);
  24. digitalWrite(motor0, LOW);
  25. analogWrite(motor0, 13);
  26. }
  27. void loop()
  28. {
  29. Data_length = Udp.parsePacket(); //获取接收的数据的长度
  30. if (Data_length) //如果有数据那么Data_length不为0,无数据Data_length为0
  31. {
  32. int len = Udp.read(incomingPacket, 255); //读取数据,将数据保存在数组incomingPacket中
  33. if (len > 0) //为了避免获取的数据后面乱码做的判断
  34. {
  35. incomingPacket[len] = 0;
  36. }
  37. Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //准备发送数据到目标IP和目标端口
  38. Udp.print("Receive data:"); //将数据receive data:放入发送的缓冲区
  39. if (len == 1) { rd = int(incomingPacket[0]) - 48; }//一位数控制速度
  40. Udp.println(rd); //将接收到的数据放入发送的缓冲区
  41. Udp.endPacket(); //向目标IP目标端口发送数据
  42. }
  43. analogWrite(motor0, 13+rd);//13-25,13解锁,25最大速度
  44. }

白线接GPIO2,黑线接GND。接好线后,需要先在Arduino标签栏->工具->串口监视器,看串口管理器的回复IP。

然后打开NetAssist(串口调试助手),连接同一WiFi,选择UDP协议,随便使用一个本地主机端口,打开端口,在远程主机里输入你刚刚看到的回复IP:2380,并且发送一个数字看能否收到回复。

收到回复后,在窗口发送的数字就是可以调节的50Hz的PWM波高电平时间。

默认高电平时间是1ms,因为解锁BLHeli_S电调的电机保护就是高电平1ms。

上电单片机后,连接电调,当听到嘀、嘀、嘀(3S电池响3声短),然后滴(短),滴~(稍长的一声),电机解锁成功。在窗口输入个位数1-9,电机就可以进入转速工作模式,输入0停止。

如果需要精确控制,下面这里代码控制速度更加精确。

  1. #include <ESP8266WiFi.h>
  2. #include <WiFiUdp.h>
  3. #define motor0 2 //GPIO2
  4. const char ssid[] = "Redmi K40"; // your network SSID (name)
  5. const char pass[] = "12345679"; // your network password
  6. WiFiUDP Udp;
  7. unsigned int localPort = 2380;
  8. unsigned int sendport = 2390;
  9. char incomingPacket[255];
  10. float rd = 0;
  11. int Data_length;
  12. void setup()
  13. {
  14. Wire.begin();
  15. Serial.begin(115200);
  16. WiFi.begin(ssid, pass);
  17. while (WiFi.status() != WL_CONNECTED)
  18. {
  19. delay(500);
  20. Serial.print(".");
  21. }
  22. Serial.println(WiFi.localIP());
  23. Udp.begin(localPort);//启动UDP监听本地端口
  24. pinMode(motor0, OUTPUT);
  25. digitalWrite(motor0, LOW);
  26. analogWrite(motor0, 13);
  27. }
  28. void loop()
  29. {
  30. Data_length = Udp.parsePacket(); //获取接收的数据的长度
  31. if (Data_length) //如果有数据那么Data_length不为0,无数据Data_length为0
  32. {
  33. int len = Udp.read(incomingPacket, 255); //读取数据,将数据保存在数组incomingPacket中
  34. if (len > 0) //为了避免获取的数据后面乱码做的判断
  35. {
  36. incomingPacket[len] = 0;
  37. }
  38. Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //准备发送数据到目标IP和目标端口
  39. Udp.print("Receive data:"); //将数据receive data:放入发送的缓冲区
  40. if (len == 1) { rd = int(incomingPacket[0]) - 48; }//一位数控制速度
  41. Udp.println(rd); //将接收到的数据放入发送的缓冲区
  42. Udp.endPacket(); //向目标IP目标端口发送数据
  43. }
  44. delayMicroseconds(19000-rd*100);
  45. digitalWrite(motor0,LOW);//管脚写入函数
  46. delayMicroseconds(1000+rd*100);
  47. digitalWrite(motor0,HIGH);//管脚写入函数
  48. }

二、Keil使用BLHeli_S电调工程

多次尝试之后,发现就使用航模的电调和自己的工程完全不匹配,如果不想自己做无刷驱动,又想直接用上无刷驱动电调,那就只能编程了。

在网上也搜了关于BLHeli_S电调的Keil工程,但是发现资料很少,这里主要参考此博主的文章,然后说一下自己遇到的坑。

原文链接:https://blog.csdn.net/qq_41100189/article/details/119832506

按照博主的内容,去keil官网填一下几个空,就可以下载软件C51V961.EXE,在github下载BLHeli_S工程源代码,BLHeli_S /SiLabs文件夹里所有文件就是源代码。

Github下载代码时,压缩包解压总提示不可预料的压缩末端,下多次也是一样,没办法,新建文件BLHeli_S.asm用记事本把网页上的4000行代码全部粘贴进去,效果是一样的。

我看了自己电调芯片型号为EFM8BB21F16G,然后数了电调上引脚数20,那就是和博主一样的EFM8BB21F16G-QFN20。

至于引脚方案怎么确定是哪个?我是看了电调引脚接线和芯片引脚图的,我的电调接线方案就是J_,估计大部分BLHeli_S电调都是。

 keil新建工程并选择此芯片,只导入了BLHeli_S.asm,按照博主更改代码取消3处注释,这里代码已经有区别了。

ESCNO EQU J_

MCU_48MHZ EQU  2

FETON_DELAY EQU 50

一点编译,很多错误。

看了一下代码,Github的代码已经更新了,和原来博主下载到的代码不一致,而找Github历史版本又不确定是哪一版,没办法自己改最新版代码的报错,最后如下导入5个文件,下载不了就新建文件复制代码保存效果一致。

 由于只需要用到J.inc的引脚定义,删除所有其他硬件类型判断,例如

IF ESCNO == A_
$include (A.inc)    ; Select pinout A
ENDIF

然后就可以编译成功。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/453235?site
推荐阅读
相关标签
  

闽ICP备14008679号