赤外線通信の実験パート2
(赤外線リモコンを送信器にして何か動かす)

〔パート1〕 〔マイコンのトップに戻る〕


前回の記事では、赤外線を利用しマイコン間でデータを送受信する通信の話でしたが、
このページでは、何処の家庭でも有るであろう赤外線リモコンからデータを受信して何かを動かします
何か......それは、あなたのアイデア次第です、
例えば、ラジコンがわりにしたり、ランプを点灯したり等のスイッチがわりに使用したり出来ます。
ここでは、赤外線リモコンからデータを受信する仕掛けの部分を紹介します。
だからぁ、送信器は通常の赤外線リモコンでぇ、受信器のみ作ります。

送信データのフォーマット
フォーマット図22
通信データフォーマットの記事はこちらを参照しましょう。


今回の受信スケッチプログラムではこのNEC系フォーマットで受信します、
なのでSONY系フォーマットのリモコンは受信できません。
また、赤外線リモコンによってはリーダ部の無い送信データフォーマットを採用している場合が
有ります、この場合も、このプログラムでは受信できません。

PS. NEC系・SONY系・家電製品協会フォーマットに対応した記事に書き加えます。 *6)

赤外線リモコンのボタンを押すと、押すボタンに対応してデータ部の一部が変わる場所が有ります
その変化場所のデータを取り出してしまおうと言うわけです。
それと、ボタンを押しっぱなしにすると、同じ送信データを繰返し送るリモコンと、
リーダ部+ストップビットのみ繰返し送る(リピートコード)リモコンが有ります。

PS. *5)
リモコンによっては、ボタンにより繰り返す回数が決まっている物が有ります、
例えばELPAのTVリモコンはチャンネルボタンは押しっぱなしでも3回しか繰り返さないが、
ボリュームボタンは押している間ず〜っとぉ繰り返し同じ送信データを送り続けます。

下の図は「panasonic蛍光灯のリモコン」からの送信内容をロジックアナライザに表示させた物です。 *2)
送信側リモコンから送られた信号は、受信モジュールで反転されてマイコンに入力されます
ですので下記図は反転された波形が表示されています。 (画像をクリックすれば拡大表示されます)

リモコン受信波形図1

リモコン受信波形図2

データ部のビット1/0判断は、LOW部分長の長さよりHIGH部分が約3倍程長い波形が1となります。
尚、上記図で記載の波形の長さは「panasonic蛍光灯のリモコン」での長さで有り、リモコンにより長さは変わります。
(NEC系フォーマットの基本規格はこちらですが、波形長やデータ仕様などメーカによってまちまちです)

赤外線受信のサンプル回路
配線図21

今回のこの回路では赤外線リモコンからの受信データはarduinoIDEのシリアルモニタ画面に表示します、 通常はデータ内容によりモータを回したり、LEDを点灯させたりの回路を追加して動かす事になります。
また、今回はとりあえずぅ、arduinoを使用します、PICは.....どうしようかなぁ?

赤外線受信モジュール
IR 秋月通商のこちらで購入できます。
低電圧で駆動したい場合はこちらあたりですかね。

上の回路では取付けていませんが、実際に半田付けして回路を作る場合は端子の
GNDと5V間にCR回路(データシート参照)を取り付けて下さい。

《赤外線リモコンの送信データを探る》

下のスケッチで赤外線リモコンのデータを調べます。

@上記の回路の様に配線を行います。

Aarduinoボード(Arduino Duemilanove 328)はUSBケーブルで接続してarduino IDEを起動させます。

BIDEに下記のスケッチプログラムをコピーペーストして貼り付けて下さい。
 このスケッチ(NEC系・家製協フォーマット)をダウンロードしたい方はこちら
 ダウンロードスケッチの保存先と開き方はこちらを参照下さい。
---------------------------------------------------------------------
// 赤外線リモコンの"NEC系フォーマット"と"家電製品協会フォーマット"に対応 *6)
// 《赤外線リモコンの送信データを探る》
//
#define IRpin       2    // 赤外線受信モジュール接続ピン番号

