单片机解码PPM信号
遥控器发射机、接收机原理
每个通道信号脉宽0~2ms,变化范围为1~2ms之间。1帧PPM信号长度为20ms,理论上最多可以有10个通道,但是同步脉冲也需要时间,模型遥控器最多9个通道。
PPM格式
只连接了通道3(油门)
arduino要测量脉宽时间很简单。有专门的库函数pulseIn( )。问题在于这个库函数使用查询方式,程序在测量期间一直陷在这里,CPU利用率太低。因此下面代码采用中断方式,效率很高。
代码参考:http://arduino.cc/forum/index.php/topic,42286.0.html
ARDUINO 代码复制打印
//read PPM signals from 2 channels of an RC reciever
//http://arduino.cc/forum/index.php/topic,42286.0.html
//接收机两个通道分别接arduino的数字口2、3脚
//Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3).
//The Arduino Mega has an additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 (pin 18).
intppm1 =2;
intppm2 =3;
unsignedlongrc1_PulseStartTicks,rc2_PulseStartTicks;
volatileintrc1_val, rc2_val;
voidsetup(){
Serial.begin(9600); //PPM inputs from RC receiver pinMode(ppm1,INPUT); pinMode(ppm2,INPUT); // 电平变化即触发中断 attachInterrupt(0, rc1, CHANGE); attachInterrupt(1, rc2, CHANGE); }
voidrc1()
{
// did the pin change to high or low? if(digitalRead(ppm1)==HIGH) rc1_PulseStartTicks =micros(); // store the current micros() value else rc1_val =micros()- rc1_PulseStartTicks; }
voidrc2()
{
// did the pin change to high or low? if(digitalRead(ppm2)==HIGH) rc2_PulseStartTicks =micros(); else rc2_val =micros()- rc2_PulseStartTicks; }
voidloop(){
//print values Serial.print("channel 1: "); Serial.print(rc1_val); Serial.print(" "); Serial.print("channel 2: "); Serial.println(rc2_val); }
上述代码每个通道都要占用一个中断口。但是一般的Arduino只有数字口2、3具有中断功能,也就是说只能接两个通道。如果想使用更多的通道,就需要用mega了,mega有5个外部中断源。其实,还有一种简单办法可以用一个中断接收所有通道。这就是绕过接收机的解码电路,使用arduino直接对PPM信号解码。这种方式麻烦的地方是需要拆开接收机,把解码前的PPM信号引出来。
参考:http://diydrones.com/profiles/blogs/705844:BlogPost:38393
打开接收机后,寻找PPM信号接口有几种办法:
1.
2.
3.
ARDUINO 代码复制打印
//http://diydrones.com/profiles/blogs/705844:BlogPost:38393
#define channumber4//How many channels have your radio?
intvalue[channumber];
voidsetup()
{
Serial.begin(57600);//Serial Begin pinMode(3,INPUT);//Pin 3 as input }
voidloop()
{
while(pulseIn(3,LOW)<5000){}//Wait for the beginning of the frame for(intx=0; x<=channumber-1; x++)//Loop to store all the channel position { value[x]=pulseIn(3,LOW); } for(intx=0; x<=channumber-1; x++)//Loop to print and clear all the channel readings { Serial.print(value[x]);//Print the value Serial.print(" "); value[x]=0;//Clear the value afeter is printed } Serial.println("");//Start a new line }
单片机解码PPM信 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)