2015年08月26日

マイコン

GROVE スターターキット for mbed の使い方(赤外線リモコンと赤外線受信モジュール編)

こんにちは。 今回は前回予告した、赤外線リモコンと赤外線受信モジュールの使い方を簡単に解説し、リモコン操作で3色LEDを制御するサンプルコードを作ってみたいと思います。

 

赤外線通信の仕組み と 赤外線リモコンの使い方

赤外線通信の仕組みについてご存じない方のため、簡単に説明します。
赤外線通信とは、電気の代わりに赤外線と呼ばれる非可視光線を使って行う近距離無線通信です。 テレビのリモコンなどの通信に用いられています。

装置の仕組みは簡単で、送信側(リモコン)はボタンが押されるとそのボタンに応じたビットパターンに合わせて赤外線LEDを一定周期で点滅させます。受信側(赤外線センサ)は送信側の赤外線の点滅を受け取り、電気信号に戻します。マイコンは受信側の電気信号を解析することで、ビットパターンに応じた制御を行うことができます。

リモコンの出力するビットパターン(通信フォーマット)は規格化されており、今回使用する「GROVE スターターキット for mbed」についてきたリモコンの通信フォーマットは「NECフォーマット」となっています。

Tips: NECフォーマットの詳細についてはルネサスの以下のサイトを参照してください。

http://japan.renesas.com/support/faqs/faq_results/Q1000000-Q9999999/mpumcu/com/remo_012j.jsp
NECフォーマットのリモコンのボタンを押すと、リーダコード、カスタマーコード、データコードの順にデータが送られます。 このうちリモコンの制御に重要なコードはカスタマーコードとデータコードです。

 

カスタマーコードはリモコンメーカーを識別するために使用する16bitのコードです。 今回使用するリモコンでは0×0000が設定されています。

データコードはボタンを表す8bitのコードとコードの反転値8bitが合わさった16bitのコードです。 このコードを読み取ることで、どのボタンが押されたかの判断ができます。 今回使用するリモコンでは、次のような割り当てになっています。

 

mbed 赤外線通信ライブラリの使い方

次にmbedで赤外線通信を行う方法を説明します。

mbedでは赤外線通信を行うためのIR Libraryが提供されており、このライブラリを用いることで簡単に赤外線通信プログラムが作れます。

まずは以下のページにアクセスし、空のプロジェクトにライブラリをインポートしてください。

IR Library

今回は送信側に赤外線リモコンを用いるので、受信側のプログラムを作成します。

 

API説明

赤外線通信の受信側プログラムの作成には、ReceiverIRクラスを用います。

APIの詳細は以下のページにまとまっているので、こちらを参照してください。

ReceiverIR Class Reference

 

プログラムの流れ

受信側のプログラム制御の流れは、次のようになります。

コンストラクタに使用するピン番号を入れ、ReceiverIRクラスのインスタンスを作成
getStateメソッドの戻り値が ReceiverIR::Received になるまで待機
getData を使って通信フォーマットとコードを取得
コードからメーカーコードとデータコードを取り出し、制御を行う
サンプルプログラム

次にサンプルプログラムを動かし、実際の動作を確認してみます。

以下のコードをIR Libraryをインポートしたプロジェクトのmain.cppに上書きしてください。

#include "mbed.h"
#include "ReceiverIR.h"
#include <stdint.h>

Serial pc(USBTX, USBRX);
DigitalOut myled(LED1);

int main() {
    // ポートD6を赤外線受信モジュールの接続先に指定
    ReceiverIR ir_rx(D6);
    RemoteIR::Format format;
    uint8_t buf[32];
    uint32_t bitcount;

    // シリアル出力のボーレートを115200bpsに設定
    pc.baud(115200);

    pc.printf("start\n");
    
    while(1){
        // 受信待ち
        if (ir_rx.getState() == ReceiverIR::Received) {
            pc.printf("get ir data\n");
            // コード受信
            bitcount = ir_rx.getData(&format, buf, sizeof(buf) * 8);
            if(bitcount < 1){
                // ビット数0のものは無視
                continue;
            }
            // 受信コード出力
            pc.printf("code: ");
            for(int i=0;i<(bitcount>>3);i++){
                pc.printf("%02x",buf[i]);
            }
            pc.printf("\n");
        }
    }
}