// 初期化処理
void setup()
{
     Serial.begin(9600) ; // パソコン(ArduinoIDE)とシリアル通信の準備を行う
     pinMode(IRpin,INPUT) ; // 赤外線受信モジュールに接続ピンをデジタル入力に設定
}
// メインの処理
void loop()
{
     unsigned long t ;
     int i ;
     char IRbit[512] ;
     static int pre_val ;

     t = 0 ;
     if (digitalRead(IRpin) == LOW) {
          // リーダ部のチェックを行う
          t = micros() ;                      // 現在の時刻(us)を得る
          while (digitalRead(IRpin) == LOW) ; // HIGH(ON)になるまで待つ
          t = micros() - t ;                  // LOW(OFF)の部分を測る
     }
     // リーダ部有りなら処理する(2.8ms以上のLOWにて判断する)
     if (t >= 2800) {
          i = 0 ;
          while(digitalRead(IRpin) == HIGH) ; // ここまでがリーダ部(ON部分)読み飛ばす
          // データ部の読み込み
          while (1) {
               while(digitalRead(IRpin) == LOW) ; // OFF部分は読み飛ばす
               t = micros() ;
               while(digitalRead(IRpin) == HIGH) ;// ON部分の長さを測る
               t = micros() - t ;
               //Serial.println(t); // ON部分時間表示(debug用)
               if (t >= 8000) break ;             // ストップデータ
               if (t >= 1000)  IRbit[i] = (char)0x31 ;  // ON部分が長い
               else            IRbit[i] = (char)0x30 ;  // ON部分が短い
               i++ ;
          }
          // データ有りなら表示を行う
          //Serial.print("bit kosu = ");
          //Serial.println(i);      // ビットの個数表示(debug用)
          if (i != 0) {
               IRbit[i] = 0 ;
               DspData(i,IRbit) ;
          }
     }
}
// 受信データをシリアルモニタ画面に送り表示をさせる処理
void DspData(int num,char *data)
{
     int i , j , x , dt ;
     
      Serial.print(data) ;    // ビットデータで表示
      Serial.write(" ( ") ;
      x = num / 8 ;
      // ビット文字列データから数値に変換する
      for (j=0 ; j < x ; j++) {
           dt = 0 ;
           for (i=0 ; i < 8 ; i++) {
                if (*data++ == 0x31) bitSet(dt,i) ;
           }
           Serial.print(dt,HEX) ; // HEX(16進数)で表示
           Serial.write(' ') ;
      }
      Serial.println(')') ;     
}
---------------------------------------------------------------------
CIDEツールバーの赤枠部分「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを
 行います。

upload

D正常終了後、ArduinoIDEのシリアルモニタを起動します。
 尚、シリアルモニターの使い方はこちらを参照下さい。

E赤外線リモコンを押してみて下さい。

COM画面23

四角の赤枠部分がボタンを押す事により値が変わっていますので、この部分(5個目のデータ)を
利用する事にします。(リモコンによりデータ内容や場所は変わります、念のため)

上の実行画面で、"0101 0101 0101 1010 1111 0001.......(AA 5A 8F...)"と有りますが、
実際は(55 5A F1...)が本来の16進内容です、ここではLSB/MSBがひっくり返って作っています。*2)

《赤外線リモコンからデータを受信する》

上で調べた変化する部分のデータを、下のスケッチで受信します。
受信したデータはシリアルモニタ画面に表示しています。
上で調べた変化する部分は5個目のデータですので、
変更する場所は、
#define DATA_POINT  5     // 受信したデータから読取る内容のデータ位置
を変えます。

下のスケッチ(NEC系・家製協フォーマット)をダウンロードしたい方はこちら
ダウンロードスケッチの保存先と開き方はこちらを参照下さい。
---------------------------------------------------------------------
// 赤外線リモコンの"NEC系フォーマット"と"家電製品協会フォーマット"に対応 *6)
// 《赤外線リモコンからデータを受信する》
//
#define IR_PIN      2        // 赤外線受信モジュール接続ピン番号
#define DATA_POINT  5        // 受信したデータから読取る内容のデータ位置

// 初期化処理
void setup()
{
     Serial.begin(9600) ;    // パソコン(ArduinoIDE)とシリアル通信の準備を行う
     pinMode(IR_PIN,INPUT) ; // 赤外線受信モジュールに接続ピンをデジタル入力に設定
}
// メインの処理
void loop()
{
     int ans ;

     ans = IRrecive() ;                      // 赤外線リモコンのデータを受信する
     if (ans != 0) Serial.println(ans,HEX) ; // リモコンからデータを受信したら表示する
}
// 赤外線リモコンのデータを受信する処理関数
int IRrecive()
{
     unsigned long t ;
     int i , j , ans ;
     char IRbit[512] ;
     static int pre_val ;

     ans = 0 ;
     t = 0 ;
     if (digitalRead(IR_PIN) == LOW) {
          // リーダ部のチェックを行う
          t = micros() ;                       // 現在の時刻(us)を得る
          while (digitalRead(IR_PIN) == LOW) ; // HIGH(ON)になるまで待つ
          t = micros() - t ;                   // LOW(OFF)の部分を測る
     }
     // リーダ部有りなら処理する(2.8ms以上のLOWにて判断する)
     if (t >= 2800) {
          i = 0 ;
          while(digitalRead(IR_PIN) == HIGH) ; // ここまでがリーダ部(ON部分)読み飛ばす
          // データ部の読み込み
          while (1) {
               while(digitalRead(IR_PIN) == LOW) ; // OFF部分は読み飛ばす
               t = micros() ;
               while(digitalRead(IR_PIN) == HIGH) ;// ON部分の長さを測る
               t = micros() - t ;
               if (t >= 8000) break ;             // ストップデータ
               if (t >= 1000)  IRbit[i] = (char)0x31 ;  // ON部分が長い
               else            IRbit[i] = (char)0x30 ;  // ON部分が短い
               i++ ;
          }
          // データ有りなら指定位置のデータを取り出す
          if (i != 0) {
               i = (DATA_POINT-1) * 8 ;
               for (j=0 ; j < 8 ; j++) {
                    if (IRbit[i+j] == 0x31) bitSet(ans,j) ;
               }
               pre_val = ans ;     // データを記憶して置く
          } else {
               // リピートコードと見なす
               ans = pre_val ;     // 記憶して置いたデータを返す
          }
     }
     return( ans ) ;
}
---------------------------------------------------------------------

