本帖最后由 w飞鹰j 于 2017-11-29 11:46 编辑
福斯i6遥控升级8通道,只有六通道接收机支持ppm输出,想用其余通道怎么办? 简单快捷方法——买一个十通道接收啊!!
进入主题!来另一种方法DIY,(在此感谢arduino项目开发者,arduino给我此作品带来极大便利)重新对ppm信号解码!(别人忙着复习期中考试,我却忙着做ppm解码器,,花了两个下午,程序写好!!)
什么是ppm信号?
PPM信号是将多个控制通道(理论可10个控制通道)集中放在一起调制的信号。
也就是一个PPM脉冲序列里面包含了多个通道的信息。如下图所示(此图是借用的)更多资料请自行查阅。
开始构思程序前,网上查阅了很久,都提到测量出图中t1、t2、……的时长,但是我在程序设计时发现记录下时间了,怎样把时间对应产各通道并产生pwm信号遇到问题(八路pwm)!
于是又换了另一种思路,不测量t1、t2、……具体时间,只要捕捉到起点和终点即可。
例如;解码出第一通道信号
(1)定义一个输出pwm引脚;
(2)当检测到t1时段起点时刻,输出高电平。
(3)检测到t1时段终点时刻,输出低电平。
提到捕捉起点终点位置,怎么捕捉呢?
328芯片有两个外部中断,
attachInterrupt(0, RC_in, RISING); //上升沿触发中断
,即是由低电平变为高电平时触发中断。利用外部中断捕捉到时间变化始末位置。
接下来还有一个重要步骤,(ppm信号是连续不断的从接收机输出)我们怎么知道捕捉到的是第几通道的始末点呢?
借用一张图,先谢谢原创者
图示,一帧数据中,绿色高电平时间最长,八通道时肯给定大于3毫秒的!我们只要捕捉到这一特殊时段,就知道接下来就是第一通道的信号了!!arduino中有一个函数很方便测量脉冲宽度,
pulseIn函数用于读取引脚脉冲的时间长度,脉冲可以HIGH或LOW。如果是HIGH,函数将先等引脚变为高电平,然后开始计时,一直到变为低电平为止。返回脉冲持续的时间长短!这样我们就把信号同步问题解决了,到此结束!!大家有兴趣自己做了试试!转载请注明出处,谢谢!
代码
#define ppm_in_pin 2
#define ppm_pulseIn 4
unsigned int RC_count = 0;
unsigned int PPM_HIGH = 0;
void RC_in() {
RC_count++;
}
void setup()
{
DDRB = DDRB | 0X1F ;
DDRD = DDRD | 0XE0 ;
Serial.begin(57600);
pinMode(ppm_in_pin, INPUT_PULLUP);
pinMode(ppm_pulseIn, INPUT);
attachInterrupt(0, RC_in, RISING); //上升沿触发中断
}
void RC_valout() {
switch ( RC_count ) {
//第一通道
case 0: {
PORTD = PORTD & 0X1F; //PD后三位清零
PORTD = PORTD | 0X20;//PD5输出高电平
PORTB = PORTB & 0XE0; //PB前五位清零
}; break;
//第二通道PD6
case 1: {
PORTD = PORTD & 0X1F; //PD后三位清零
PORTD = PORTD | 0X40; //PD6输出高电平
PORTB = PORTB & 0XE0; //PB前五位清零
}; break;
//第三通道PD7
case 2: {
PORTD = PORTD & 0X1F; //PD后三位清零
PORTD = PORTD | 0X80; //PD7输出高电平
PORTB = PORTB & 0XE0; //PB前五位清零
}; break;
//第四通道PB0
case 3: {
PORTD = PORTD & 0X1F; //PD后三位清零
PORTB = PORTB & 0XE0; //PB前五位清零
PORTB = PORTB | 0X01; //PB0输出高电平
}; break;
//第五通道PB1
case 4: {
PORTB = PORTB & 0XE0; //PB前五位清零
PORTB = PORTB | 0X02; //PB1输出高电平
}; break;
//第六通道PB2
case 5: {
PORTB = PORTB & 0XE0; //PB前五位清零
PORTB = PORTB | 0X04; //PB2输出高电平
}; break;
//第七通道PB3
case 6: {
PORTB = PORTB & 0XE0; //PB前五位清零
PORTB = PORTB | 0X08; //PB3输出高电平
}; break;
//第八通道PB4
case 7: {
PORTB = PORTB & 0XE0; //PB前五位清零
PORTB = PORTB | 0X10; //PB4输出高电平
}; break;
case 8: {
PORTB = PORTB & 0XE0; //PB前五位清零
PORTD = PORTD & 0X1F; //PD后三位清零
}; break;
}
}
void loop()
{
PPM_HIGH = pulseIn(ppm_pulseIn, HIGH);
if (PPM_HIGH > 3000) {
RC_count = 0;
}
RC_valout();
}
|