スタートアップエンジニアの作ってみた日記

ものづくりが下手な横好きなエンジニアによる作ってみた的なブログです。

ESP32を使ってIoTデバイスを作ってみた。その3(赤外線LEDにて家電の操作)

ESP32を使っての第3弾ということで、今回は赤外LEDを発光させて家のエアコンを操作してみたいと思います。

 

家電によって赤外の信号は異なるので、信号を受信して学習するところもやっていきます。

 

■必要なもの

・赤外LED

秋月電子で購入できます。  http://LED(http://akizukidenshi.com/catalog/g/gI-03261/

・フォトトランジスタ

こちらも秋月電子で購入可能です。 http://LED(http://akizukidenshi.com/catalog/g/gI-03261/

・抵抗 20KΩ

・その1、その2で作った回路

 

■赤外信号の学習

まずは家にあるリモコンの信号を学習するところを作ります。

フォトトランジスタを使って以下の回路を作ってください。

f:id:goengine:20190623135811p:plain

フォトトランジスタは、トランジスタのベースが光になったもので、光(今回は赤外光)を受けると電気が流れます。(詳細を知りたい方は各自フォトトランジスタの原理を参照してください。)

 

これによって光を受けると、35ピンに5Vが入力されます。

 

 

 では次にESP32に以下のコードを書き込みましょう。

#define READ_PIN 35
#define LOW_STATE 0
#define HIGH_STATE 1

void setup() {
  Serial.begin(115200);
  pinMode(READ_PIN, INPUT);
  //pinMode(4, OUTPUT);

  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.print("\n");
      return;
    }
  }

  now = micros();
  Serial.print((now - lastStateChangedMicros) / 10, DEC);
  Serial.print(",");
  lastStateChangedMicros = now;
  if (state == HIGH_STATE) {
    state = LOW_STATE;
  } else {
    state = HIGH_STATE;
  }
}

 

上記のコードは35ピンのHigh,Low状態の変化を受けると、それまでの時間を計算して表示するというものです。

 

では、Arduinoのシリアルモニタを出した状態でフォトトランジスタに向かって手持ちのリモコンを向けて、何かボタンを押してみましょう。

f:id:goengine:20190623144720p:plain

 

するとシリアルモニタに以下のような数字が出てきます。

f:id:goengine:20190623144906p:plain

これの一番初めの大きい数字を除いた数字をメモ帳などにコピペして保存しておきましょう。

この数字は後程の赤外信号を生成するところで使います。

 

これでリモコンの信号の学習は完了です。

 

■赤外線信号の生成

次にさきほどの取得した信号をESP32と赤外LEDを使って生成し、家の家電を操作してみましょう。

回路はその1の記事をご参照ください。

こちらの記事に書かれている回路のLEDのところを今回用意した赤外LEDにするだけです。 

https://goengine.hatenablog.com/entry/2019/05/26/141312

 

それでは、ESP32にコードを書き込みましょう。

#include <WiFi.h>

const char* ssid = "******"; //ご自分のルーターのSSIDに書き換えてください。
const char* password = "******"; //ご自分のルーターのパスワードに書き換えてください。

