羽ばたき飛行機の滑空制御装置GPAT10製作編



羽ばたき飛行機の滑空制御装置GPAT10設計編の続きになります。

制御装置の仕様が固まったので実際にコードを書いてみる事にしました。

基本は、16ビットタイマで受信機から出るPWMをキャプチャ、すぐに同じ16 ビットタイマでPWMを出力するループを作ります。
PWM入出力の合間に入力信号から条件分岐をし、制御する事にします。

以上の様にコードを書くと、結構問題が出てきました。16ビットをフル活用したタイマ測定が出来ないのです。
仕方なく、10ビットタイマに分解能を落としてコードを書きました。
10ビットタイマを4MHzで駆動させるようにしたので、周期は2.5msちょっとになります。
ラジコンのPWMのON時間は最大でも2.2ms程度なのでぎりぎり対応出来ます。
20msの周期は受信機のPWMをキャプチャしたらすぐに波形出力をするため、時間の制御は必要ありません。
下にβ版のソースコードを載せておきます。
※素人が作ったプログラムなので、改善する点があれば教えていただければ幸いです。

/*
* ATtiny10_program.c
*
* Created: 2012/10/02
* Author: hiro
*/ 
#ifndef F_CPU
#define F_CPU 4000000UL
#endif
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define LED PB0
#define DELAY 100
#define PLS_UP		1
#define PLS_DOWN	0
uint8_t pls_state;//パルスキャプチャフラグ
uint8_t oneshotP;//ワンショットパルス生成フラグ
uint16_t b=0 ;//受信機パルス格納変数
uint16_t count = 0x03ff;//受信機パルス計算結果格納変数
uint8_t i;//初期化実行変数
uint16_t motor_OFF = 0;//モーターOFFパルス格納変数
uint16_t motor_ON = 0;//モーターONパルス格納変数
uint16_t power_select = 0;//モーターON or OFF 条件分岐変数
//power_select == 0 通常駆動
//power_select == 1 モータースロー駆動
//power_select == 2 モーター停止
uint8_t glide_mode;//滑空モードフラグ
uint8_t cycle = 0;//PWMサイクルカウント格納
uint8_t hall_cont = 0;//磁気センサーカウントフラグ
/******************************************/
/*タイマ0オーバーフロー割り込み
/******************************************/
ISR(TIM0_OVF_vect)
{
if(oneshotP == 1){
switch(power_select)
{
case 0:	OCR0A = count;	//出力パルス入力
oneshotP = 0;	//ワンショットフラグOFF
cycle ++;
break;
case 1:	OCR0A = motor_ON;
oneshotP = 0;
cycle ++;
break;
case 2:	OCR0A = motor_OFF;
oneshotP = 0;
cycle ++;
break;
}
}else{
OCR0A = 0x03ff;	//パルスOFF
oneshotP = 0;
}
}
/******************************************/
/*タイマ0 インプットキャプチャ割り込み
/******************************************/
ISR(TIM0_CAPT_vect)
{
if(pls_state == PLS_UP){
TCNT0 = 0x0000;	//カウントアップ初期化
pls_state = PLS_DOWN;//フラグ変更
TCCR0B = 0x0A;//(00001010) 下降エッジキャプチャ設定
}else{
pls_state = PLS_UP;//フラグ変更
TCNT0 = 0x03FF;	//カウントアップ初期化
b=ICR0;
count = 0x03ff - b;
TCCR0B = 0x4A;//(01001010) 上昇エッジキャプチャ設定
oneshotP = 1;//ワンショットフラグON
}
}
/******************************************/
/*入力変化割り込み(ホールセンサー)bit_is_clear()
/******************************************/
ISR(PCINT0_vect)
{
if (bit_is_clear(PINB,PINB2)){
if ( power_select ==1 ){
if (hall_cont==0){
hall_cont = 1;
}else{
hall_cont = 0;
power_select = 2;
OCR0A = motor_OFF;
//oneshotP = 0;
}
}
}
}
/******************************************/
/*メインプログラム
/******************************************/
int main(void)
{
//発振器の選択
CCP = 0xD8;
CLKMSR = 0;//発振器の選択
CCP = 0xD8;
CLKPSR = 1;//発振器のプリスケーラ2(4MHz)
//ポート入出力設定
DDRB = 0x09;
//タイマー設定
TCCR0A = 0xC3;//(11000011)
TCCR0B = 0x4A;//(01001010)
TCCR0C = 0x00;
OCR0A = 0x03ff;	//カウンター比較値
TCNT0 = 0x0000;	//カウントアップ初期化
//割り込み設定
TIMSK0 = 0x21;
pls_state = PLS_UP;	//キャプチャーフラグセット
oneshotP = 0;//ワンショットフラグOFF
PCICR = 0x01;
PCMSK = 0x04;
sei();
//初期化プログラム///////////////////////////////////////////////////////
if(motor_OFF == 0){//モーターOFFパルス公正
i=0;
while (i < 10){//電源挿入後、約1秒間の安定パルス確認
if ( (motor_OFF < (count + 5)) && (motor_OFF > (count - 5)) && (count !=  0x03ff) && (count >  0x0000)){
i++;
_delay_ms(DELAY);
}else{
motor_OFF = count;
i=0;
}
}
}
if (motor_ON == 0){
i = 0;
while (i < 10){//モーターONパルス設定
if ( (motor_ON < (count+5)) && (motor_ON > (count-5)) && ( (motor_ON < (motor_OFF-10)) || (motor_ON > (motor_OFF+10))) ){
i++;
_delay_ms(DELAY);
}else{
motor_ON = count;
i=0;
}
}
}
if (motor_ON > motor_OFF){//受信機タイプ選択
i=0;
}else{
i=1;
}
//初期化プログラム終了///////////////////////////////////////////////////////
while(1){
if ( ((count < (motor_ON + 5)) && ( count > (motor_OFF - 5) ) && (i==0) ) || ((count > (motor_ON - 5)) && (count < (motor_OFF + 5)) && (i==1)) ){
glide_mode = 1;//滑空モード
if ( ((count < (motor_OFF + 5)) && (i==0)) || ((count > (motor_OFF - 5)) && (i==1)) ){
cli();
power_select = 2;//パワー OFF
sei();
}else{
if (power_select == 0){
cycle = 0;//サイクルカウント開始
cli();
power_select = 1;//パワー Low
sei();
}
}
if (cycle > 200){//ワンサイクル20msとした場合、約4秒
cli();
power_select = 2;//パワー OFF
sei();
}
}else{
glide_mode = 0;//羽ばたきモード
cli();
power_select = 0;//通常モード
sei();
}
}
}

