アナログからデジタルへ、センサーの値をA/D変換して取得しよう!マイクロマウスで始める組み込み開発入門(10)(2/2 ページ)

» 2013年02月05日 08時35分 公開
[三月兎,MONOist]
前のページへ 1|2       

センサードライバとコントローラの作成

 次に、センサードライバの作成に入ります。「drv.h」にA/D変換ドライバとセンサーLED用のポートおよびレジスタの定義を追加します(ソースコード5)。


int  drv_adc_r(void);                  //AD変換ドライバ(右)
int  drv_adc_l(void);                  //AD変換ドライバ(左)
int  drv_adc_fr(void);                 //AD変換ドライバ(前右)
int  drv_adc_fl(void);                 //AD変換ドライバ(前左)
 
//AD変換(右センサー)
#define SLED_R           PA.DRL.BIT.B7          //センサーLED(右)
#define ADC_R_CH         AD0.ADCSR.BIT.CH       //チャネル選択(右)
#define ADC_R_START      AD0.ADCR.BIT.ADST      //AD変換開始(右)
#define ADC_R_FIN_FLG    AD0.ADCSR.BIT.ADF      //AD変換終了フラグ(右)
#define ADC_R_CHNO       3                      //AD変換チャネル(右)
#define ADC_R_VALUE      AD0.ADDR3              //AD変換値(右)
 
//AD変換(左センサー)
#define SLED_L           PA.DRL.BIT.B6          //センサーLED(左)
#define ADC_L_CH         AD1.ADCSR.BIT.CH       //チャネル選択(左)
#define ADC_L_START      AD1.ADCR.BIT.ADST      //AD変換開始(左)
#define ADC_L_FIN_FLG    AD1.ADCSR.BIT.ADF      //AD変換終了フラグ(左)
#define ADC_L_CHNO       0                      //AD変換チャネル(左)
#define ADC_L_VALUE      AD1.ADDR4              //AD変換値(左)
 
//AD変換(前右センサー)
#define SLED_FR          PA.DRL.BIT.B9          //センサーLED(前右)
#define ADC_FR_CH        AD0.ADCSR.BIT.CH       //チャネル選択(前右)
#define ADC_FR_START     AD0.ADCR.BIT.ADST      //AD変換開始(前右)
#define ADC_FR_FIN_FLG   AD0.ADCSR.BIT.ADF      //AD変換終了フラグ(前右)
#define ADC_FR_CHNO      1                      //AD変換チャネル(前右)
#define ADC_FR_VALUE     AD0.ADDR1              //AD変換値(前右)
 
//AD変換(前左センサー)
#define SLED_FL          PA.DRL.BIT.B8          //センサーLED(前左)
#define ADC_FL_CH        AD0.ADCSR.BIT.CH       //チャネル選択(前左)
#define ADC_FL_START     AD0.ADCR.BIT.ADST      //AD変換開始(前左)
#define ADC_FL_FIN_FLG   AD0.ADCSR.BIT.ADF      //AD変換終了フラグ(前左)
#define ADC_FL_CHNO      2                      //AD変換チャネル(前左)
#define ADC_FL_VALUE     AD0.ADDR2              //AD変換値(前左)
 
//センサーLED 計測待ち
#define ADC_WAIT_COUNT   800                    //LEDを光らせてからAD変換を開始するまでの待ちカウント
ソースコード5 「drv.h」にA/D変換とセンサーLEDのポートやレジスタなどを定義する

 「drv.c」に各センサー用のA/D変換ドライバ「drv_adc_@」を作成します。戻り値は「受光した値」になります(ソースコード6)。

/************************************************/
/*  A/D変換ドライバ(右センサー) (drv_adc_r) */
/************************************************/
/*    右センサー用LEDをONにし、受光した値を     */
/*    A/D変換して取得して返す                   */
/*----------------------------------------------*/
/* RET:int……受光した値(下位6ビットは捨てる) */
/************************************************/
int drv_adc_r(void)
{
    //A/D変換ドライバ(右センサー)
    int i;
    //
    SLED_R = LED_ON;                        //LED点灯
    //
    ADC_R_CH = ADC_R_CHNO;                  //AD変換のチャンネルを選択
    //
    for(i = 0; i < ADC_WAIT_COUNT; i++);    //フォトトランジスタの応答待ちループ
    ADC_R_START = 1;                        //AD変換開始
    //
    while(ADC_R_FIN_FLG == 0);              //AD変換終了まで待つ
    ADC_R_FIN_FLG = 0;                      //フラグクリア
    //
    SLED_R = LED_OFF;                       //LED消灯
    //
    return ADC_R_VALUE >> 6;                //値を返す
}
ソースコード6 右センサー用A/D変換ドライバを作成。同様に左センサー用(drv_adc_l)、前右センサー用(drv_adc_fr)、前左センサー用(drv_adc_fl)を作成する

 「ctrl.c」に各センサー用のA/D変換ドライバを呼び出す処理を追加します(ソースコード7)。