COM画面24

と、こんな感じに表示されると思います。

だからぁ、例えばぁこんな感じでぇ、利用しましょう
     ans = IRrecive() ; // 赤外線リモコンのデータを受信する
     if (ans != 0) {
          switch(ans) {
           case 0x20: // LEDを点灯する
                    break ;
           case 0xd8: // LEDを消灯する
                   break ;
           case 0xd7: // モータをON
                   break ;
           case 0x57: // モータをOFF
                   break ;

          }
     }
あ、これで、モータを制御する方法は次回の記事で予定、って言うかぁ、予定は未定みたいなぁ
でもぉ、今回の記事ではスイッチ的にしか制御できないのですよぉ、
例えば[UP]ボタンを押す毎にモータの回転を上げて行き、[DOWN]ボタンで下げて行くみたいなぁ感じぃ
ジョイステックの様にアナログの変化量が送れないよねぇ?

NEC系・家製協フォーマットの話 *6)

リピートコードは、NEC系にしか存在しませんが、今回の変更で対応して置きました。
今回、日立エアコンのリモコンがあったので家製協フォーマットも動作する様にしましたが...
データの数が多いのと可変長になっている様で、同じボタンを押しても内容が変化している感じです、
ボタンに付随して他のデータも送っている様な気がしています。
その中でも12個目のデータがボタン固有の内容の様でぇ、利用出来るようです。

SONY系フォーマットの話 *6)

SONY系フォーマットのダウンロードをしたい方はこちら
SONYのリモコンで使ったのは、古いビデオテープデッキ時代のリモコンなので現在のが
動作するかは不明です。
#define DATA_POINT  1    // 受信したデータから読取る内容のデータ位置
が有りますがぁ、これは変更しないで下さい。
現在のリモコンは変更しないといけないかも不明です。


って事でぇ、後はあなたのアイデアしだいって事でぇ、がんばぁp(*^-^*)q

TVのリモコンでモータを動かして車のラジコンを操作する実験をこちらで行って見ました。*1)
(このスケッチは前のままです、変更していません)

《赤外線機器にデータを送って見る》  *3)

前ページの実験パート1で、赤外線LEDからデータを送信しました、
上記の記事ではTVのリモコンからデータをIRモジュールで受信して見ました。
なので、このデータ送信と受信の合体合わせ技のサンプルを追記して置きます、
TVリモコンからArduinoでデータを受信してそのデータ内容をTVに送信して見たいと思います。

配線図22  左図が実験のサンプル回路図で電源は
 5Vです。

 SW1/SW2のプルアップ抵抗は、
 Arduino内蔵のプルアップを使っています。
 IRモジュールの端子機能名称等は、
 使用する機器のデータシートを見ましょう。

 この回路の動作としては、
 SW1を押します、LEDが点灯、
 リモコンのボタンを押しましょう、
 データを受信して内容を記憶すれば
 LEDは消灯します、
 SW2を押せば記憶内容を赤外線LEDから
 送信します。

 注意としては上記にも書いて有る様に
 リモコンにより受信できない物が有ります。

又、ON/OFF波形の長さを固定にしているのでリモコンによってはSW2を数回押さないと
動作しないとか有ったりするでしょう。

本来なら受信したON/OFFの波形長さ等も記憶しそれを再生させる様なプログラムを
作ればモット万能なリモコンが出来るとは思うのですがぁ....
ちょっとぉ、めんどくちゃいなぁ....

サンプルスケッチ

スケッチのダウンロードはこちらから行って下さい。
(このスケッチは前のままです、変更していません)

《その他》

スイッチサイエンスのこちらに「SIS-2 プログラマブル赤外線リモコン受信チップ」なる物が有ります。
これは2種類のリモコンコードを受信し記憶させます、その後にこの何れかのコードを受信したら
それに対応した2種類の出力端子からスイッチ的にON/OFF動作させる物の様です。
これだとマイコンは要りませんね。 *4)



NEC・SONY・家製協フォーマットに対応(*6) 2021/05/30
リピートコードを受信する様にした話(*5) 2019/03/23
追記(*4) 2014/12/27
追記(*3) 2014/10/28
追記(*2) 2014/05/22
追記(*1) 2011/08/05


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2021 Shigehiro Kimura All Rights Reserved.