5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 15302|回复: 41
打印 上一主题 下一主题

DIY个飞翼用的陀螺仪混控器

[复制链接]
跳转到指定楼层
楼主
发表于 2012-7-23 22:59 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
最近天天有空就陪小女儿下水,收获大啊,比做混控还有意思:em15:


混控要等到10月分了呀。
一直想玩个飞翼,但是在论坛上潜水发现都说飞翼比较难控制。飞直机的时候有陀螺仪,现在还有1个0704和一个FUTABA GY401,控是天八2.4G。
前段时间学习了下AVR单片机,觉得用最小系统板就可以实现这个混控了。

慢慢来吧,反正连飞翼都没有。

舵机有3颗85mg bb,电机就多了,什么1806有3个,还有几个也说不上牌号的,电调也有。


准备定制专用翼型的机翼,看能不能做个没有垂尾的飞翼。

翼展想大点,还要能组合的。虽然有车,不过运输途中体积越小越好啊。

翼展多大好?初步定1600mm吧。



其实单片机有3个,一个avr16,一个avr32,还有一个avr128,应该用avr16 + 8M 晶振就可以了。

进度不会很快,因为还有别的事。虽然大女儿放假了准备去上高中,但还有个2岁半的小女儿要我陪啊。

先上个小女儿最近学游泳的视频吧

视频地址:http://www.56.com/u55/v_NzAwNTE4Mjg.html#fromoutpvid=NzAwNTE4Mjg


[ 本帖最后由 n44303 于 2012-8-18 13:35 编辑 ]

2012-07-23-218.jpg (52.57 KB, 下载次数: 82)

手头的配件

手头的配件

欢迎继续阅读楼主其他信息

42
发表于 2012-10-14 15:22 | 只看该作者
41
发表于 2012-10-11 17:19 | 只看该作者
不错
40
 楼主| 发表于 2012-10-11 11:21 | 只看该作者
39
发表于 2012-8-22 13:39 | 只看该作者
占楼看更新,真是幸福的人:em15:
38
发表于 2012-8-22 13:04 | 只看该作者
37
发表于 2012-8-17 12:05 | 只看该作者
:em26:
36
 楼主| 发表于 2012-8-16 12:52 | 只看该作者
原帖由 buknwbg 于 2012-8-16 10:21 发表
看中LZ的手提。。是苹果的吧。。

Apple MBP
35
发表于 2012-8-16 10:21 | 只看该作者
看中LZ的手提。。是苹果的吧。。
34
发表于 2012-8-15 04:20 | 只看该作者
这个其实有简单的办法。随便找个 MCPX, GCP 的主板上面带了三维陀螺仪。
还是数字的。芯片是 xmega 的,比 mega 还要好。然后就是编程就行了。
你这个读 gyro PPM 的输出频率太慢了,比较难做。
33
 楼主| 发表于 2012-8-15 02:01 | 只看该作者
没人关注啊
32
 楼主| 发表于 2012-8-10 12:19 | 只看该作者

混控没时间搞,确有了意外的收获

:em15:

没耐心拖到中间看,呵呵。

31
 楼主| 发表于 2012-8-4 21:49 | 只看该作者
原帖由 铜河 于 2012-8-4 10:35 发表
不错,程序都出来了。不知调通没?
看了上面程序,感觉有个地方可小小改进一下,现提出探讨:
TC1在TOP值为ICR1的快速PWM模式下,当计数器计到ICR1+1后,会自动清0,在溢出中断中可以省去清0的语句,省去两个时钟周 ...

接受
调通很容易,问题是混控程序还没有搞好,有什么好的建议么?
30
发表于 2012-8-4 21:11 | 只看该作者
顶了
29
发表于 2012-8-4 10:35 | 只看该作者
不错,程序都出来了。不知调通没?
看了上面程序,感觉有个地方可小小改进一下,现提出探讨:
TC1在TOP值为ICR1的快速PWM模式下,当计数器计到ICR1+1后,会自动清0,在溢出中断中可以省去清0的语句,省去两个时钟周期的中断时长。
28
 楼主| 发表于 2012-7-31 23:49 | 只看该作者
昨晚把输入检测写好了,现在手机上网,明天贴上来。

可以贴上了:

//ICC-AVR application builder : 2012/7/27 17:49:05
// Target : M16
// Crystal: 16.000Mhz

#include <iom16v.h>
#include <macros.h>


int out_f = 100,
//设置输出频率,单位Hz

ch_in_01,
   
//存储ch1的输入值

ch_in_02,
//存储ch2的输入值

ch_out_01,
//存储ch1的输出值

ch_out_02,
//存储ch2的输出值

int0_rising,

int0_falling,

int1_rising,

int1_falling;


char int0_ovf_count,

int1_ovf_count;
  //这里记录上升沿后timer1的溢出次数


void port_init(void)
{
PORTA = 0x0F;
DDRA  = 0xF0;
//PORTA最高4位为输出端口
PORTB = 0xFF;
DDRB  = 0x00;
PORTC = 0xFF;
DDRC  = 0x00;
PORTD = 0xFF;
DDRD  = 0x30;
}

