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

今天我们来论如何上天。

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第1张图片

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第2张图片

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

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

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

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

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

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

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第3张图片

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
连接 若干

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第4张图片

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

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

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

1.连接方式

电路连接方式

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

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第5张图片

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

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第6张图片
7V以上电压才能激活

2.电调初始化

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

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

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第7张图片

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

模拟设置油门行程代码如下,直接刷入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来调控功率(速度)的。

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第8张图片
电调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

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第9张图片
直流电源上电压缓缓调高

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%的时候,若是太快,电机会来不及变化,产生暴增或暴减,后果就是 无人机忽上忽下,或是电动滑板加速太快人仰马翻;若是太慢,会出现控制迟缓。因此,我们需要平滑速度变化。

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

[Maker]不握遥控器?Arduino+电调控制四轴飞行器电机_第10张图片

曲线函数
想要速度变得更加平滑的,比如先慢后快,可以用数学建模 弄一个过渡函数,比如(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+电调控制四轴飞行器电机)