main文の最初に行うのは、ReceiveIRインスタンスの生成です。

ReceiverIR ir_rx(D6);

 

コンスタラクタには赤外線受信モジュールの接続先を指定します。 今回はD6ポートに接続しました。

注意: サンプルではインスタンスの生成をmain文の外に書いてあるものが多いですが、Nucleo F401 ではエラーが起こるので、必ずmain文内に書いてください。

参考URL: https://developer.mbed.org/forum/wiki-IR-cookbook-forum/topic/5240/
次にフォーマットを入れる列挙型変数format、受信したコードを格納するbuf、受信したコードのビット長を格納するbitcount変数を定義します。

RemoteIR::Format format;
uint8_t buf[32];
uint32_t bitcount;

次に無限ループを作り、受信待ちを行います。

while(1){
    // 受信待ち
    if (ir_rx.getState() == ReceiverIR::Received) {

受信を検知したら、getDataメソッドを使ってデータの受信を行います。

// コード受信
bitcount = ir_rx.getData(&format, buf, sizeof(buf) * 8);

 

getDataメソッドの引数は前から順に、RemoteIR::Format型変数のアドレス、受信バッファのアドレス、受信バッファのサイズ、を指定します。 戻り値には実際に受信したビット数が返ってきます。

受信したコードはbufに入るので、bitcount変数の値を使ってfor文で出力します。

// 受信コード出力
pc.printf("code: ");
for(int i=0;i<(bitcount>>3);i++){
    pc.printf("%02x",buf[i]);
}
pc.printf("\n");

 

このプログラムを動かすと以下のように受信したメーカーコードとデータコードが出力されます。 例えば今回、一番左上の電源ボタンを押すと、メーカーコードは0x00ff, データコードには0x45baが出力されます

code: 0x00ff45ba

 

赤外線リモコンを使った3色LED制御プログラムの作成

先ほどのサンプルプログラムをちょっといじって、リモコン入力に合わせて3色LEDの色を制御するプログラムを作ってみます。

ハードの方は前回に引き続き、D4端子に3色LEDを接続し、D6端子に赤外線受信モジュールを接続します。

プログラムの作り方は簡単で、ChainableLEDのライブラリをインポートしたあと、先ほど受信コードをprintしていた部分を書き換え、データコードの入ったbuf[2]の値を見て制御を行えば良いだけです。

以下に修正を行ったmain.cppのコードを示します。

#include "mbed.h"
#include "ReceiverIR.h"
#include "ChainableLED.h"
#include <stdint.h>

Serial pc(USBTX, USBRX);
DigitalOut myled(LED1);
ChainableLED cled(D4,D5,1);

int main() {
    ReceiverIR ir_rx(D6);
    pc.baud(115200);
    RemoteIR::Format format;
    uint8_t buf[32];
    uint32_t bitcount;
    pc.printf("start\n");
    
    while(1){
        // 受信待ち
        if (ir_rx.getState() == ReceiverIR::Received) {
            pc.printf("get ir data\n");
            // コード受信
            bitcount = ir_rx.getData(&format, buf, sizeof(buf) * 8);
            if(bitcount < 1){
                // リピート信号は無視
                continue;
            }

            // LED点灯
            uint8_t code = buf[2];
            switch(code){
                case 0x0c:
                    // push 1
                    cled.setColorRGB(0, 255,0,0);
                    break;
                case 0x18:
                    // push 2
                    cled.setColorRGB(0, 0,255,0);
                    break;
                case 0x5e:
                    // push 3
                    cled.setColorRGB(0, 0,0,255);
                    break;
                default:
                    ;
            }
        }
    }
}

このプログラムを動かした状態でリモコンのボタン1,2,3を押すと、LEDを赤、緑、青に変化させる事ができます。

 

おわりに

今回はGroveモジュールの赤外線受信モジュールと赤外線リモコンを使った制御方法を説明しました。

赤外線通信が使えるようになると、例えば電子ボリュームの制御などをリモコンで行えるようになるなど、非常に便利です。 この記事が皆様の工作の助けになれば幸いです。

 

 

作者

作者: 西永俊文

Twitter: tnishinaga

協力: マルツエレック株式会社

この 作品 は クリエイティブ・コモンズ 表示 – 改変禁止 4.0 国際 ライセンスの下に提供されています。

 

ページトップへ