//TIMER1 initialize - prescale:8
// WGM: 14) PWM fast, TOP=ICRn
// desired value: 10000uSec
// actual value: 10000.000uSec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00;
  //stop
TCNT1H = 0x00;
  //setup
TCNT1L = 0x00;
  OCR1A = ch_out_01;
  OCR1B = ch_out_02;
  ICR1  = out_f*100*2;
   

//16M晶振;8分频;实际TOP数值为20000;TOP值可以用“out_f”进行修改;
TCCR1A|= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
//OC1A/B 比较匹配时输出低电平;WGM13:WGM10配置TC1为快速PWM、TOP值=ICR1;
TCCR1B|= (1<<WGM13)|(1<<WGM12)|(1<<CS11);
//时钟8分频,每2个时钟=1uS;
}

#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
//TIMER1 has overflowed
TCNT1H = 0x00 /*INVALID SETTING*/; //reload counter high value
TCNT1L = 0x00 /*INVALID SETTING*/; //reload counter low value
int0_ovf_count++;
int1_ovf_count++;

ch_out_01 = (unsigned long)ch_in_01/100*75+(ch_in_02>>1);
//更新ch1的输出值

ch_out_02 = (unsigned long)ch_in_01/100*75-(ch_in_02>>1);
//更新ch2的输出值
}

#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{//external interupt on INT0  PD2

if(PIND & 0x04)//如果PD2为高电平,证明是上升沿触发

{

int0_rising = TCNT1;

int0_ovf_count = 0;

}

else

{

int0_falling = TCNT1;
//读取当前寄存器数值

ch_in_01 =(unsigned long)int0_ovf_count*ICR1+(unsigned long)int0_falling-(unsigned long)int0_rising;

}
}

#pragma interrupt_handler int1_isr:iv_INT1
void int1_isr(void)
{//external interupt on INT1 PD3

if(PIND & 0x08)//如果PD3为高电平,证明是上升沿触发

{

int1_rising = TCNT1;

int1_ovf_count = 0;

}

else

{

int1_falling = TCNT1;
//读取当前寄存器数值

ch_in_02 =(unsigned long)int1_ovf_count*ICR1+(unsigned long)int1_falling-(unsigned long)int1_rising;

}
}


//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer1_init();
TIMSK |= 1<<TOIE1;   
  
//开timer1溢出中断

  GICR |= (1<<INT1)|(1<<INT0);
//开启外部中断int1,int0
MCUCR |= (1<<ISC10)|(1<<ISC00);
  
//设置int1,int0电平变化触发中断
SEI(); //re-enable interrupts
//all peripherals are now initialized
}








void main(void)
{
init_devices();
while(1)
{
;
}

}

[ 本帖最后由 n44303 于 2012-8-1 23:43 编辑 ]
27
发表于 2012-7-31 17:18 | 只看该作者
NICE:em15:
26
发表于 2012-7-31 17:04 | 只看该作者

DDD

DDD
25
 楼主| 发表于 2012-7-29 13:02 | 只看该作者

用M16或者M32实现2通道输出

用16位计数器的比较匹配输出功能实现2通道输出控制。

输出频率先定为100Hz,也就是10mS的周期,比普通的50Hz快一倍,但也没有333Hz那么快。飞翼还是没有那个必要的:em15:

就2个通道的输出,就没有必要用数组了

int   ch_in_01,                    //存储ch1的输入值,来自接收器
        ch_in_02,                 //存储ch2的输入值,来自接收器
        ch_out_01,         //存储ch1的输出值,直接作为舵机信号线的驱动信号
        ch_out_02,         //存储ch2的输出值,直接作为舵机信号线的驱动信号
        out_f = 100;         //设置驱动信号输出频率,单位Hz;今后可以方便的修改为50Hz或者333Hz

//TIMER1 initialize - prescale:8
// WGM: 14) PWM fast, TOP=ICRn
// desired value: 10000uSec
// actual value: 10000.000uSec (0.0%)
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x00; //setup
TCNT1L = 0x00;
  OCR1A = ch_out_01;
  OCR1B = ch_out_02;
  ICR1  = out_f*100*2;//16M晶振;8分频;实际TOP数值为20000;TOP值可以用“out_f”进行修改;
TCCR1A|= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);        //OC1A/B 比较匹配时输出低电平;WGM13:WGM10配置TC1为快速PWM、TOP值=ICR1;
TCCR1B|= (1<<WGM13)|(1<<WGM12)|(1<<CS11);        //时钟8分频,每2个时钟=1uS;
}
24
 楼主| 发表于 2012-7-29 12:27 | 只看该作者
原帖由 铜河 于 2012-7-28 07:31 发表
大约明白LZ的意思了:就是在不动摇杆的时候,保持副翼和升降方向的稳定?
买一个现成的混控器就可以了,淘宝20元左右。


用现成的混控一来速度慢、滞后严重,二来少了DIY的乐趣了。再说我那些单片机反正闲着也是闲着,还可以巩固一下单片机的知识。

好处多多啊。:em15: :em15:
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

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