Sponsored link

製作編

まず、表面実装品にプログラムを書き込む為に、アダプターを作ります。
NCフライスを導入してからはこの様な工作がずっと楽になりました。基盤の配線の間隔は0.5mm。

↓この様にマイコンをセットし、アダプターにビス止めして使います。

秋月電子の実装品と比較

このアダプターを使ってプログラムを書き込み、基盤に実装します。
↓1.6mm厚のベーク基盤を使いました。こちらの配線の間隔は0.2mmです。
部品(基盤以外は全て秋月電子で購入出来るもので作りました。)
・ATtiny10マイコン
・10kΩ抵抗2個
・表面実装用ショットキーバリアダイオード 【SS2040FL】
↑このセンサーはラッチ回路になっていますので、磁石は2つ必要です。
・100μFセラミックコンデンサ

ここまで小さくなるとハンダ付けも大変です。
ニッパーでハンダ線を小さく切って使います。

写真の赤丸の部分に切ったはんだを乗せ、ハンダ付けします。
基盤の間隔が0.2mmなので切ったハンダの大きさが分かるかと思います。ちなみにこれでも大きい方です。

ハンダ付けするとこうなります。

完成品はこちら

コネクターも合わせた質量は1.84g
センサーと一体になっているのでこれだけ軽量に作る事が出来ました。

動作確認してみました。

関連記事



Sponsored link

One Response to 羽ばたき飛行機の滑空制御装置GPAT10製作編

  1. tt on 2014年3月8日 at 20:59

    おっさんだと思ってたのに、指がキレーじゃねえかwww

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です