こんちゃ!洋梨🍐です。
「スマホから家電の操作したいな~」なんて思ったこと皆さん無いでしょうか?
きっとあると思います(暴論)^^
そこで今回はスマホから家電を操作する為の手順を公開したいと思います~
今回使うもの
製作環境
・Unity + C#
スマートフォン(操作)側アプリの開発に使います。今回紹介するソースコードはC#で書かれているので.NET FrameworkやXamarinでも動きますよ。(確認済)
・Arduino + C
リモコン(実行)側にはArduinoを用います。なお言語はC言語ベースです。
材料
・Arduino 本体
HiLetgo® 2個セット NEWバーション UNO R3 ATmega328P USB CH340G Arduinoと互換性 + USB ケーブル [並行輸入品]
今回の主役です。C言語を使って電子部品を扱うことができます。
・赤外線LED
リモコンの操作信号を再現するために使います。波長は 950nmに近いものを使います。※850nmでは動きませんでした。
・赤外線 受光モジュール
リモコンの操作信号を再現するために使います。
・ボタン
操作用に使います。
・Wi-Fiモジュール
スマートフォンから操作したい場合、使用します。Arduinoをインターネットに接続できるようにすればいいのでイーサネットでもOK!
オプション
・IC2 OLED (128×64)
Arduinoから情報を出力(可視化)するために今回は使いました。
・コンデンサー
リモコンの光を遠くまで飛ばせるようにするとき使います。
・リレー
赤外線操作ではなくコンセント操作を使いたいときにどうぞ
仕組み
例えば、普通は左のようにテレビの操作にリモコンを使いリモコンがテレビに信号を送っています。
しかし、スマホで操作したくてもスマホではテレビに信号を送ることができません。
そこで今回は信号を送る部分をArduinoに肩代わりしてもらい、スマホからArduinoを操作することで間接的にテレビに信号を送るというわけです。
作成 (Arduino側)
すべて説明すると長くなってしまうため簡単な説明です。
Arduinoでは赤外線信号を保存・再生します。
受光モジュールを使いリモコンの信号を事前にキャプチャーし、スマホからの信号が届いたら赤外線LEDを用いてキャプチャーした信号を 再生すればいいというわけです。
まずキャプチャー(保存)するためのソースコードです。
// Capture.c
bool recIR(){
/* キャプチャーを開始します。*/
ir_beforeStat = digitalRead(IR_RLED);
cleanData();
return recIR_();
}
bool recIR_(){
unsigned long nT = micros();
for(unsigned long i;micros() < TIME_MICROSECONDS + nT;){
int irR_val = digitalRead(IR_RLED);
if(ir_beforeStat!=irR_val){
/*状態変異時*/
i = micros() - nT;
if(!addData(i)) return false; //保存できなかったらエラー
ir_beforeStat = irR_val;
}
//delayMicroseconds(TIMMING_WAIT_MICROSEC);
}
return true;
}
bool addData(unsigned long t){
if(irDataPointer>IRDATA_SIZE) return false;
irData[irDataPointer] = t;
irDataPointer++;
return true;
}
次に再生するためのソースコードです。
bool playIR(int IRLED){
if(irData[0]==0){
return false;
}
digitalWrite(IRLED, LOW);
int playPoint = 0;
bool irStat = false;
unsigned long nT = micros();
for(unsigned long i;micros() < TIME_MICROSECONDS + nT;){
i = micros() - nT;
if(irData[playPoint]<=i){
if(!irStat){
digitalWrite(IRLED, HIGH);
irStat = true;
}else{
digitalWrite(IRLED, LOW);
irStat = false;
}
playPoint++;
if(irData[playPoint]==0) break; //終端の場合抜ける
}
//+delayMicroseconds(TIMMING_WAIT_MICROSEC);
}
digitalWrite(IRLED, LOW);
//printData();
return true;
}
このプログラムをボタンを押したときに呼び出すようにすればボタンを押したときにキャプチャーした信号が再生されるようになります。
スマホからの操作に使用する際はUDPポートを監視し、信号が流れてきたら事前に決めたパケット構造に基づき対応した信号を再生するようにした。
操作用アプリ製作 (操作側)
紹介用に部屋の電気をON・OFFにする機能だけをつけたものにしてあります。C#で書かれています。なおUnityで動作確認済みです。
メインプログラム (Unity用)
public class Main : MonoBehaviour {
const int PORT = 12345;
public InputField input;
UDPSystem udpSystem;
public void Button_OnClick(int n)
{
if (udpSystem == null) udpSystem = new UDPSystem(null, 0, input.text, PORT, null);
switch (n)
{
case 0:
udpSystem.Send(new byte[] { 1,0 });
break;
case 1:
udpSystem.Send(new byte[] { 1,1 });
break;
}
}
}
ここで使っている「UDPSystem」のスクリプトは長いため以前書いた
こちらの記事をご覧ください。UDPパケットの送信には上記事のスクリプトを汎用しています。
これでスマートフォンからUDPでのパケットの送信ができるようになったと思います。もちろんTCPを使ってもできます。(むしろそっちのほうが良いかも)
テスト
このアプリで本当に信号(パケット)が出せているのか、しっかり届いているのかは調べないとわかりません。今回は「Wireshark」というパケットキャプチャーを使い、パケットが届いているかどうか確認したいと思います。
なお、外出先など外部からパケットを送信・受信(操作)するには「ポート開放」などが必要です。プログラムではUPnPやホールパンチングなど技術を使う必要があります。UPnPは比較的簡単なのでこちらを参考にしてみてください。
今回は外部(外出先)から使う事を推定しているのでテストではスマートフォンの4G回線(Docomo)からリクエストを送信します。
今回テストで送信するリクエストは「ID(01)の機器の電源をON(01)にする」にします。つまりUDPで送るデーターは「0101」です。
先ほどのプログラムの「case 1:」の部分です!
アプリでプログラムを実行すると、自宅にあるPCの「パケットキャプチャー」で見るとUDPでパケット「0101」が届いているのが確認できました。これで外部からつけることができるという事が確認できました。
まとめ
今回はIoTデバイス作りの第一歩として家電操作を行いました。
この記事は以前私がレポートとしてやったものを記事に起こしたものになりますので詳しく知りたい方は こちらからレポートをダウンロード してください~
書いている途中で面倒になってしまったのもあり、説明がいくつか抜けて分からない部分があるかもしれませんでしたがすいませんです!(> 3 <)
「よくわかんないからプロジェクトファイルくれ」「もっと詳しく記事書いて」などリクエストはメールにお願いします!
ここまで読んでくれてありがとうございました!!
ホームページでは他にも
・様々な記事や作った作品および過程
・ソースコード、素材ファイル
・あらゆる”モノ”の作り方
などなど随時、記事や作品を新規公開・更新していますので是非見ていってくださいね!見ていただけると本当に嬉しいです!
Thank You Watching💛