スポンサーリンク

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

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

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

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

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

#ifndef F_CPU
#define F_CPU 4000000UL
#endif

#include
#include
#include

#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();
}
}
}
[/c]

スポンサーリンク

製作編

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

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

秋月電子の実装品と比較

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

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

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

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

完成品はこちら

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

動作確認してみました。

コメント

  1. tt より:

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