赤外線センサー by PIC16F1823

宇都宮

2011年10月05日 10:00



シャープの赤外線測距モジュールGP2Y0A21YKを使用してみました。

制御用のマイコンは 「PIC16F1823」 90円で売られていた14ピンマイコンです。

秋月電子で購入した赤外線測距モジュールの専用ケーブルは
がVo オレンジがGND がVccなので要注意です。


【参考資料】

赤外線測距モジュールGP2Y0A21YKデータシート
PIC16F1823データシート
電圧-距離換算表 「PIC AVR 工作室

【配線】
1pin  VDD
2pin  RA5 LCD RS出力
3pin  RA4(AN3) A/D入力
4pin  MCLR
5pin  RC5 x
6pin  RC4 x
7pin  RC3 LCDデータ(D7) 出力
8pin  RC2 LCDデータ(D6) 出力
9pin  RC1 LCDデータ(D5) 出力
10pin RC0 LCDデータ(D4) 出力
11pin RA2 LCD E 出力
12pin PGC
13pin PGD
14pin VSS

【ソースコード抜粋】


//───────────────────────────────────
//    ポート初期設定
//───────────────────────────────────
void init_port(void)
{
    PORTA = 0x00;
    TRISA = 0b00010000; // 1:入力、0:出力設定
    ANSELA = 0b00010000; // RA4:A/D入力
    PORTC = 0x00;
    TRISC = 0b00100000; // 1:入力、0:出力設定

    ADCON0 = 0b00001100; // AN3指定
    ADFM = 1;             // A/D Result Format Right justified
    ADON = 1;            // A/D On
}

//───────────────────────────────────
//    A/D変換 10bit結果取得
//───────────────────────────────────
unsigned int read_a2d( void )
{
    unsigned int tmpData;

    GODONE = 1;        // initiate conversion on the selected channel
    while(GO_nDONE)
    {
        continue;
    }
    tmpData = ADRESL;
    tmpData |= (ADRESH<<8)&0x0300;
    return(tmpData);   // return 10bit result
}

//───────────────────────────────────
//    定数/型定義
//───────────────────────────────────

// 各距離での電圧値(10bit)
typedef enum
{
    DISTANCE_80 = 78,
    DISTANCE_70 = 88,
    DISTANCE_60 = 101,
    DISTANCE_50 = 121,
    DISTANCE_40 = 148,
    DISTANCE_30 = 183,
    DISTANCE_20 = 263,
    DISTANCE_15 = 332,
    DISTANCE_10 = 469,
    DISTANCE_05 = 641
} IR_DISTANCE;


// 各距離での傾き(cm/V)
typedef enum
{
    TILT_80 = 218,
    TILT_70 = 158,
    TILT_60 = 103,
    TILT_50 = 76,
    TILT_40 = 58,
    TILT_30 = 26,
    TILT_20 = 15,
    TILT_15 = 7,
    TILT_10 = 6
} IR_TILT;


// 各距離での基準距離(cm)
typedef enum
{
    BASE_80 = 164,
    BASE_70 = 138,
    BASE_60 = 111,
    BASE_50 = 95,
    BASE_40 = 82,
    BASE_30 = 53,
    BASE_20 = 39,
    BASE_15 = 27,
    BASE_10 = 24
} IR_BASE;

//───────────────────────────────────

const IR_DISTANCE DISTANCE[]={
    DISTANCE_80,DISTANCE_70,DISTANCE_60,DISTANCE_50,DISTANCE_40,
    DISTANCE_30,DISTANCE_20,DISTANCE_15,DISTANCE_10,DISTANCE_05};

const IR_TILT TILT[]={
    TILT_80,TILT_70,TILT_60,TILT_50,TILT_40,TILT_30,TILT_20,TILT_15,TILT_10};

const IR_BASE BASE[]={BASE_80,BASE_70,BASE_60,BASE_50,BASE_40,
    BASE_30,BASE_20,BASE_15,BASE_10};

//───────────────────────────────────
//    距離計算 (cm)
//───────────────────────────────────
unsigned short read_distance( void )
{
    unsigned short tmpAD;
    unsigned short tmpData;
    unsigned char  i;

    // A/D値取得
    tmpAD = read_a2d();

    if( tmpAD < DISTANCE[0] )
    {
        return( 0xffff );            // 80cm以上
    }
    else
    {
        for( i = 1; i < 10; i++ )
        {
            if( tmpAD < DISTANCE[i] )
            {
                tmpData = tmpAD * TILT[i-1];
                tmpData /= 205;           // 10bit/5V = 1024/5
                tmpData = BASE[i-1] - tmpData;
                return( tmpData );        // 計算値(cm)
            }
        }
    }
     return( 0x0000 );            // 範囲外
}


関連記事