/************************************************/
/*    A/D変換処理(右センサー) (ctrl_adc_r)  */
/************************************************/
/*    右センサーの値を取得する                  */
/*----------------------------------------------*/
/*    RET:int  …… センサー値                  */
/************************************************/
int ctrl_adc_r(void)
{
    //A/D変換処理(右センサー)
    int    value;
    //右センサーの値を取得
    value = drv_adc_r();
    //
    return value;
}
ソースコード7 「ctrl.c」右センサー用A/D変換ドライバを呼び出すctrl_adc_r関数を追加する。同様に、左センサー用(ctrl_adc_l)、前右センサー用(ctrl_adc_fr)、前左センサー用(ctrl_adc_fl)を追加する

北上

よし! これで、センサーの値をA/D変換して取得できるようになったよ。


えみ

はい! 早速、アプリケーションを作って動かしてみましょうよ〜!!


北上

……うん。そうだね。作ってみようか!


えみ

はい!!



アプリケーション作成

 センサーの値をA/D変換して取得できるようになったので、モード2にセンサーの値を取得するアプリケーションを作成しましょう。なお、今回は、モード2を実行するとセンサーが起動してセンサー値を取得し、プッシュスイッチのいずれかを押すとブザーを鳴らして終了する仕様にしました(ソースコード8)。

/************************************************/
/*   モード2の処理   (app_mode2)              */
/************************************************/
/*   センサーの値を取得                         */
/************************************************/
void app_mode2(void)
{
    //センサーの値を取得
    int r;                     //右センサーの値
    int l;                     //左センサーの値
    int fr;                    //前右センサーの値
    int fl;                    //前左センサーの値
    unsigned char sw_r;        //右スイッチの状態
    unsigned char sw_c;        //中スイッチの状態
    unsigned char sw_l;        //左スイッチの状態
    //
    while(1)
    {
        //センサー値取得
        r  = ctrl_adc_r();     //右
        fr = ctrl_adc_fr();    //前右
        fl = ctrl_adc_fl();    //前左
        l  = ctrl_adc_l();     //左
        //全てのスイッチの値を取得する
        ctrl_sw_all(&sw_r, &sw_c, &sw_l);
        //スイッチの値をチェック
        if(sw_r == SW_ON || sw_c == SW_ON || sw_l == SW_ON)
        {
            //どれかのスイッチが押されたらブザーを鳴らし、終了する
            ctrl_bz(BZ_FREQ_DO, 100);        //ブザー鳴動(ド)
            break;
        }
    }
}
ソースコード8 モード2を実行するとセンサーの値を読み込む。スイッチを押すと終了する

>>ソースコード(Mouse201302.lzh)のダウンロードはこちら

 では、プログラムをビルドして、Pi:Co Classicの動作を確認してみましょう(動画1)。

動画1 モード2にして、黄色ボタンを押すと赤外線センサーが稼働する

えみ

やったー。ちゃんとLEDが光ってますね。

よーし、スイッチ・オンでセンサーの値をゲットしちゃいますよぉ〜!


北上

……。


えみ

あれぇ〜、センパーィ。LEDも光っているし、ブザーも鳴ったけど……。

これじゃ、センサーの値が分かりませんよぉー。


北上

えみちゃん、よーく考えてごらんよ。今は、センサーの値をA/D変換しただけじゃないか。まだ、PCのモニターに表示するプログラムは作っていないんだよ! もう1つあっただろ、重要なキーワードが。


えみ

あっ……、「シリアル通信」!! これを使って、PCのモニターに表示するプログラムを作るんですね。


北上

そう。そういうこと! さぁ、もう少しガンバろう。


えみ

はーい! でも、その前にお茶休憩希望で〜す。


北上

ふふっ。

そうくるだろうと思って、今日は角の和菓子屋さんで豆大福を買っておいたよ。


えみ

やったー!!





 前回、(ブザー音で)レベルアップしたはずのえみちゃんでしたが……。やはり、おっちょこちょいは治りませんね。

 最近のマイクロマウスの機体には、壁読みセンサーだけでなく、ジャイロセンサーを搭載したものも増えています。ロボットの状態を検出するためには、センサー技術は必須です。そして、今回紹介したA/D変換も避けては通れない道なので、しっかりと理解しておく必要があります。

 さて次回は、シリアル通信を使って、センサーで取得した値をPCのモニターに表示させるプログラムに挑戦します。お楽しみに! (次回に続く)

ロボット/ロボット開発 コーナー

ロボット/ロボット開発コーナー
あらゆる技術の集大成といわれる「ロボット」をテーマに、産業、レスキュー、生活支援/介護分野などにおけるロボット開発の実情や、関連する要素技術、研究開発、ロボットコンテスト、ロボットビジネスの最新動向などをお届けする。

>>コーナーTOPはこちらから


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.