基于Arduino环境开发小型遥控气垫船-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 5400|回复: 3

基于Arduino环境开发小型遥控气垫船

[复制链接]
发表于 2019-6-10 12:04 | 显示全部楼层 |阅读模式
前几个月制作了一款基于Arduino的最小板,上面集成了一些功能,经过了几次的迭代后终于达到了我想要的效果,紧接着又为这款电路板制作了一个配套的遥控器,用来操控这块板子上的一些功能,例如电机驱动以及控制一些IO口之类的。这两个项目制作过程都可以从如下的链接找到:自制Arduino最小系统板
自制Arduino遥控器
当时调试完成之后一直就放着落灰了,进来准备使用这套板子来制作一些项目,结合了板子的资源之后,就选择了气垫船的项目,准备用我设计的这套板子制作一个遥控气垫船。
首先话不多说,上完成品照片:


接下来我就会带来整个气垫船的开发,制作过程。

灵感来源
首先我端详了我做的这款板子,上面有三个L9110s电机驱动芯片,以及一个支持1-2s的锂电池接口,一个支持NRF24L01的接口以及报警电路。对于这个L9110s驱动,我使用了几乎arduino的全部支持硬件PWM的管脚,其中有两个驱动芯片是支持正反转PWM调速的,有一个驱动苦于arduino的PWM管脚不够,所以只能支持单向PWM调速,显然这样的配置对于一些小车的项目肯定是绰绰有余,而这也是我设计这块板子的设计初衷,对于一些车船类的项目,这款板子可以完全适应。

所以选择来选择去,还是选择了车船类的项目。但是我对于车船类的项目感觉玩不什么花样,偶然间在网上看到别人3D打印的气垫船项目,就动心了。

想法到图纸
之前玩过一段时间的航模,所以最开始想用空模的那一套东西来做,用无刷电机带动扇叶转动,然后电调可以用arduino输出的PWM波来控制,刚好家里也有3D打印机。但是接着我就发现那我为啥不用arduino nano板来做,因为这么做的话貌似我板子上的功能一个都没用到,简直就是浪费资源,遂放弃。。。。。。

有一天玩那种空心杯的四轴时候,看到四轴的电机体格虽然很小,但是力道却很足,于是想用这个电机来做动力,刚好板子上的驱动芯片应该能带的动。于是上某宝搜索,对比了很多不同型号的空心杯电机之后,选择了720电机,店家还给配了螺旋桨,直径差不多55mm。数天之后,电机到货了,拆开上电之后,感觉风还挺大,比得上一个小电扇了,于是确定了这个动力系统。720电机配55mm螺旋桨。

动力总算是确定了,接下来就是结构的问题,在开始绘制图纸之前,有个很重要的问题要解决——气垫船的转向方式?
于是上百度上查询气垫船的图片,发现大概分为两类,一类是使用单个风扇作为推进,扇叶后方有可动的导流板来控制方向,就是类似船的舵一样,我开始准备用这种的,因为只需要一个电机,感觉比较省电。但是后来查看了详细的结构之后还是放弃了,结果比较复杂,实行起来比较麻烦。另外一类是使用两个或者四个风扇作为推进,使用两侧风扇的速度差来控制船体的方向,这种结构比较简单,而且两测风扇我还可以使用两个支持正反转PWM调速的驱动芯片来驱动,达到速度差调速的目的。

终于是确定了使用的动力以及转向方式,下面就是埋头画图纸了。作为CAD小白,我学习了几节课程之后终于是能勉强画图了。下面是画好的图纸,一共有四页,使用的软件是迅捷的CAD。


整个机身一共有四个电机,两个负责推进两个负责起升,这样刚好用光了我设计板子上面所有的电机接口,后续还想加什么功能的话也有多余的端口来使用。
画好之后,我想能够在电脑上先模拟一下完成之后的样子就好了,于是没有建过模的我又去学了建模,将CAD中画好的图片导入到建模软件之后,经过简单的拉伸操作就得到了大致完成的样子,我用的建模软件是犀牛,刚刚学习,只会简单的几个操作,请各位看官轻拍。

终于是完成了图纸的设计了,导入到建模软件的效果也还满意,于是准备下一步的切割了。

图纸到实物
我在某宝上找了个加工KT板的厂家,将图纸发过去了。之前确实考虑过使用木板,但是轻木太软,桐木太脆,椴木太重,权衡下来还是切kt板,因为之前玩航模确实很多飞机都是用KT板做的,很结实也很轻。
等待了几天之后,切割好的kt板送到了,查看了一下,没有问题,由于切割KT板的时候切割机会烧灼KT板的边缘导致一些尺寸会对不上,幸好我在设计图纸的时候预留了一些余量,这点也提醒大家注意。
随后急忙的组装了起来,这时候门铃响了,原来是买的电机到货了。正好赶上组装,于是迅速的安装上了电机,成品如下:
下面就是安装我设计的电路板了,设计图纸时给气垫船设计了一个设备舱,正好可以容纳电路板。
电路板装进去,将电机插头插到板子上,到这里所有的结构搭建以及硬件电路都连接好了,下面就是给气垫船注入灵魂——编写代码了!
程序的编写

