ESP32とNatureRemoでパソコンをリモートで起動する
TL;DL
- esp32とサーボモーターを使って物理的にパソコンのスイッチを押すことに成功
- 赤外線モジュールを搭載することで、NatureRemoなどのスマートリモコンから操作可能
- NatureRemoから操作できるようにすることでNatureRemoのオートメーション機能が使える
はじめに
皆さんのご自宅はスマートホーム化しているでしょうか。
最近ではNatureRemoやSwitchBotなどお手軽にスマートホームを実現するデバイスが増えてきています。
私も自分の家にNatureRemoを導入してから、エアコンやシーリングライト、サーキュレーターを遠隔で起動させたり決まった時間に自動で起動するようにしたりなど、なかなか便利なものです。
しかし、NatureRemoには弱点があります。それは 「物理ボタンが押せない」 ということです。
NatureRemoは赤外線リモコンの信号を読み取って、リモコンの代わりにNatureRemoから様々な赤外線デバイスを操作するデバイスです。
SwitchBotも似たようなデバイスですが、異なる点として、SwitchBotは自社から専用の物理ボタンを押すことができるデバイスを販売しています(指ロボットと言ったりもします)。
モチベーション
私は基本リモコンで操作する家電やデバイスを選ぶようにしていますが、それでも物理的にボタンを押さなければならないシーンはまだまだあります。
なんとかNatureRemo君を無駄にせずにスマートホームを実現できないか...
そこで、マイコンとサーボモーターを使って何とか物理的にボタンを押そうではないかと考えました。
仕組み
大まかな流れは以下のようになります。
- NatureRemoに赤外線信号を学習させる
- NatureRemoが学習した赤外線信号を発信する
- マイコンで赤外線を受信させて、信号を識別する
- 特定の信号を受信したら、モーターを動作させて物理的にボタンを押す
用意するもの
私はすべて秋月電子で購入しました。値段は当時のものなので参考までに。
- ESP32 WROOM 32E (580円)
- ESP32 ダウンローダーキット(円)
- マイクロサーボ SG92R(580円)
- 赤外線受信モジュール GP1UXC41QS(50円)
普段から電子工作されている方なら持っているかもしれませんが、初めて作成する方なら以下のものが必要でしょう
- 開発用ブレッドボード(円)
- ジャンパワイヤー(円)
作成
それでは作っていきます。
配線
配線をする前に、今回使用するモジュールについて確認しておきましょう。
今回主に使用するのは、「マイクロサーボSG92R」と「赤外線受信モジュール」の二つです。
秋月電子のサイトを参考にすると、マイクロサーボSG92Rとの接続部分は以下のような仕様になっているようです。
動作電圧は4.8V、トルクは2.5kgf・cmです。
同様に、赤外線受信モジュールの仕様を確認すると以下のようになっています。
動作電圧は2.7~5.5Vです。
2つのモジュールとも5Vあれば動きそうですね。
仕様を確認したら以下のように配線します。
ESP32 | サーボモーター | 赤外線モジュール |
---|---|---|
5V | +V[電源] | Vcc[電源] |
GND | GND | GND |
GPIO 14 | SIG[制御信号] | - |
GPIO 12 | - | Vout |
ESP32の5Vから電源を供給する形です。二つのモジュールのそれぞれの電源とGNDをESP32の5VとGNDに並列で繋げます(並列ならば電圧は同じのはず)。
そして、制御信号をそれぞれESP32のGPIOにつなげます。このときつなげるGPIOは何番でもよいですが、今回は12番に赤外線受信モジュール、14番にマイクロサーボを接続しました。
私の購入した「ESP32-WROOM-32E マイコンボード」は別途USB-シリアル変換モジュールが必要だったため、写真では複雑な配線をしていますが、「ESP32 Dev Kit」など最初からUSBアダプタがついているものならば図のようすれば大丈夫です。
ちなみに電子工作や電子回路については素人なので、「こんな配線じゃだめだ!」等意見がありましたら気兼ねなくいただけますと幸いです。
コーディング
ESP32にコードを記述し、期待する動作をするようにしていきます。
ESP32に記述する際はArduinoIDEというソフトを使用することが一般的らしいのでこれを使用していきます。
ArduinoIDEのインストール
公式から自分のOSにあったArduinoIDEをインストールします。
ArduinoIDEのセットアップ
コード記述
#include "IRremote.h"
#include "ESP32Servo.h";
int IR_RECEIVE_PIN = 12;
int SERVO_PIN = 25;
int servo_left = 120;
int servo_right = 180;
Servo servoMotor;
void setup() {
Serial.begin(115200);
pinMode(SERVO_PIN, OUTPUT);
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK, SERVO_PIN);
servoMotor.attach(SERVO_PIN);
print_wakeup_reason();
esp_sleep_enable_ext0_wakeup(GPIO_NUM_12,LOW);
}
void loop() {
if (IrReceiver.decode()) {
IrReceiver.printIRResultShort(&Serial);
if (IrReceiver.decodedIRData.decodedRawData == 0xFC03EF00) {
delay(1000);
servoMotor.write(servo_left);
delay(1000);
servoMotor.write(servo_right);
IrReceiver.resume();
esp_sleep_enable_ext0_wakeup(GPIO_NUM_12,LOW);
esp_deep_sleep_start();
}
IrReceiver.resume();
}
}
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t wakeup_reason;
wakeup_reason = esp_sleep_get_wakeup_cause();
switch(wakeup_reason)
{
case 2 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
case 3 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
case 4 : Serial.println("Wakeup caused by timer"); break;
case 5 : Serial.println("Wakeup caused by touchpad"); break;
case 6 : Serial.println("Wakeup caused by ULP program"); break;
default : Serial.println("Wakeup was not caused by deep sleep"); break;
}
}
軽く解説します
最初にincludeしているIRremote.h
は赤外線モジュールで受信した信号を処理するライブラリ、ESP32Servo.h
はサーボモータを制御するライブラリです。
int IR_RECEIVE_PIN = 12;
int SERVO_PIN = 25;
で赤外線とサーボモータを接続したGPIOのピン番号を定数として持っておきます。配線の時点で接続したGPIOの番号が違う場合は、その番号を記述してください。
ESP32ではsetup()
メソッドで変数の初期化などを行い、loop()
メソッドで実際の処理を記述していきます。
今回はIRreceiver
で赤外線信号を受信したらservoMotor.write(servo_left)
servoMotor.write(servo_right)
でサーボモーターを動かします。servo_right
servo_left
は上で定義したサーボモータの動作角度です。今回の場合は180度の時点から120度までモータを動かし、180度に戻すという処理を実装しています。
また、delay(1000)
は処理を遅らせることができ、この場合1000ms(1秒)間隔を開けてモーターを動かします。
追記
しばらく運用していたのですが、モーターの動きが鈍くなっていました。途中で一回モーターを分解したのが悪かったのか、PCに強めに接着したせいでモーターに負荷がかかってしまったのか、原因は不明です。
本記事はあくまで参考程度にとどめておいてもらうとよいと思います。
関連リンク
今回作成したコードのgithubリポジトリ
秋月電子通商
Discussion