美文网首页arduino玩转Arduino我爱编程
[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机

作者: 鸿鑫在简书 | 来源:发表于2017-09-15 23:47 被阅读162次

    今天我们来论如何上天。

    也许我们想飞得更高,看得更远

    或是打造一款澎湃动力的电动漂移板:

    那我们总离不开用单片机控制电机。

    那么,arduino控制电机跟arduino通过电调控制电机区别在哪儿呢?

    前者,控制小电机是比较容易的。然而对于四轴和电动滑板,电压太高烧主板!
    由于电池电压过高(四轴无人机电压14.1V,电动漂移板28.8V),若是直接连接单片机,会烧坏。
    这个时候便需要连接电调(speed controler)作为中转桥梁。

    问题就是,电机连上电调后,就不受单片机直接控制了。电调就像是一位机场的安检员,只有“说服”安检员,让安检员传话给电机,电机才会动。

    那怎么样用Arduino “说服” 电调呢?

    Arduino控制高电压的四轴电机需要电调,然而坑爹的是电调默认校准方式是实体遥控器校准,电调说明书上并没写关于单片机与软件控制的方法,且目前网上搜集到的这方面教程比较散乱。

    因此这篇文章的目的就是,一条龙解决Arduino连接电调控制电机。也就是让这小家伙通过Arduino而不是实体遥控器转起来,这样可以为自己用手机app遥控(一个实体遥控器几百呢)、电脑控制和以后其自主编程控制提供方便。


    claim:standing on the shoulders of the giants

    接下来以四轴无人机电机为例,电动滑板轮毅电机同理

    要点:
    1.电路连接方式
    2.PWM控制
    3.电调初始化
    4.转速的有效信号区间查找
    5.Wifi遥控时Arduino中 Serial.read() 的char转换为 速度的 int
    5.过渡与渐变

    材料
    四轴20A电调 1
    四轴2212电机 1
    4S电池或直流电源 1
    连接 若干

    若电机有报障声音,请参考电调故障申明

    值得注意的是,声音是从电机上发出来的,并不是电调。

    其次,电机的声音能给我们提供非常多的反馈信息。

    准备就绪后,电机没有声音又没有转动,说明电路未连接正确或电压不够(要大于7V)。

    1.连接方式

    电路连接方式

    总的来说,就是:电源连电调,电调的电源线连电机+电调的信号线连arduino(接有“~”标记的7)

    一张图搞定(只不过这里的接收机为Arduino):

    电调与arduino连接时,因为电调有自动低压保护措施,记得要保证电源电压大于7V,才能正常激活电调!否则什么反应都没有。

    有电池的同学用电池,当然电池什么的相比,还是可直接调压的直流电源更方便。

    7V以上电压才能激活

    2.电调初始化

    这电调可高级了,内置独立的程序和连接马达的报错程序。

    最关键的是,电调首次使用,没调制好油门行程,也是不能驱动电机的。想要首次激活电调,就要在Arduino上说一样的“暗号”,也就是模仿实体遥控器的程序走一遍。

    说明书上关于实体遥控器校准的方法是这样的:

    于是,我们需要模拟设置油门行程。

    模拟设置油门行程代码如下,直接刷入Arduino等待几秒,若电调发出滴滴声音后开始转动,表示已激活(正常使用时只需要激活一遍,当然重复激活也不影响):

    int sp1=9;//定义舵机接口数字接口7
    int pulsewidth;//定义脉宽变量
    int val;
    int val1;
    int myangle1;
    //下面是servopulse函数部分(此函数意思:也就是說每次都是0.5ms高電平 1.98ms低電平 然後再0.52ms低電平 17ms延時也是低電平)
    void servopulse(int sp1,int val1)//定义一个脉冲函数
    {
      myangle1=map(val1,0,180,500,2480);
      digitalWrite(sp1,HIGH);//将舵机接口电平至高
      delayMicroseconds(myangle1);//延时脉宽值的微秒数
      digitalWrite(sp1,LOW);//将舵机接口电平至低
      delay(20-val1/1000);
    }
    //servopulse函数部分到此结束
    void setup()
    {
      pinMode(sp1,OUTPUT);//设定舵机接口为输出接口
      //设置两组串口波特率
      Serial.begin(9600);
      
      Serial.println("servu=o_seral_simple ready" ) ;
      
      //看电调说明书,设置油门行程时,一开始需要把遥控器打到最高点。i<=110大概是2杪多
      for(int i=0;i<=110;i++)
        {
          servopulse(sp1,150);//引用脉冲函数
        }
        
    //等电机发出B-B两声后(就是两秒后,大概就是这里了)把油门打到最低点
        for(int i=0;i<=55;i++)
        {
          servopulse(sp1,20);//引用脉冲函数
        }
        
    //后面提示后,就可以控制电机转动了
        for(int i=0;i<=150;i++)
        {
          servopulse(sp1,150);//引用脉冲函数
        }
        
        Serial.println("hello world" ) ;
      
    }
    
    void loop()
    {
        Serial.print(val1,DEC);
        Serial.println();
        for(int i=0;i<=50;i++)//给予舵机足够的时间让它转到指定角度
        {
          servopulse(sp1,val1);//set the speed
        }
      }
    
       }
    
    

    设置好了之后,电机终于转起来了!若是正常使用,以后就不需要再次校准了。

    但是,我们若在初始速度信号不等于0时启动了电机,电调就会报错,我们需要重新刷入这个程序进行一遍校准。

    3.寻找速度的有效信号区间

    校准后,我们就想控制速度了。下面刷入正式的代码,以调速:

    int sp1=9;//定义舵机接口数字接口7
    int pulsewidth;//定义脉宽变量
    int val;
    int val1;
    int speed1=0;
    int myangle1;
    
    
    
    //下面是servopulse函数部分(此函数意思:也就是說每次都是0.5ms高電平 1.98ms低電平 然後再0.52ms低電平 17ms延時也是低電平)
    void servopulse(int sp1,int val1)//定义一个脉冲函数
    {
      myangle1=map(val1,0,180,500,2480);
      digitalWrite(sp1,HIGH);//将舵机接口电平至高
      delayMicroseconds(myangle1);//延时脉宽值的微秒数
      digitalWrite(sp1,LOW);//将舵机接口电平至低
      delay(20-val1/1000);
    }
    //servopulse函数部分到此结束
    void setup()
    {
      pinMode(sp1,OUTPUT);//设定舵机接口为输出接口
      //设置两组串口波特率
      Serial.begin(9600);
      
      Serial.println("servu=o_seral_simple ready" ) ;
        
        Serial.println("hello world" ) ;
    
    }
    
    void loop()
    {
          String inchars="";
      while(Serial.available()>0)
      {
        char inchar=Serial.read();
        if(isDigit(inchar))
        {
          inchars+=inchar;
        }
          speed1=inchars.toInt();
      }
    
    
    Serial.println(speed1);
    
    
        
        for(int i=0;i<=50;i++)//给予舵机足够的时间让它转到指定角度
        {
          servopulse(sp1,speed1);//引用脉冲函数
        }
      
    
    }
    

    我们知道,arduino的PMW功能其实是通过构造不同电压和时间,利用W=P*T来调控功率(速度)的。

    我们首先来看一下这个脉冲函数的构造:

    电调PMW信号构造

    Arduino可以发出的PMW的范围是非常宽的,高达over 2000Hz,而我手上这款电调最高只能识别600,因此会被电调识别为无信号输入,产生报警。我们需要不断设置电调速度值,探索出有效信号区域。

    于是,构造电调可以识别的PMW信号,代码如下:

    int sp1=9;//定义舵机接口数字接口7
    int pulsewidth;//定义脉宽变量
    int val;
    int val1;
    int speed1=0;
    int myangle1;
    
    void servopulse(int sp1,int val1)//定义一个脉冲函数
    {
      myangle1=map(val1,0,180,500,2480);
      digitalWrite(sp1,HIGH);//将舵机接口电平至高
      delayMicroseconds(myangle1);//延时脉宽值的微秒数
      digitalWrite(sp1,LOW);//将舵机接口电平至低
      delay(20-val1/1000);
    }
    

    构造好后,开始试探出识别的有效区间。简单来说,用二分法,在电压7V以上的条件下,找出min和max。

    一般来说,min<50,max<200。我的电调很快通过二分法试出有效信号范围是[27,163];

    这个时候,我们通过改变speed1的值,加上这条命令

          servopulse(sp1,speed1);//set the speed
    

    就已经可以改变电机速度了。

    直流电源上电压缓缓调高

    Hhh,小心螺旋桨割到手,打开Arduino的Serial.命令台,输入一个有效区间内的速度,比如31,电源电压调起,感受风声吧~

    4.Wifi遥控中读取到的String型速度转换为int型

    可以改变速度后,我们想着怎样遥控接收更改的速度值。不论是蓝牙还是wifi遥控,都离不开Arduino中Serial.available 和Serial.read() 帮助我们获取和读取我们输入的速度值。问题就是,我们接收到的是String,是不能够speed=(int)String的

    这个时候,我么需要把String转化为int。可是怎么转化呢,由于获取信号这个本身就涉及到函数调用,在调用过程中试图改变类型是非常难的,于是我们从result想办法。找了很久终于找到了:

    将接收到的速度信号转化为int值 代码有:

    void loop()
    {
          String inchars="";
      while(Serial.available()>0)
      {
        char inchar=Serial.read();
        if(isDigit(inchar))
        {
          inchars+=inchar;
        }
          speed1=inchars.tolnt();
      }
    

    记得清空 String要在每一个loop之前,而赋值要等到有新值输入后。

    转化为int后,就可以设置电调速度了

    speed1=inchars.tolnt();
    servopulse(sp1,speed1);//set the speed
    

    这个时候,我们已经具备了电脑、手机遥控电机速度的能力,甚至乎可以自己写app或用已有的app进行控制,如TCP连接;

    6.平滑速度变化(可选)

    我们改变电机速度的值,比如从10%到90%的时候,若是太快,电机会来不及变化,产生暴增或暴减,后果就是 无人机忽上忽下,或是电动滑板加速太快人仰马翻;若是太慢,会出现控制迟缓。因此,我们需要平滑速度变化。

    延时函数
    线性速度增长函数。

    曲线函数
    想要速度变得更加平滑的,比如先慢后快,可以用数学建模 弄一个过渡函数,比如(ax^2+bx+cx) or (a^x),然后再把值赋给speed1.

    好,至此为止,我们已经能够用Arduino连接电调控制无刷电机,甚至通过wifi进行遥控
    这意味着我们具备了arduino驱动电机的基础,加上自己编写或应用手机软件,将在四轴无人机飞行和电动滑板上大显神通。

    最后,愿大家都能做出像航模协会大神那样DIY的成品:

    Good luck!_

    欢迎关注/交流讨论~


    参考资料:

    1.Arduino控制好盈电调

    2.Arduino 编程入门到实战(PWM部分)

    3.Arduino串口数据分割字符串和数字

    4.单片机控制无刷电机转速——Arduino篇(详细代码)

    5.Make: Drones: Teach an Arduino to Fly

    相关文章

      网友评论

        本文标题:[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机

        本文链接:https://www.haomeiwen.com/subject/hisxrxtx.html