🌌

赤外線用の学習リモコンをBluetooth操作対応リモコンにしてみた

2021/03/11に公開

はじめに

今回は市販の赤外線用の学習リモコン利用し Atom Lite 経由で Bluetooth 機器の操作も可能な万能学習リモコンとして使えるようにしてみたいと思います。

ソース類は
https://github.com/toyo-toyo/AtomLite_IR_Recv_2_Ble_Gamepad
に公開しています。

必要なもの

作ることになった経緯

この章は読み飛ばしても問題ありません。

実装方法だけ知りたい方は
赤外線リモコンを受信し、Bluetooth信号を送信
から確認してください。

市販の学習リモコン調査

家にはリモコンがたくさんあり学習リモコンを使って一つにまとめたいと思いましたが、最近購入した Chromecast with Google TV が Bluetooth リモコンでした。

リモコン類

そこで Bluetooth の学習もできるリモコン製品を探してみたところ、ソニー SONY スマートリモコン HUIS REMOTE CONTROLLERクレードルセット (ホワイト) HUIS-100KCぐらいしか見つけれませんでした。

ソニー SONY スマートリモコン HUIS REMOTE CONTROLLERクレードルセット (ホワイト) HUIS-100KCの値段を確認してみると 19,800 円 (2021-03-10現在)と思っていた以上に高価で、しかも液晶での操作なので少し使いにくそうだなと感じました。

スマートリモコンはすでに使っていますが、携帯画面でのリモコン操作が面倒なので声での操作でしかほぼ使っていない状況です。

Bluetooth 対応リモコン自作方法の検討

とりあえず Bluetooth と赤外線を操作できるリモコンを自作出来ないか?と考え、余っているリモコンの赤外線信号を判断し、スマートリモコンの API または Bluetooth の操作をするという方法を考えました。
スマートリモコンのAPI呼び出しとBluetoothでの接続が可能な、家に存在するIoT機器で考えてみたところ、色々と候補はありましたが Raspberry Pi Zero で確認してみることにしました。

実用はしてはいませんでしたが昔に作った Raspberry Pi の自作スマートリモコンから赤外線受信部品をとりだし、試作を簡単に Raspberry Pi Zero で作ってみました。

Raspberry Pi Zero と 赤外線受信モジュール
この方法だと余ったリモコンさえあれば、学習リモコンすら必要ないのでいいと考えていましたが、スマートリモコンへの登録が面倒そうだったのと、Raspberry Pi だと赤外線受信部分もむき出しなので何かしら工作が必要なのでもう少し考えてみることにしました。

そこで学習リモコンを購入する必要は出てきますが、赤外線の信号を学習リモコンに任せてしまえば、スマートリモコンの API を叩く必要もなくシンプルでいいのかな?と考えました。

スマートリモコンの API が不要であれば、赤外線受信が出来て Bluetooth の操作出来るだけでもいいので、 Atom Lite でも試してみることにしました。
M5Stack 用の赤外線送受信ユニットも購入後に一度試して放置していたという経緯もあり部品はそろっていました。

Atom Lite と M5Stack 用の赤外線送受信ユニット

物理操作が出来る赤外線用の学習リモコンは複数あるみたいでしたが、比較的安価で評判もよさそうな
ソニー 学習リモコン RM-PLZ430D : テレビ/レコーダーなど最大5台操作可能 RM-PLZ430D
を購入して、とりあえず赤外線リモコンはこれに集約し、Bluetooth リモコンは Atom Lite 経由で操作する方針に切り替えました。

赤外線リモコンを受信し、Bluetooth信号を送信

Atom Lite で赤外線リモコンのボタンを判断し、 Bluetooth の信号を送信するようにしてみます。
Bluetooth の送信には Keyboard 用のライブラリもありましたが、今回は Gamepad 用のライブラリを使用します。

lemmingDev/ESP32-BLE-Gamepad で Zip ファイルをダウンロードします。
Arduino IDE の「スケッチ」>「ライブラリをインクルード」>「.zip形式のライブラリをインストール」でライブラリを登録してください。

AtomLite_IR_Recv_2_Ble_Gamepad.ino
#include <M5Atom.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRutils.h>
#include <BleGamepad.h> 

const uint16_t kRecvPin = 32;
const uint16_t kCaptureBufferSize = 1024;
const uint8_t kTimeout = 50;
const CRGB CRGB_BLE_CONNECTED(0x00, 0x00, 0xf0);
const CRGB CRGB_BLE_DISCONNECTED(0x00, 0xf0, 0x00);

IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results;  // Somewhere to store the results

BleGamepad bleGamepad;
bool isBleConnected = false;

void setup() {
  M5.begin(true, false, true);
  M5.dis.drawpix(0, CRGB_BLE_DISCONNECTED);
  irrecv.enableIRIn();
  bleGamepad.begin();
}

void loop() {
  M5.update();
  // if (bleGamepad.isConnected()) {
  if (true) {  // 赤外線信号確認だけの場合は true 固定
    if (!isBleConnected) {
      M5.dis.drawpix(0, CRGB_BLE_CONNECTED);
      isBleConnected = true;
      Serial.println("Connected");
    }
    // Check if the IR code has been received.
    if (irrecv.decode(&results)) {
      uint32_t value = results.value;
      Serial.println(value);
      switch(value){
        case 1111111111:
          Serial.println("上");
          sendLeftThumb(0, -32767);
          break;
        case 2222222222:
          Serial.println("下");
          sendLeftThumb(0, 32767);
          break;
        case 3333333333:
          Serial.println("左");
          sendLeftThumb(-32767, 0);
          break;
        case 4444444444:
          Serial.println("右");
          sendLeftThumb(32767, 0);
          break;
        case 5555555555:
          Serial.println("決定");
          sendButton(BUTTON_1);
          break;
        case 6666666666:
          Serial.println("戻る");
          sendButton(BUTTON_2);
          break;
        default:
          Serial.println("他の値です");
      }
    }
  } else {
    if (isBleConnected) {
      M5.dis.drawpix(0, CRGB_BLE_DISCONNECTED);
      isBleConnected = false;
      Serial.println("Disconnected");
    }
  }
  delay(50);
}
void sendLeftThumb(int16_t x, int16_t y) {
  bleGamepad.setLeftThumb(x, y);
  delay(1);
  bleGamepad.setLeftThumb(0, 0);
}
void sendButton(uint8_t sendkey) {
  bleGamepad.press(sendkey);
  delay(1);
  bleGamepad.release(sendkey);
}

