78K0でラジコン
これまでの記事78K0で無線通信(1)(2)(3)で
78K0のUARTを使って簡単に無線通信できることがわかりました。
今回はその応用編として、トイラジを動かしてみたいと思います!
今回動かしたラジコン

■■78K0でラジコンを制御することのメリット■■
短く言うと高機能化。
●メリット1●たくさんのものを制御できる
今回は前後左右のモーターのON/OFFだけを行っていますが、
もちろんソフトと回路次第でライト類の点灯・消灯など
制御対象となるものを自由に増やすことができるようになります。
●メリット2●自動操縦もできる
制御しているのが78K0なので、動作をプログラムの中に記述することで、
たとえばあるスイッチを押すと、自動で部屋を一周して戻ってくる、
というような自動操縦もできるようになります。
●メリット3●操縦される側にも自律性を持たせることができる
通常のラジコン受信機用ICは決まったことしかできません。
でも制御される側に78K0を使うことで、暗くなったら自動的に
ライトをつけたり、進む先に障害物があったら自動的にそれを
よけたりさせることができるようになります。
もちろんそれだけのプログラムを組むことが必要ですが。
いろいろ書きましたが、今回は単純に走行用モータとステアリングのON/OFFの
制御だけを行います。
■■送信機■■
■ハードウェア■
改造前の送信機です。

分解すると・・・

こうなってます。基板が裏返っていてちょっとしか見えませんが、この基板の
部品面に銅板?とすずめっき線による接点が設けられていて、それがレバーで
押されてスイッチとして機能しています。回路的にはこの基板のスイッチ部分だけを
使用します。基板上のスイッチ部分とそれ以外の箇所がつながっている部分を
カッターでパターンカットします。そして下のように回路を組み、配線します。
配線し終わったのが、次の写真です。送信機の基板の上側にある蛇の目基板は
LM1117-ADJとコンデンサ、微弱無線送信モジュールが載っています。

これを元の送信機のケースに戻したのがこの写真です。
トラ技78K0基板にUSBケーブルを挿せるように、ケースに切り欠きを入れています。

