ソースに絡まるエスカルゴ

貧弱プログラマの外部記憶装置です。

【ESP32】赤外線通信について

 ESP32で赤外線を使って色々やってみようと思ったですが、ArduinoUnoで使えていたライブラリ等がESP32ではまだないようです。
 色々調べて行くとライブラリを使わずに赤外線通信を行なっている記事を見つけたので、それを元にESP32で動かした時のことを備忘録として記録しておきます。


・2017/06/27追記:より実用的な方法の記事を書きました
rikoubou.hatenablog.com



1:材料
 今回自分が使ったのは以下のものですが、すべての材料は安いものでも大丈夫だと思います。

・赤外線LED
3φ砲弾型赤外線LED 940nm LIR034の通販ならマルツオンライン

・赤外線受光器
リモコン受光モジュール RPM7138-Rの通販ならマルツオンライン

・適当な単色LED
・ESP32-DevKitC×2
・単3電池ボックス(必要に応じて)
・200Ω程度の抵抗×2
・ブレッドボード×2


2:受信側について
・プログラム

#define READ_PIN 26
#define LOW_STATE 0
#define HIGH_STATE 1
 
void setup(){
  Serial.begin(115200);
  pinMode(READ_PIN,INPUT);
 
  Serial.println("Ready to receive");
}
 
void waitLow() {
  while (digitalRead(READ_PIN)==LOW) {
    ;
  }
}
 
int waitHigh() {
  unsigned long start = micros();
  while (digitalRead(READ_PIN)==HIGH) {
    if (micros() - start > 5000000) {
      return 1;
    }
  }
  return 0;
}
 
unsigned long now = micros();
unsigned long lastStateChangedMicros = micros();
int state = HIGH_STATE;
 
void loop() {
    if (state == LOW_STATE) {
      waitLow();
    } else {
      int ret = waitHigh();
      if (ret == 1) {
        Serial.println("");
        return;
      }
    }
 
    now = micros();
    Serial.print((now - lastStateChangedMicros) / 10, DEC);
    Serial.print(",");
    lastStateChangedMicros = now;
    if (state == HIGH_STATE) {
      state = LOW_STATE;
    } else {
      state = HIGH_STATE;
    }
}

 基本的には参考記事にあるものそのままです。

 回路は、材料にあげたのと同じものを使うのであれば、以下の赤外線受光器のデータシートにあるように繋ぎます。
f:id:rikoubou:20170612140529p:plain

 シリアルモニタを立ち上げてESP32のリセットボタンを押すと、「Ready to receive」が表示されます。
 この状態で赤外線受光器にリモコンを向けてボタンを押すと数値の羅列が表示され、受信できていることが確認できます。


3:送信側について
・プログラム

const int IR_SEND_PIN = 33; // 赤外線LEDのピン
const int LED_PIN = 25;     // LEDのピン

// 送信データ
unsigned int data[] = {1000,2000,3000,4000,5000,6000,7000};

void setup() {
  pinMode(IR_SEND_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_PIN, HIGH);
  sendSignal(); // 赤外線信号を送信
  digitalWrite(LED_PIN, LOW);
  delay(3000);
}

// dataの赤外線信号を送信
void sendSignal() {
  int dataSize = sizeof(data) / sizeof(data[0]);
  for (int cnt = 0; cnt < dataSize; cnt++) {
    unsigned long len = data[cnt]*10;
    unsigned long us = micros();
    do {
      digitalWrite(IR_SEND_PIN, 1 - (cnt&1));
      delayMicroseconds(8);
      digitalWrite(IR_SEND_PIN, 0);
      delayMicroseconds(7);
    } while (long(us + len - micros()) > 0); // 送信時間に達するまでループ
  }
}

 こちらも参考記事にあるものほぼそのままです。

 回路図も書くほどではないので省きます。LEDの足の長い方と出力ピンの間に抵抗を入れ、足の短い方をGNDに繋ぐだけです。
 単色LEDは赤外線が送信されていることを肉眼で確認するためです。


4:送受信の確認
 受信側、送信側のどちらも準備ができたら、両方とも電源を入れて赤外線LEDが赤外線受光器に当たるようにします。
 すると以下のような値が受信側のシリアルモニタに表示されるはずです。(以下の例では2回送信しています)
f:id:rikoubou:20170612141632p:plain

 一番最初の大きな値は無視します。それ以降はdataに設定した値とほぼ同じ値が送信されていることがわかります。
 何度か試した感じでは、誤差は最大で±20程度のようです。またdataとして送る一つの信号の長さは長い方が(1000以上ぐらい)の方が良いようです。


 以上、ESP32を使っての赤外線通信についてでした。


■参考記事
Arduinoで赤外線リモコンの信号を解析する
Arduinoで赤外線リモコン信号を発信する