Arduino获取商业遥控器(如天地飞等)PWM信号的例子

如果我们做了一个小的创意作品,而它需要远距离的无线控制,比如遥控车、遥控航模、遥控船等,这时候我们必定会认真考虑如何实现无线控制这个问题。蓝牙、WiFi、ZigBee、NRF、HC-12等都可以,但是也都不同程度上存在一定的弊端,而且使用以上几种方式都得另外制作一个遥控器实体,既然如此那么为什么不考虑直接使用成熟的商业遥控器呢?比如便宜好用的天地飞、高端的Futaba等。它们自身就是一个成熟的遥控器,有两个遥杆,至少四路信号输出,千米级的稳定传输,一切看来似乎都是这么美好!但问题是如何接收到并解析出它们所发出的信号呢?下面就来解决一下这个问题!
首先得了解一下遥控器的基本常识,就是遥控器和接收机之间有自己的通信协议,这个协议各个遥控器厂商都有自己的一套标准而且之间互不兼容,但是接收机输出的信号却有较为统一的标准,常见的有PWM、PPM、各种.bus(比如Futaba的s.bus),这里面最简单的自然就是PWM了,接收机的每个引脚单独输出一路PWM信号,发送给执行器或者飞控,在固定翼航模上面通常都是直接发给执行器(舵机、电调等),实现对它们的直接控制。
PWM是一种高低电平信号,通过高电平的持续时间(脉冲宽度)来传输信息,在遥控器上这个脉冲宽度通常大约是1000-2000毫秒,电调和舵机接收的信号范围通常也是1000-2000毫秒。那么如何使用Arduino来获取到这个脉冲宽度呢?这就要用到Arduino的外部中断了(当然单片机系统都有中断功能),通过两次中断事件发生的时间间隔来获取脉冲宽度。解决了这个问题,那么就可以使用遥控器去控制航模、车模、船模了!(令人愉快的事情又多了一件!)

下面是Arduino MEGA获取天地飞7遥控器信号并发给电调和舵机来控制航模的一段代码:

#include <Servo.h>
#define forward_back_pin            19 //2通道
#define left_right_pin              20 //1通道
#define power_pin                   21 //3通道
//中断引脚编号
#define forward_back_int_pin        4
#define left_right_int_pin          3
#define pow_int_pin                 2
//4路舵机和1路电调的引脚
#define forward_back_servo_pin1     8
#define forward_back_servo_pin2     9
#define left_right_servo_pin1       10
#define left_right_servo_pin2       11
#define pow_servo_pin               12

Servo forward_back_servo1;          
Servo forward_back_servo2;    
Servo left_right_servo1; 
Servo left_right_servo2;
Servo pow_servo; 

int power_val=0,forward_back_val=0,left_right_val=0;
unsigned long timer1=0,timer2=0,timer3=0;

void setup() {
  Serial.begin(115200);
  
  pinMode(power_pin,INPUT);
  pinMode(left_right_pin,INPUT);
  pinMode(forward_back_pin,INPUT);
  //注册中断函数
  attachInterrupt(pow_int_pin,power,CHANGE);
  attachInterrupt(forward_back_int_pin,forward_back,CHANGE);
  attachInterrupt(left_right_int_pin,left_right,CHANGE);
  
  pow_servo.attach(pow_servo_pin,1000,2000);
  forward_back_servo1.attach(forward_back_servo_pin1,1000,2000);
  forward_back_servo2.attach(forward_back_servo_pin2,1000,2000);
  left_right_servo1.attach(left_right_servo_pin1,1000,2000);
  left_right_servo2.attach(left_right_servo_pin2,1000,2000);
}

void loop() {
//   Serial.println("!!!!!!!!!!!!!!!!!" );
//   Serial.println("Pulse Value Is : ");
//   Serial.print("power:");
//   Serial.println(power_val);
//   Serial.print("left_right:");
//   Serial.println(left_right_val);    
//   Serial.print("forward_back:");
//   Serial.println(forward_back_val);
//   Serial.println("!!!!!!!!!!!!!!!!!" ); 
//   delay(1000);

   pow_servo.write(power_val);
   turn();
   fly();
     
}

void turn(){
  
  left_right_servo1.write(left_right_val);
  left_right_servo2.write(left_right_val);
}
void fly(){
  
  forward_back_servo1.write(3000-forward_back_val);
  forward_back_servo2.write(forward_back_val);
}
//油门信号中断函数
void power(){
  
  if(digitalRead(power_pin)==HIGH){
    timer1=micros();
  }
  else{
    power_val=micros()-timer1;
  }
}
//前后舵量信号中断函数
 void forward_back(){
  
   if(digitalRead(forward_back_pin)==HIGH){
      timer2=micros();
   }
   else{
     forward_back_val=micros()-timer2;
   }
 }
//左右多量信号中断函数
 void left_right(){
  
   if(digitalRead(left_right_pin)==HIGH){
      timer3=micros();
   }
   else{
     left_right_val=micros()-timer3;
   }
 }
  • 10
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值