ふたを閉めてプログラムを書き込めば、送信機として動作します。
■ソフトウェア■
今回送信機側で必要なプログラムは以下のとおりです。
・radicon_tx.c
・uart6.c
・RamStart.asm
・trgbios.h
・radicon_tx.h
・RAMAPP.dr
radicon_tx.c、radicon_tx.h以外は前々回の記事(78K0で無線通信(2))に掲載した
ものと同じものを使います。ただし、uart6.cの
#include "wireless_test.h”
の行を
#include "radicon_tx.h”
に変更して使ってください。
●ラジコン送信機メインプログラム radicon_tx.c●
/*
■トラ技78K0付録基板
■uPD78F0730
■radicon_tx.c
■315MHz微弱無線モジュールによるラジコン送信機
2009.2.25作成
*/
#pragma EI /* 全体割り込み許可命令を使用できるようにする */
#pragma DI
#pragma sfr /* プログラム上で直接SFR名でSFRを操作できるようにする */
#include "trgbios.h” /* トラ技CDのUSBの関数を使用するためにトラ技BIOSをインクルード */
#include "radicon_tx.h”
/*
****************************************
main 初期化
****************************************
*/
void main( void )
{
/* クロックは内部発振 16 MHz */
/* 関数の宣言 */
unsigned char temp; /* データ一時保存 */
/* 入出力ポートの初期化(0:出力,1:入力) */
PM0.0 = 0;
PM0.1 = 0;
PM1 = 0b11110001;
/* P10 スイッチ後
P13 TxD6
P15 スイッチ左
P16 スイッチ右
P17 スイッチ前
*/
PM3.0 = 0;
PM3.1 = 0;
PM6.0 = 0;
PM6.1 = 0;
PM12.0 = 0;
P6.1 = 0;/* 起動中青消灯 */
/* 通信ポートの初期化 */
UART6_INIT( 0x09 , 13 , 0x04 ); /* UART6初期化(1200bps,8bit,none CPUユーザーズマニュアル参照) */
UART6_MANEGE( 1 ); /* UART6動作開始 */
/* タイマ50初期化 */
TCL50 = 0x07; /* クロックは1953.125Hz */
CR50 = 0xC3; /* インターバル周期は0.512mS*195 = 99.84mS */
TMC50 = 0x00; /* インターバル */
/* タイマH1初期化 */
TMHMD1 = 0b01000000; /* タイマーH1クロックは3906.25Hz (周期0.256mS) インターバル */
/* トラ技biosに対する割り込み関数の設定 */
trg_regintsrv( TRG_INTID_BSITM50 , READ_AND_TX );
TMC50.7 = 1; /* タイマ50動作開始 */
MK0H.5 = 0; /* タイマ50割り込みマスクをクリア */
P6.1 = 1;/* 青消灯 */
/* 割り込み受付 */
EI();
while( 1 );/* 以後0.1Sごとにスイッチ読み込み&送信 */
}
/*
****************************************
スイッチの読み込みと送信
****************************************
*/
void READ_AND_TX( void ) /* 0.1秒ごとにスイッチの状態を読み込み、
それに応じた送信データを作る */
{
unsigned char txdata = 0x00;
IF1L.3 = 0;/* トラ技biosが動作しているため、割り込み要求フラグのクリアが必要 */
if( P1.6 == 0 ) /* 右なら2ビット目1 */
{
txdata = txdata | 0b00000100;
}
else if( P1.5 == 0 ) /* 左なら3ビット目1 */
{
txdata = txdata | 0b00001000;
}
if( P1.7 == 0 ) /* 前なら0ビット目1 */
{
txdata = txdata | 0b00000001;
}
else if( P1.0 == 0 ) /* 後なら1ビット目1 */
{
txdata = txdata | 0b00000010;
}
txdata = txdata & 0b00001111; /* 上位4ビットは使わないのでクリアしておく */
if( txdata != 0b00000000 ) /* 前後左右のいずれかが押されているときのみ送信する */
{
P6.1 = 0;/* 送信中青点灯 */
UART6_TX( 0x55 ); /* 受信側安定化待ち */
UART6_TX( 0xff );
WAIT256U( 0x26 );
UART6_TX( 0x02 ); /* ヘッダ */
UART6_TX( 0x0A ); /* ヘッダ */
UART6_TX( txdata + 0x40 ); /* 無線で出力(UART6) *//* + 0x40 しているのはターミナルソフトでの表示のため */
UART6_TX( 0x03 ); /* フッタ */
P6.1 = 1;/* 送信後青消灯 */
}
}
/*
****************************************
タイマーH1を使った待ち時間生成
****************************************
*/
void WAIT256U( unsigned char c )
{
CMP01 = c; /* タイマーH1リセット周期は c * 256uS */
TMHMD1.7 = 1; /* タイマーH1動作開始 */
IF0H.3 = 0;
while( IF0H.3 != 1 ); /* タイマーH1リセットかかったらタイムアウト */
TMHMD1.7 = 0; /* タイマーH1動作停止 */
}
●ラジコン送信機プログラム用ヘッダファイル radicon_tx.h●
/*
■トラ技78K0付録基板
■uPD78F0730
■radicon_tx.h
■315MHz微弱無線受信モジュールによるラジコン送信機のヘッダファイル
2009.2.25作成
*/
/* メイン関数の宣言 */
void main( void );
/* サブ関数の宣言 */
void READ_AND_TX( void );
void WAIT256U( unsigned char );
void UART6_INIT ( unsigned char , unsigned char , unsigned char );
void UART6_MANEGE ( unsigned char );
unsigned char UART6_RX( void );
void UART6_TX( unsigned char );
●プログラムの解説●
タイマ50で約0.1秒ごとの割り込みをつくり、そのたびに前後左右のスイッチの
ON/OFFを読み込み、前後左右のいずれかがONであれば、送信を行います。
寝ている送信モジュールを起こし、常にランダムデータを受信している
受信モジュールが正しくスタートビットを認識できるように、
前々回(78K0で無線通信(2))と同じように、0x55・0xFF・ウェイト・0x02を
送信してから、前後左右のON/OFFデータを送信しています。
今回のプログラムもトラ技BIOS上で動くものだったので、割り込みを使うためには
トラ技BIOS上のルールに従う必要がありました。
通常は78K0の開発環境でC言語を使うときはこのように、
#pragma interrupt INTTM50 READ_AND_TX nobank
割り込みが生じたときに実行する関数を前処理指令で指定しますが、トラ技BIOS上で
割り込みを使うときには、
trg_regintsrv( TRG_INTID_BSITM50 , READ_AND_TX );
のようにトラ技BIOSの中にある割り込み関数設定用関数を使う必要があります。
また、通常の割り込みでは割り込み要求フラグは割り込みが生じると自動的に
クリアされますが、トラ技BIOS上ではこれを割り込みごとにクリアしてやる必要が
あります。クリアしないとクリアするまで次の割り込みが起こらないことになります。
また、送信時にはトラ技基板上の青LEDを点灯させています。スイッチのすきまから
青い光が見えて、送信中であることがわかります。
■■受信機■■
■ハードウェア■
まず元のラジコン受信機の基板に載っているトイラジ受信機専用ICのデータシートを
探してみてみるか、基板から回路図を起こして、基板のどこにどんな信号を入れれば
走行用モーター・ステアリング用モーターをまわせるのか調べます。
今回の基板ではモーターをドライブしているトランジスタが見つかったので、
基板のそのほかの部分に電源を供給しているパターンをカットして、それらの
トランジスタのベースにエレキジャック78K0基板のデジタル出力を接続しました。

