M5StickC(ESP32)で赤外線リモコンを作ろう


M5StickCで赤外線リモコンを作ります

完成するとこんな感じになりますがこの記事では赤外線リモコンにするまでにしてAlexa対応は別の記事に分けようと思います

ハードウェア

M5StickC

M5StickC - スイッチサイエンス
https://www.switch-science.com/catalog/5517/
Arduino互換なESP32がケースに入っててボタンとディスプレイとバッテリーと赤外線LEDがついててWifiとBluetoothも使える欲張りセット

M5StackでもよいけどM5StickC,Atom Matrix,Atom liteは赤外線LEDを内蔵してるのでオススメ

赤外線LED,赤外線受信機

M5Stack用赤外線送受信ユニット - スイッチサイエンス
https://www.switch-science.com/catalog/5699/

Amazonなどで赤外線LED,赤外線受信機を売ってますが回路組むのめんどくさいしGroveに刺すだけで使えるのでこれをオススメします
308円と安いし

GroveがないESP32 Dev kitなどでもGPIOからジャンパケーブルなどで強引につなげば使えます

赤外線を受信する

まずESP32対応のIRremoteを導入します

IRremoteESP8266のサンプルからIRrecvDumpV2を開きます

IR UnitのINはGroveのG33になるのでIRrecvDumpV2のkRecvPinを33に変更してM5StickCに書き込みます

const uint16_t kRecvPin = 33;

M5StickC以外のデバイスを使う場合はそのデバイスに合わせたGPIOにしてください

スケッチが書き込めたらIR Unitに向かってリモコンを操作するとシリアルモニタに内容が表示されます

赤外線を送信する

先ほど受信した赤外線のコードを送信してみます
これはたまたま手元にあったテレビのリモコンの電源ボタンのコードです

Timestamp : 000457.310
Library   : v2.7.2

Protocol  : NEC
Code      : 0x15748B7 (32 Bits)
uint16_t rawData[67] = {9044, 4416,  642, 510,  618, 510,  616, 510,  618, 510,  618, 510,  616, 510,  616, 508,  618, 1636,  618, 510,  618, 1636,  618, 510,  618, 1636,  618, 510,  616, 1636,  618, 1636,  618, 1610,  644, 508,  618, 1636,  618, 510,  618, 508,  618, 1636,  618, 508,  618, 510,  616, 510,  616, 1638,  616, 510,  618, 1636,  618, 1636,  622, 506,  616, 1638,  618, 1636,  618, 1612,  644};  // NEC 15748B7
uint32_t address = 0xEA80;
uint32_t command = 0x12;
uint64_t data = 0x15748B7;

シリアルモニタに表示されているProtocolごとに関数が用意されているのでNECに対応した関数sendNECを使用しCodeを送信します(他にもsendSONYなどがある)


#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <M5StickC.h>

const uint16_t kIrLed = 9; // M5StickC内蔵LED

IRsend irsend(kIrLed);  // Set the GPIO to be used to sending the message.

void setup() {
  irsend.begin();
  M5.begin();
}

void loop() {
  M5.update();
  if ( M5.BtnA.wasReleased() ) {
    irsend.sendNEC(0x15748B7);
  }
  delay(1);
}

M5StickCのIR LEDはこの部分にあります

M5StickCの先端をテレビに向けてディスプレイ横のボタンを押す度に電源をON/OFFすることができます

IR Unitを使う場合はOUTのG32を使用します
ちなみにM5StickCの内蔵IRLEDよりIR Unitの方が射程距離が長いです

また、メーカーが特定できなかった場合でもrawDataを配列として書き込めば送信することができます(IRsendDemoサンプルを参照してください)

エアコンを操作する

IRremoteESP8266には各社のエアコンに対応したクラスが用意されています
たまたま手元にあったリモコンを読み込んでみたらMITSUBISHI_HEAVY_152だったのでTurnOnMitsubishiHeavyAcサンプルを開いて内容を書き換えます
Mesg Desc.の部分に信号の内容が表示されるのでそれぞれ関数の引数に設定します

Timestamp : 000017.074
Library   : v2.7.2