上記コードを Arduino IDE で Atom Lite に書き込みします。
赤外線送受信ユニットに向けてリモコンボタンを押下し、シリアルモニタでボタンごとにでる赤外線信号を確認します。

1234567890
他の値です

のように赤外線信号が表示されると思います。

同じボタンを複数回押下し、数値に変化がないことを確認してください。
確認出来たら case 1111111111:などの部分を対応するボタンの赤外線信号にコードを変更します。
同様に「上」「下」「左」「右」「決定」「戻る」の6か所のボタンを確認しコードを変更します。

変更したコードを再度を Arduino IDE で Atom Lite に書き込みします。
シリアルモニタにボタンに対応した「上」などが表示されるのを確認できれば登録完了です。

すべてのボタンを変更できれば

  // if (bleGamepad.isConnected()) {
  if (true) { // 赤外線信号確認だけの場合は true 固定

の部分を

  if (bleGamepad.isConnected()) {
  // if (true) { // 赤外線信号確認だけの場合は true 固定

に変更します。

また複数のボタンで同じ動作をさせたい場合は

        case 1111111111:
        case 7777777777:
        case 8888888888:
          Serial.println("上");
          sendLeftThumb(0, -32767);
          break;

のように書くことも可能です。
私の場合は2種類のリモコンで同様の操作ができるように登録し、さらに戻るボタンは複数のボタンを割り当ててみました。

Bluetoothリモコンとしてペアリング

Bluetooth リモコンを登録したい機器で Atom Lite へのペアリングを行います。
ペアリングが完了すると Atom Lite の LED が青く点灯します。

赤外線送受信ユニットに向けてリモコンボタンを押下し想定通り機器が操作できることを確認します。

無事操作出来れば完了です。

おまけ

独自の赤外線信号を登録

学習リモコン (RM-PLZ430D) を確認していたところ、購入したての状態では信号が登録されていないボタンがいくつかありました。
余ったリモコンの信号などを登録し、何かしらの信号を送信するように出来れば問題ないですが、余ったリモコンがない場合などの為に独自の信号を発信できるコードも書いておきます。

AtomLite_IR_Send.ino
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <M5Atom.h>

const uint16_t kIrLed = 26; // AtomLite内蔵LED 12 IR UNIT 26
const uint32_t sendValue = 1234567890;    //送信する赤外線信号

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

void setup() {
  M5.begin(true, false, false);
  irsend.begin();
}

void loop() {
  M5.update();
  // Atom Lite Button
  if (M5.Btn.wasReleased()) {
    Serial.println("sendNEC()");
    irsend.sendNEC(sendValue);
  }
  delay(100);
}

上記コードを Arduino IDE で Atom Lite に書き込みします。
Atom Lite に赤外線送受信ユニットを装着し、学習リモコンに向けて Atom Lite のボタンを押下すると赤外線信号が送信されます。
sendValue (送信するコード)を変更しながら「上」「下」「左」「右」「決定」「戻る」の6項目を学習リモコンに登録してください。

3Dプリンタでケース作成

ここは必要ありませんが、3D プリンター「 ADVENTURER 3S 」でケースも自作してみました。

興味がある方は印刷してお使いください。
AtomLite_IR_UNIT.stl
AtomLite_IR_UNIT_Cap.stl


3D プリント中の FlashXPrint 画面

完成したケースに Atom Lite と M5Stack 用の赤外線送受信ユニットを装着

参考記事

ESP32で赤外線通信ができるライブラリ「IRremoteESP8266」の使い方
M5Stack Atomで赤外線リモコンを作る(2)受信編
ATOM LiteをBLEキーボードにして,特定の文字列を送付する
lemmingDev/ESP32-BLE-Gamepad

まとめ

Atom Lite と赤外線送受信ユニットであれば、ケースは作らずにそのままの実用でもそこまで違和感もなく、半田なども使わなくていいのでかなり敷居が低くなりましたね。
リモコンでもっと色々操作出来たほうがいいかな?とも思うので、Raspberry Pi で作り直すかもしれません。

もちろんここまで出来たら Bluetooth 信号もスマートスピーカーやスマートリモコン経由で音声操作も可能になりますね。

スマートリモコンは携帯での操作が不便なので、余ったリモコンで他の赤外線信号を送信できる機能はスマートリモコンの機能として実装してほしいですね。
それと Bluetooth 機器の操作も出来るスマートリモコンも早く市販してほしいです。

あと Atom Lite を操作するのに赤外線である必要はないので、Wifi 対応リモコンとかも市販してほしいですね。

とりあえずこれでリモコンを一つにまとめれそうなのでうれしいですね(●´ω`●)

まだ使い始めなので、とりあえずこれを使っての使用感など様子をみてみます。
家族が複数人いるのであれば、学習リモコン自体も複数あってもいいかもですね。

続きの記事も書きました!
https://zenn.dev/toyotoyo/articles/d4aa950e323469

Discussion