エレキジャック78K0基板側の回路もブレットボード上に組みます。

回路図は下のとおりです。
■ソフトウェア■
受信機側に必要なプログラムは以下のとおりです。
・radicon_rx.c
・uart6.c
・radicon_rx.h
uart6.cは前々回(78K0で無線通信(2))と同じものを使います。ただ、
送信側と同じように、
#include "wireless_test.h”
を
#include "radicon_rx.h”
に変更してください。
●ラジコン受信機メインプログラム radicon_rx.c●
/*
■エレキジャック78K0付録基板
■uPD78F0503DA
■radicon_rx.c
■315MHz微弱無線受信モジュールによるラジコン受信機
2009.2.25作成
*/
#pragma interrupt INTTM50 TURNOFF nobank/* タイマ50割り込み時に実行する関数 */
#pragma DI /* 全体割り込み禁止命令を使用できるようにする */
#pragma EI /* 全体割り込み許可命令を使用できるようにする */
#pragma sfr /* プログラム上で直接SFR名でSFRを操作できるようにする */
#include "radicon_rx.h”
/*
****************************************
ハードウェアの初期化
****************************************
*/
void INIT( void )
{
/* クリスタルは 10 MHz */
/* メモリ・クロック初期化 */
IMS = MEMORY_IMS_SET; /* 内部RAM,内部ROMのメモリサイズ設定 */
AMPH = OSC_FREQ_CONT; /* 発振周波数範囲の設定 */
OSCCTL = CLOCK_MODE; /* クロック動作モード設定 */
MOC = 0x00; /* X1発振回路の発振開始 */
while( OSTC != 0x1f ); /* X1入力クロック発振安定待ち(6.55ms以上) */
MCM = SYSTEM_CLOCK_SELECT; /* システムクロック供給選択 */
PCC = 0x00; /* CPU動作クロック:fx(10MHz)に設定 */
/* 入出力ポートの初期化(0:出力,1:入力) */
/* PORT0 */
PM0.0 = 0;
PM0.1 = 0;
/* PORT1 */
PM1.0 = 0;/* TxD0 */
PM1.1 = 0;/* RxD0 */
PM1.2 = 0;
PM1.3 = 0;/* TxD6 */
PM1.4 = 1;/* RxD6 *//* 受信 */
PM1.5 = 0;/* 受信確認用 */
PM1.6 = 0;/* 右 */
PM1.7 = 0;
/* PORT2 A/D兼用 */
PM2.0 = 0;
PM2.1 = 0;
PM2.2 = 0;
PM2.3 = 0;
/* PORT3 割り込み兼用 */
PM3.0 = 0;/* 左 */
PM3.1 = 0;
PM3.2 = 0;/* 前 */
PM3.3 = 0;/* 後 */
/* PORT6 I2C */
PM6.0 = 0;
PM6.1 = 0;
/* PORT12.0 割り込み兼用 */
PM12.0 = 0;
P1.5 = 1;/* 電源投入確認のためLED点灯 */
/* UART初期化・動作開始 */
UART6_INIT( 0x06 , 0x41 , 0x04 ); /* UART6初期化(1200bps,8bit,none CPUユーザーズマニュアル参照) */
UART6_MANEGE( 1 ); /* UART6動作開始 */
/* タイマ50初期化 */
TCL50 = 0x07; /* クロックは2441.40625Hz */
CR50 = 0xF2; /* 0.4096ms×242=99.1232ms */
TMC50 = 0x00; /* インターバル */
MK0H.5 = 0; /* タイマ50割り込みマスククリア */
EI(); /* 全体割り込み許可 */
}
/*
****************************************
main 315MHz微弱無線受信
****************************************
*/
void main( void )
{
/* 変数の宣言 */
unsigned char temp;
/* ハードウェアの初期化 */
INIT(); /* メモリ・クロック初期化、入出力設定 */
/* 無線受信→UART送信 */
while( 1 )
{
temp = UART6_RX();
if( temp == 0x02 )
{
temp = UART6_RX();
if( temp == 0x0A ) /* 連続で0x20,0x0Aを受信したときのみ駆動 */
{
temp = UART6_RX();
DRIVE( temp );
}
}
}
}
/*
****************************************
モータ駆動
****************************************
*/
void DRIVE ( unsigned char temp )
{
if( ( temp <= 0x4A ) & ( temp >= 0x41 ) )
{
TMC50.7 = 0; /* タイマ50動作停止 */
P1.5 = 1;/* 受信LED点灯 */
if( ( temp & 0b00000001 ) == 0b00000001 )
P3.2 = 1;/* 前駆動 */
else if( ( temp & 0b00000010 ) == 0b00000010 )
P3.3 = 1;/* 後駆動 */
else
{
P3.2 = 0;/* 前後とも停止 */
P3.3 = 0;
}
if( ( temp & 0b00000100 ) == 0b00000100 )
P1.6 = 1;/* 右駆動 */
else if( ( temp & 0b00001000 ) == 0b00001000 )
P3.0 = 1;/* 左駆動 */
else
{
P1.6 = 0;/* 右左とも停止 */
P3.0 = 0;
}
TMC50.7 = 1; /* タイマ50動作開始 */
}
else
{
P3.2 = 0;/* 前後右左とも停止 */
P3.3 = 0;
P1.6 = 0;
P3.0 = 0;
P1.5 = 0;/* 受信LEDも消灯 */
}
}
/*
****************************************
一回受信につき0.1秒のみモーターを駆動
****************************************
*/
void TURNOFF ( void )
{
TMC50.7 = 0; /* タイマ50動作停止 */
P3.2 = 0;/* 前後右左とも停止 */
P3.3 = 0;
P1.6 = 0;
P3.0 = 0;
P1.5 = 1;/* 受信LED消灯 */
}
●ラジコン受信機プログラム用ヘッダファイル radicon_rx.h●
/*
■エレキジャック技78K0付録基板
■uPD78F0503DA
■radicon_rx.h
■315MHz微弱無線受信モジュールによるラジコン受信機のヘッダファイル
2009.2.25作成
*/
#define MEMORY_IMS_SET 0xC8 /* 内部RAM1KByte,内部ROM32KByteに設定 */
#define OSC_FREQ_CONT 0x00 /* 発振周波数範囲「1 MHz≦fXH≦10 MHz」 */
#define CLOCK_MODE 0x40 /* X1,X2端子をX1発振モードに設定 */
#define SYSTEM_CLOCK_SELECT 0x07 /* CPUや周辺に高速システムクロックを供給 */
/* メイン関数の宣言 */
void main( void );
/* サブ関数の宣言 */
void INIT( void );
void UART6_INIT ( unsigned char , unsigned char , unsigned char );
void UART6_MANEGE ( unsigned char );
unsigned char UART6_RX( void );
void UART6_TX( unsigned char );
void DRIVE ( unsigned char );
void TURNOFF ( void );
●プログラムの解説●
信号がなければ何もせずにただ待ちます。連続して0x02,0x0Aを受信すると
そのあとの1バイトを読み込み、スイッチが入っているモーターをスイッチが
入っている方向にON("H"を出力)します。同時にタイマを動作開始し、
その後約0.1秒以内に連続して0x02,0x0Aを受信しなければ、タイマの割り込みで
ONにしていたモーターをOFFにします。約0.1秒以内に連続して0x02,0x0Aを
受信すれば、タイマを停止してスイッチの入っているモーターをONにします。
そしてタイマを動作開始します。タイマは何かスイッチがONになっているときだけ
動作するということになります。
要は一回の受信につき約0.1秒間モーターを動かしているということです。
そして送信機のスイッチが連続してONされているときは、約0.1秒ごとに送受信
することになるので、連続してモーターも駆動されるということです。
また、電源を入れるとLEDが点灯します。最初の連続した0x02,0x0A受信以後は
モーター動作中のみ点灯します。
実はこのプログラムでは元のトイラジとは同じ動作をしません。トイラジの
ステアリングはON/OFFで、切れ角の制御をしていません。右いっぱいに切るか、
左いっぱいに切るか、切れ角0°(直進)のいずれかしかありません。
そしてステアリングの切れ角をトイラジ受信機専用ICに伝える信号線が
ステアリング部分から出ており、直進時はこの切れ角が0°でなくなったときに
反対方向にステアリングを切り、直進の状態を保ちます。
今回のプログラムでは、ステアリングのモーターを単にON/OFFさせているだけ
なので、ステアリングのレバーを戻して直進にしても、ステアリングは切れたまま
になっています。ステアリングを切ったあとは切れたままのステアリングを
切れ角0°にするために、ステアリングを短時間反対側に切って戻してやる必要が
あります。もちろん切れ角検出の線を78K0に入力して、ソフトを変えてやれば
元のトイラジと同じように、ステアリングを切ったあとに自動的に切れ角0°に
戻してくれるようにすることもできます。
■■次回予告!!!■■
次回はトラ技・エレキジャック78K0基板を使って、コンセントに挿した家電製品の
電気代を算出してパソコン上に表示する電力料金計を製作します!!!
省エネもとい、エコが叫ばれる昨今、強力な味方となるはずです!!!
そしてその電力料金計のソフトは、去年の秋にリリースされた
マイコン統合開発プラットフォーム CubeSuite を使って書こうと思います!!!
乞うご期待!!!
コメント
この投稿には、まだコメントが付いていません
コメントの投稿
ごめんなさい、現在コメントを付けることは出来ません