其实控制程序非常简单,首先说接受端,其实就是将无线模块接收到的数据转换成对应引脚输出的PWM占空比来控制电机的转速。于是一段时间过后,我编好了接受端的代码。
[mw_shl_code=arduino,true]//接收端程序

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

unsigned int value;
unsigned int CH1,CH3,left,right,qi;
void setup()
{
  Serial.begin(9600);
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();

  Mirf.setRADDR((byte *)"FGHIJ"); //设置自己的地址(接收端地址),使用5个字符
  Mirf.payload = sizeof(value);   
  Mirf.channel = 90;   //设置使用的信道
  Mirf.config();
  Serial.println("Listening...");  //开始监听接收到的数据

  pinMode(10,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(9,OUTPUT);
  digitalWrite(5,0);
  digitalWrite(6,0);
  digitalWrite(9,0);
  digitalWrite(3,0);
  digitalWrite(10,0);
}

void loop()
{
  if(Mirf.dataReady()) {  //当接收到程序,便从串口输出接收到的数据
    Mirf.getData((byte *) &value);

    CH3=(unsigned int)value&255;
    CH1=(unsigned int)value>>8;
   

    if(CH1>140)
    {
       qi=CH1;
       if(CH3>135)       //左转弯
       {
         right=CH1;
         
         if(CH1<CH3)     
           left=0;
         else
           left=CH1-CH3/3.5;
       }
       else if(CH3<120)    //右转弯
       {
         if(CH1<(255-CH3))
           right=0;
         else
           right=CH1-((255-CH3)/3.5);
           
         left=CH1;
       }
       else
       {
         right=CH1;
         left=CH1;
       }
    }
    else
    {
      left=0;
      right=0;
      qi=0;
    }
   
    analogWrite(3,left);
    analogWrite(9,right);
    analogWrite(10,qi);

    Serial.print("Got data: ");
    Serial.print(CH1);
    Serial.print(" ");
    Serial.print(CH3);
    Serial.print(" ");
    Serial.print(left);
    Serial.print(" ");
    Serial.println(right);
  }
}
[/mw_shl_code]
发送端也是很简单,我使用摇杆作为控制杆,用arduino的ADC引脚读取摇杆输出的电压来获得当前的摇杆位置,然后将摇杆位置的数据通过无线模块发送出去。
[mw_shl_code=arduino,true]//发射端程序

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

unsigned int value,value1;
unsigned int data;

unsigned int CH1,CH3;
void setup()
{
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"ABCDE"); //设置自己的地址(发送端地址),使用5个字符
  Mirf.payload = sizeof(value);
  Mirf.channel = 90;              //设置所用信道
  Mirf.config();

  Serial.begin(9600);
}

void loop()
{
  Mirf.setTADDR((byte *)"FGHIJ");           //设置接收端地址
  value = analogRead(1);                      //0-255的随机数
  value1 = analogRead(6);

  CH1=value/4;
  CH3=value1/4;

  data=((unsigned int)(CH1<<8)+CH3);
  Serial.print(CH1);
  Serial.print(" ");
  Serial.print(CH3);
  Serial.print(" ");
  Serial.println(data);
  //Serial.println(value1);
  Mirf.send((byte *)&data);                //发送指令,发送随机数value
  while(Mirf.isSending()) delay(1);         //直到发送成功,退出循环
  delay(10);
}
[/mw_shl_code]
下载程序到气垫船和遥控器中:
上电!我使用的电池是550mah的3.7v锂电池,带这四个电机大概可以玩10分钟的时间。于是》》》迫不及待的上电开始玩耍!!


需要的一些改进

在玩耍中发现由于气垫船的阻力非常小(几乎不和地面接触),所以推进电机要是速度不一样就会导致气垫船偏航,但是由于驱动芯片的误差以及电机之间的误差问题,即使我使用相同占空比的PWM方波驱动他们,仍然会导致他们转速不同以致气垫船容易偏航(很难跑直线),这个问题比较影响玩耍的体验感,需要改进。
计划是使用一个电子罗盘,也就是磁力计来确定现在气垫船船头的指向,然后引入PID算法来通过电子罗盘的数据来校正控制每个推进电机的PWM波,这样应该会改善到整体的操控性。
不过这有需要一段时间的研究,主要是软件方面,现在板子上预留了IIC的通信接口,想必找到一个IIC通信的电子罗盘应该不是什么难事,问题就在PID算法以及一些滤波算法上,我还对PID算法不太了解。而且是否运转的电机或者电机内的磁铁会对电子罗盘的数据产生干扰也不是很确定。                           
成功的让这个气垫船跑起来达到了我的目的,对于 其的一些改进应该会放在之后,应为近期准备开始做室内玩的遥控飞机的板子,是基于51和LT8920的,所以这个改进应该会等到做完那个项目之后。如果你对这个气垫船有什么改进的建议,欢迎提出来。

发表于 2020-10-28 11:28 | 显示全部楼层
为什么我看不到图片    只有我是这样的吗
发表于 2021-2-24 21:36 | 显示全部楼层
楼主,图裂了么,嘛都看不到
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-1 05:51 , Processed in 0.101358 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表