Protocol  : MITSUBISHI_HEAVY_152
Code      : 0xAD513CE51A09F609F625DA807F827D40BF807F (152 Bits)
Mesg Desc.: Power: On, Mode: 1 (Cool), Temp: 26C, Fan: 5 (UNKNOWN), Swing(V): 4 (Low), Swing(H): 2 (Left), Silent: Off, Turbo: Off, Econo: Off, Night: On, Filter: Off, 3D: Off, Clean: Off
uint16_t rawData[307] = {3206, 1560,  424, 366,  426, 1164,  426, 366,  426, 368,  426, 1162,  424, 366,  426, 1162,  424, 368,  424, 368,  424, 1164,  424, 1164,  424, 1162,  428, 364,  426, 1164,  424, 366,  426, 1162,  424, 1162,  424, 1162,  424, 366,  426, 368,  426, 368,  426, 366,  426, 1164,  424, 1162,  424, 366,  426, 1162,  424, 368,  426, 1162,  424, 1164,  422, 368,  426, 368,  424, 370,  424, 1164,  424, 366,  426, 1164,  424, 366,  424, 370,  410, 1178,  424, 1162,  424, 1164,  424, 368,  426, 1164,  424, 1164,  424, 366,  426, 1164,  424, 1162,  424, 1164,  422, 1164,  424, 1164,  424, 368,  424, 370,  424, 1164,  424, 368,  424, 370,  424, 368,  426, 368,  424, 368,  400, 1188,  422, 1166,  424, 336,  456, 1164,  424, 1164,  424, 1164,  424, 1162,  424, 1162,  424, 368,  400, 394,  400, 1188,  424, 368,  400, 394,  422, 370,  424, 368,  424, 370,  424, 1162,  424, 370,  400, 1188,  424, 1164,  424, 368,  422, 1166,  424, 1164,  424, 1164,  424, 368,  400, 1190,  422, 368,  400, 394,  398, 1190,  422, 368,  400, 394,  400, 1188,  400, 1166,  448, 1160,  400, 1188,  424, 1162,  422, 1164,  424, 1164,  424, 368,  400, 394,  422, 370,  400, 394,  422, 370,  400, 394,  400, 394,  398, 394,  400, 1188,  400, 1188,  424, 368,  400, 1188,  422, 1164,  400, 1188,  398, 1188,  398, 1188,  400, 394,  400, 394,  400, 1188,  400, 394,  398, 394,  400, 392,  400, 392,  400, 394,  400, 1188,  424, 1164,  398, 1190,  422, 1164,  400, 1188,  422, 1164,  404, 1182,  424, 368,  400, 1188,  400, 392,  400, 394,  398, 394,  400, 392,  400, 392,  400, 392,  400, 1188,  424, 368,  400, 1188,  406, 1182,  400, 1188,  400, 1188,  424, 1164,  402, 1186,  400, 1188,  422, 368,  400, 394,  400, 392,  400, 394,  400, 394,  398, 394,  400, 394,  400, 394,  424, 1164,  398};  // MITSUBISHI_HEAVY_152
uint8_t state[19] = {0xAD, 0x51, 0x3C, 0xE5, 0x1A, 0x09, 0xF6, 0x09, 0xF6, 0x25, 0xDA, 0x80, 0x7F, 0x82, 0x7D, 0x40, 0xBF, 0x80, 0x7F};


#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_MitsubishiHeavy.h>
#include <M5StickC.h>

const uint16_t kIrLed = 9;  // M5StickC内蔵赤外線LED
IRMitsubishiHeavy152Ac ac(kIrLed);  // Set the GPIO used for sending messages.

void printState() {
  // Display the settings.
  Serial.println("Mitsubishi Heavy A/C remote is in the following state:");
  Serial.printf("  %s\n", ac.toString().c_str());
  // Display the encoded IR sequence.
  unsigned char* ir_code = ac.getRaw();
  Serial.print("IR Code: 0x");
  for (uint8_t i = 0; i < kMitsubishiHeavy152StateLength; i++)
    Serial.printf("%02X", ir_code[i]);
  Serial.println();
}

void setup() {
  ac.begin();
  Serial.begin(115200);
  delay(200);

  M5.begin();
}

bool on = false;

void loop() {
 M5.update();
  if ( M5.BtnA.wasReleased() ) {

    ac.setPower(!on);
    on = !on;
    ac.setFan(5);
    ac.setMode(1);
    ac.setTemp(26);
    ac.setSwingVertical(4);
    ac.setSwingHorizontal(2);
    ac.send();
    Serial.println("Sending IR command to A/C ...");
    printState();
  }
  delay(1);
}


こうすることでM5StickCのディスプレイ横のボタンを押すことでエアコンの電源をON/OFFすることができます

エアコンの機種が特定されなかった場合は先ほどと同様にrawData[]を直接送信してください

内蔵LEDのないM5StackやESP32 Dev boardなどを使う場合は
const uint16_t kIrLed = 9;
の部分を赤外線LEDを接続したGPIOに変更しハードウェアに依存する関数を変更すれば使用できます

↓昔作った奴