赤外線リモコンでGPIOを操作する


Raspberryに赤外線受光素子と赤外線発光素子をつけて、学習リモコンとして利用する例はたくさん紹介されていますが、
Raspberryそのものをリモコンで制御したり、GPIOをリモコンで制御する例はあまり(と言うかほとんど)見かけません。

私が探した範囲では、以下のページで、テレビのリモコンを使ってRaspberryをコントロールする例が紹介されています。
『テ レビのリモコンでRaspberry Piをコントロールしよう』

そこで、今回は赤外線リモコンを使ってGPIOを制御する方法を紹介します。
なお、アメリカなどではガレージの電動シャッターの開閉に、433Mhzの無線リモコンがよく使われますが、
この電波帯は日本ではアマチュア無線に割り当てられているので、使うことができません。

赤外線リモコン入手

使用する赤外線リモコンは「RW-PCM37BK」です。
AMAZONや楽天などで容易に入手可能です。
「DN-PCREMOCON」と言う型番もWEBで見る限り同じ製品です。

リモコン本体

lircのインストールとリモコンの学習

こ ちら(Raspbian Jessieの方)やこ ちら(Raspbian Stretchの方)のページを参考に、
lircのインストールとリモコンの学習を行い、irwコマンドでリモコンの確認を行います。
irrecordの使い方が少し難しいですが、分からない方は以下のファイルを「/etc/lirc/lircd.conf」として保存し、
lircdデーモンを起動した後で、irwコマンドでリモコンが認識されることを確認して下さい。

# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.0-pre1(default) on Tue Nov 26 21:54:50 2013
#
# contributed by
#
# brand:                       /home/pi/lircd.conf
# model no. of remote control:
# devices being controlled by this remote:
#

begin remote

  name  PCM37BK
  bits            8
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  one           242  1878
  zero          242   817
  ptrail        242
  pre_data_bits   8
  pre_data       0xE2
  gap          46634
  toggle_bit_mask 0x0

      begin codes
          ButtonA                  0xC4
          ButtonB                  0x44
          ButtonC                  0x84
          ButtonD                  0x04
          POWER                    0xE4
          EMAIL                    0x64
          WWW                      0xA4
          CLOSE                    0x24
          Previus                  0x38
          Next                     0x28
          Backward                 0xB8
          Forward                  0xA8
          Play                     0x98
          Stop                     0x88
          VolUp                    0xA0
          VolDown                  0x50
          UP                       0x00
          DOWN                     0x60
          LEFT                     0x90
          RIGHT                    0x20
      end codes

end remote

lircdデーモンを起動した後で、irwコマンドでリモコンを発射すると以下のように表示されます。
$ irw
000000000000e2c4 00 ButtonA PCM37BK
000000000000e2c4 01 ButtonA PCM37BK
000000000000e2c4 02 ButtonA PCM37BK
000000000000e2c4 03 ButtonA PCM37BK
000000000000e2c4 04 ButtonA PCM37BK
000000000000e244 00 ButtonB PCM37BK
000000000000e244 01 ButtonB PCM37BK
000000000000e284 00 ButtonC PCM37BK
000000000000e284 00 ButtonC PCM37BK
000000000000e284 01 ButtonC PCM37BK
000000000000e284 02 ButtonC PCM37BK
000000000000e284 03 ButtonC PCM37BK
000000000000e204 00 ButtonD PCM37BK
000000000000e204 01 ButtonD PCM37BK
000000000000e204 02 ButtonD PCM37BK
000000000000e204 03 ButtonD PCM37BK

回路図

回路図は以下のとおりです。
使用した赤外線受光モジュールは3.3V駆動が可能なTL1838で す。
最初はPL-IRM2121/PL- IRM0101を使っていましたが、動作電圧が4.5V以上なので、
こちらのモジュールに変更しました。

回路図

必要なライブラリのインストール

以下のライブラリをインストールしてください。
$ sudo apt-get install liblircclient-dev

定義ファイルとソースコード

ソースコード(lirc_sample2.c)は以下のとおりです。
なお、ソースコードは、こちらの ページを参考にさせていただきました。
このページで初めて「pinMode(Port, OUTPUT)」として設定したポートでも「digitalRead(Port)」 が できることを知りました。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <wiringPi.h>
#include <lirc/lirc_client.h>

void flipLED (int led);

#define LED1 4 // Rasp pin 16
#define LED2 5 // Rasp pin 18
#define LED3 6 // Rasp pin 22
#define ON 1
#define OFF 0
#define DEBUG 0

int main(int argc, char *argv[]){
    struct lirc_config *config;
    char *code;
    char *string;
    int ret;
    int quitFlag=0;

    if(wiringPiSetup() == -1) {
        printf("Setup Fail\n");
        exit(-1);
    }
    pinMode (LED1, OUTPUT);
    pinMode (LED2, OUTPUT);
    pinMode (LED3, OUTPUT);

    digitalWrite(LED1, OFF);
    digitalWrite(LED2, OFF);
    digitalWrite(LED3, OFF);

    if(lirc_init("irexec",1) == -1) {
        printf("lirc_init Fail\n");
        exit(-1);
    }

    if(lirc_readconfig(argc==2 ? argv[1]:NULL,&config,NULL)==0) {

        while(lirc_nextcode(&code)==0) {
if(DEBUG) printf("lirc_nextcode(): code=[%s]\n",code);
            if(code==NULL) continue;
            while((ret=lirc_code2char(config,code,&string))==0 && string!=NULL) {
if(DEBUG) printf("lirc_code2char(): ret=%d,string=[%s]\n",ret,string);
                if(strcmp (string,"LED1") == 0){
                    flipLED(LED1);
                } else if(strcmp (string,"LED2") == 0){
                    flipLED(LED2);
                } else if(strcmp (string,"LED3") == 0){
                    flipLED(LED3);
                } else if(strcmp (string,"QUIT") == 0){
                    quitFlag=1;
                }
            }
            free(code);
            if(quitFlag == 1) break;
        }
        lirc_freeconfig(config);
    }
    lirc_deinit();
    digitalWrite(LED1, OFF);
    digitalWrite(LED2, OFF);
    digitalWrite(LED3, OFF);
    exit(0);
}

void flipLED (int led){
    if(digitalRead(led)==ON) digitalWrite(led, OFF);
    else                     digitalWrite(led, ON);
}

また、以下の定義ファイルをmylircとしてソースファイルと同じディレクトリにおいてください。
button=XXXXの部分は「/etc/lirc/lircd.conf」に定義したボタン名称、config=XXXXの部分はそのボタン が押されたときに、アプリケーションに渡る文字です。
begin
 button = ButtonA
 prog   = irexec
 config = LED1
end

begin
 button = ButtonB
 prog   = irexec
 config = LED2
end

begin
 button = ButtonC
 prog   = irexec
 config = LED3
end

begin
 button = ButtonD
 prog   = irexec
 config = QUIT
end

リンク方法と起動方法は以下のとおりです。
$ cc -o lirc_sample2 lirc_sample2.c -llirc_client -lwiringPi
$ sudo ./lirc_sample2 ./mylirc

動作確認

リモコンのA、B、Cボタンを押すと、対応するLEDが点灯します。
Dボタンでプログラムを終了します。

全体
ブレッドボード

次回はリモコンで好きなコマンドを実行する方法を紹介します。

続く
...