//先ほど学習した信号情報をコピーする
int data_on[] = {337,143,58,21,58,102,58,21,58,21,58,102,57,21,58,102,57,21,58,21,58,102,54,102,55,102,54,21,58,102,54,21,58,102,54,102,54,102,54,22,58,22,58,22,57,22,57,104,55,104,55,22,58,104,55,22,57,104,55,104,55,22,57,22,57,22,57,104,55,22,57,104,55,22,58,22,58,104,55,102,54,102,54,21,58,102,54,102,54,21,58,102,54,102,54,102,54,102,54,102,57,21,58,21,58,102,54,21,58,21,58,21,58,21,58,102,57,102,57,102,57,21,58,102,57,102,58,102,58,101,58,21,58,21,58,21,58,102,58,21,58,21,58,21,58,21,58,102,57,21,58,102,58,102,58,101,58,101,58,101,58,101,58,19,57,102,58,19,57,19,57,19,57,21,58,21,58,19,57,101,58,101,58,101,58,101,58,101,58,101,58,101,58,101,58,19,60,19,60,19,60,19,60,19,60,19,60,19,60,19,61,101,58,101,58,101,59,18,61,101,59,100,59,100,59,101,58,18,61,18,61,18,62,100,59,18,61,18,61,18,61,18,61,100,59,100,59,100,59,98,58,98,58,98,61,18,61,98,58,19,61,18,61,18,61,18,61,18,61,18,61,98,58,18,61,98,61,98,61,18,61,98,61,98,61,98,61,98,61,18,61,18,61,18,61,98,61,18,61,18,61,18,61,18,61,98,58};
int data_off[] = {314, 166, 34, 45, 34, 125, 34, 45, 34, 46, 34, 125, 34, 45, 34, 125, 34, 45, 34, 46, 34, 125, 34, 125, 34, 126, 34, 45, 34, 125, 34, 45, 34, 125, 34, 126, 34, 125, 34, 45, 34, 45, 34, 45, 34, 45, 34, 125, 34, 125, 34, 45, 34, 125, 34, 45, 34, 125, 34, 126, 34, 45, 34, 46, 33, 45, 34, 126, 34, 45, 34, 125, 34, 45, 34, 45, 34, 125, 34, 126, 34, 126, 34, 125, 34, 126, 34, 45, 34, 125, 34, 125, 34, 126, 34, 126, 34, 125, 34, 45, 34, 46, 33, 126, 34, 45, 34, 46, 34, 45, 34, 46, 33, 45, 34, 126, 34, 126, 34, 126, 34, 45, 33, 125, 35, 124, 34, 125, 34, 125, 34, 46, 33, 46, 33, 45, 34, 125, 34, 45, 34, 45, 34, 45, 34, 45, 34, 125, 34, 45, 34, 126, 34, 126, 34, 125, 34, 125, 34, 125, 34, 128, 31, 45, 34, 126, 34, 45, 34, 46, 33, 46, 33, 46, 33, 46, 33, 46, 34, 125, 34, 125, 34, 125, 34, 124, 34, 125, 34, 125, 34, 125, 34, 125, 34, 45, 34, 45, 34, 45, 34, 45, 34, 46, 34, 46, 34, 45, 34, 45, 34, 125, 34, 125, 34, 125, 34, 46, 34, 125, 34, 125, 34, 125, 34, 125, 34, 45, 34, 45, 34, 46, 33, 125, 34, 45, 34, 46, 34, 45, 34, 45, 34, 125, 34, 125, 34, 127, 32, 125, 34, 126, 34, 124, 34, 46, 41, 118, 34, 46, 34, 46, 33, 46, 34, 45, 34, 45, 34, 46, 34, 125, 34, 46, 34, 125, 34, 125, 34, 45, 34, 125, 34, 126, 34, 126, 34, 125, 34, 45, 34, 46, 34, 45, 34, 125, 34, 45, 34, 45, 34, 46, 33, 45, 34, 126, 34};

int IR_SEND_PIN = 27; // 赤外線LEDのピン

const char* host = "******";//作成したサイトのURLを入れる。http://は不要

int on_off_flag = 2;

void setup() {
  Serial.begin(115200);
  delay(10);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  // 出力に設定
  pinMode(IR_SEND_PIN, OUTPUT);
}

void loop() {
  delay(100);

  Serial.print("connecting to ");
  Serial.println(host);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  // We now create a URL for the request
  String url = "/stateGet.php";

  Serial.print("Requesting URL: ");
  Serial.println(url);

  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  int timeout = millis() + 5000;
  while (client.available() == 0) {
    if (timeout - millis() < 0) {
      Serial.println(">>> Client Timeout !");
      client.stop();
      return;
    }
  }

  // Read all the lines of the reply from server and print them to Serial
  int i = 0;
  int flag_temp = on_off_flag;
  while (client.available()) {
    String line = client.readStringUntil('\r');
    if (i == 8) {
      if (line.lastIndexOf("OFF") == -1) {
        Serial.println("on");
        on_off_flag = 0;
      } else {
        Serial.println("off");
        on_off_flag = 1;
      }
      break;
    }
    i++;
  }
  if (flag_temp != on_off_flag) {
    if (on_off_flag == 0) {
      sendSignal(data_on, sizeof(data_on) / sizeof(data_on[0]));
    } else {
      sendSignal(data_off, sizeof(data_off) / sizeof(data_off[0]));
    }
  }

  Serial.println();
  Serial.println("closing connection");
}

void sendSignal(int data1[], int num) {
  int dataSize = num;
  int j = 0;
  for (int cnt = 0; cnt < dataSize; cnt++) {
    unsigned long len = data1[cnt] * 10;
    unsigned long us = micros();
    //Serial.println(len);
    do {
      digitalWrite(IR_SEND_PIN, 1 - (cnt & 1));
      delayMicroseconds(8.8);
      digitalWrite(IR_SEND_PIN, 0);
      delayMicroseconds(17.5);
      //Serial.println(j);
    } while (long(us + len - micros()) > 0); // 送信時間に達するまでループ
    //digitalWrite(IR_SEND_PIN, 0);
  }
}

こちらの配列data_onやdata_offのところに先ほどメモ帳にコピーした数列を入力してください。

 

また、Wifiの設定やサイトのURLなどは適宜、変更してください。

 

こちらのコードはその2で作ったwebサイトからon,offのボタンを押すと押された時だけ、on,offの信号を出力するコードになっています。

 

これで以下のようにブラウザから家電を操作できるようになります。

 

 

今回はこちらのサイトを参考にさせて頂きました。

ありがとうございました。

https://www.erestage.com/arduino/remo_recv/

https://www.erestage.com/arduino/arduino-send-remo/

 

以上です。