WiFiIRブラスター
コンポーネントと消耗品
> |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
必要なツールとマシン
> |
|
アプリとオンラインサービス
> |
| |||
|
このプロジェクトについて
2つのステップ...
主要な電話メーカーは組み込みのIRブラスターから離れつつあるようです。そのため、現在IoTインフラストラクチャと統合されていない「ダム」デバイスを将来にわたって利用できるようにする方法を探しています。メッシュネットワークのスマートホームを持っていますが、テレビの電源を入れるために物理的なリモコンを見つける必要がありますか?より良い方法が必要です。
最近、家にスタンドアロンのエアコンを制御するIRブラスターを構築しました。以前の別のプロジェクトは、Androidに接続されたウェブアプリに接続されたHVACベントでした。基本的に、私がする必要があるのは、これら2つのことをWebアプリケーションフロントエンドを備えたWeb接続IRブラスターに組み合わせて、電話のボタンを押してIR信号をメディアセンターに送信できるようにすることです。これらはすべての部屋に配置でき、単一のインターフェースからどこでも制御できるため、このアプリケーションは非常に幅広いものです。
ラピッドプロトタイピング
未使用のハードウェアをいくつか入手し、WiFiに接続し、HTTP接続を受け入れ、IR信号を送信するために必要なすべてのものを配線しました。
<図>これは、ESP8266に割り当てられたIPで特定のURLを要求し、Arduinoに「電源」信号をIRLEDに出力させることができるという点で問題なく機能しました。 Webアプリをホストする場所を見つけ、URLをIRブラスターに送信してから、それらのリクエストを特定のIRコードに解析する必要がありました。これは、ESP8266でATコマンドを使用するのは非常に面倒で、リクエストの送信とLEDの点滅の間に1〜2秒の遅延が発生しました。
<図>
NodeMCU
NodeMCU ESP8266開発ボードを先に進めました。これは、オンボードの電力調整、USBからシリアルへのインターフェイス、およびこの小さなパッケージに多数のI / Oピンが含まれているためです(ブレッドボードにも対応しています)。 IRコードの送信に適応できたGETリクエストを受け入れるESP8266WebServerライブラリがすでに存在し、通常のIRremoteライブラリはそのままで機能します。
<図>NodeMCUのESP8266は、Webアプリ自体をホストするほど強力ではないため、十分に活用されていないC.H.I.Pで実行します。すでにホームネットワークで実行されている9ドルのコンピューター。もう1つの制限は、ESP8266が3.3vボードであるため、I / Oピンから直接駆動されるIRLEDが非常に暗く、信号を送信するアプライアンスのすぐ隣に配置する必要があることです。代わりに、I / Oピンを使用してnpnトランジスタを駆動し、5V電源電圧のオン/オフを切り替えました。
REST ... ish
いくつかの調査を行った後、私は、Arduino用のRESTAPIを実装してadafruitのLEDを制御するための優れたチュートリアルを見つけました。 JavaScriptファイルとPHPファイルを使用してcURLリクエストを送信し、すでにapacheを実行しているが、クラウドで簡単にホストできるCHIPにロードしました。リモコンの基本的なHTMLページを作成した後、manifest.jsonファイルとアイコンファイルを追加して、Android携帯でネイティブWebアプリとして実行できるようにしました。
<図> <図> <図>Arduino側では、ウェブサーバーを縮小してGETリクエストを受け入れ、URLを解析し、200 OKを送信してから、切断しました。 URLに基づいて、Arduinoは押されたボタンにマッピングされたIRコードを送信します。
ユニバーサルリモンスター <図> <図> <図>
すべてがゼロ遅延で完璧に機能しています。使用しているIRLEDの角度が非常に狭いことがわかったので、正しく向けられていることに注意する必要があります。一部の工業用ベルクロを使用すると、棚の下に取り付けて見えないようにし、もう一方の端のIRレシーバーに向けたままにすることができます。 LEDリードに太いゲージのワイヤーを追加して、微調整できるようにしました。
IR LED用の抵抗があると、ほとんど使用できなくなったため、トランジスタは調整されていない5Vでそれらに電力を供給しています。これにより、IRを壁に反射させてブラスターを部屋全体に取り付けることができますが、寿命には間違いなく影響します。使用頻度が非常に低く、IR信号が非常に短いパルス(ほとんどの薄暗いPWM信号よりもデューティサイクルが低い)であるため、しばらくの間LEDを交換する必要がないことを期待しています。バージョン2用に広角で高出力のIRLEDを注文したので、これらが最終的に死んだら、インライン抵抗と一緒に交換します。
3か月の更新と将来の機能
私はこれを毎日使用していて、完璧に機能しています。ファミリールームに、ウィンドウACユニットと別のテレビを制御するための2つ目のデバイスを追加しました。
将来の計画:
- ウェブUIをクラウドサービスに移行する
- 音声コマンドのためにAmazonEchoと統合する(完了)
- 次のハードウェアイテレーションにもDHT22温度センサーが搭載され、天井ファンにRFを送信する方法を研究しています
- 学習機能用のIRレシーバーを追加して、既存のリモコンからIRブラスターコマンドを「教える」ことができるようにします
- ホームオートメーション/セキュリティと統合して、使用していないときにアプライアンスをオフにします
この小さな接続されたIRブラスターは、私のスマートホームとレガシーアプライアンスの間のギャップをゆっくりと埋めています。
コード
- ESP8266 ArduinoSketch用WiFiIR Blaster
- script.js
- index.html
- curl.php
- manifest.json
ESP8266 ArduinoSketch用WiFiIR Blaster C / C ++
ESP8266Wi-FiライブラリとIRremote.hが必要です。また、リモートがライブラリでサポートされている場合は、RawIRコードを使用しないことを選択する必要があります。このスケッチは、非標準のIRコードを使用して作成したエアコンコントローラーから採用しました。/ * * BuddyCrottyによるWiFiIR Blaster * ESP8266モジュールまたは開発ボードを使用してHTTPGETリクエストを受信します*次にIRコードを送信しますそれらの要求に基づいて、接続されたIRLEDに接続します。 *これは、押されたボタンに基づいて* cURLリクエストを送信するフロントエンドとして機能する別のWebサーバーで最適に機能します。 * cURL形式:http:// ESP8266 / IRcode * /#include#include #include const char * ssid ="AP_SSID"; const char * password ="AP_Pass "; MDNSResponder mdns; int khz =38; // NECとSamsungIRsendの両方の38kHzの搬送周波数irsend(4); // IR LEDはGPIO4に接続されています(NodeMCUのピンD2)//「TVPower」のRAWIR信号を挿入しますunsignedint irTVpwr [] ={4650,4250、700,1550、650,1550、700,1550、650,450 、650、500、600、500、600、500、600、550、550、1700、550、1650、600、1650、550、550、600、500、600、550、550、550、600、500、600、550、550、1650、600、550、550、550、600、500、600、550、550、550、600、500、600 、1650、600、500、600、1650、550、1700、550、1650、600、1650、550、1650、600、1650、600}; // SAMSUNG E0E040BF //「TVSource」のRAWIR信号を挿入unsignedint irTVsrc [] ={4600,4300、700,1550、650,1550、650,1600、650,450、650,450、600,550、550,550、600,500、600、 1650、550、1650、600、1650、550、550、600、500、600、550、550、550、550、550、600、1650、550、550、550、550、600、500、600、500、600、550、550、550、600、500、600、550、550、1650、550、1700、550、 1650、600、1600、600、1650、600、1600、600、1650、550}; // SAMSUNG E0E0807F //「TVミュート」のRAWIR信号を挿入unsignedint irTVmute [] ={4650,4250、700,1550、650,1550、700,1550、650,450、650,500、600,500、600,500、600,500、600、 1650、600、1600、600、1650、550、550、600、500、600、550、550、550、600、500、600、1650、550、1650、600、1650、550、1650、600、550、550、550、550、550、600、500、600、550、550、550、550、550、 600,500、600,1650、550,1650、600,1650、550,1650、600}; // SAMSUNG E0E0F00F //「TVVolumeDown」のRAWIR信号を挿入unsignedint irTVvdn [] ={4650,4250、700,1550、650,1550、700,1550、650,450、650,450、650,450、600,550、550,550、600 、1650、550、1650、550、1650、600、550、550、550、550、550、600、500、600、500、600、1650、600、1600、600、500、600、1650、550、550、600、500、600、500、600、550、550、550、600、500、600、1650 、550、550、550、1650、600、1650、550、1650、600、1650、550}; // SAMSUNG E0E0D02F //「TVVolumeUp」のRAWIR信号を挿入unsignedint irTVvup [] ={4600,4300、650,1600、650,1550、650,1600、600,500、600,550、600,500、600,550、550,550、550 、1700、550、1650、600、1650、550、550、600、500、600、550、550、550、600、500、600、1650、600、1650、550、1650、600、550、550、550、600、500、600、550、550、550、600、500、600、550、550、550、600 、1600、600、1650、600、1650、550、1650、600、1650、600}; // SAMSUNG E0E0E01F //「TVChannelUp」のRAWIR信号を挿入unsignedint irTVchup [] ={4650,4250、700,1550、650,1600、650,1550、650,500、600,500、600,500、650,500、600,500、600 、1650、550、1650、600、1650、600、500、600、500、600、550、550、550、600、550、550、550、550、1650、600、550、600、500、600、1650、550、550、600、500、600、550、550、1650、600、550、550、1650 、600、1650、600、500、600、1650、600、1600、600、1650、600}; // SAMSUNG E0E048B7 //「TVChannelDown」のRAWIR信号を挿入unsignedint irTVchdn [] ={4600,4350、650,1550、650,1600、650,1600、600,500、600,500、600,550、550,550、600,550、550 、1650、600、1650、550、1700、550、550、550、550、600、500、600、550、550、550、600、500、600、550、550、550、550、550、600、1650、600、500、600、500、600、550、550、1650、600、1650、600、1650 、550、1650、600、550、550、1650、600、1650、600、1650、550}; // SAMSUNG E0E008F7 //「ReceiverPower」のRAWIR信号を挿入unsignedint irRECpwr [] ={9050,4350、650,500、600,1600、600,500、650,500、600,1600、600,550、600,1600、600,1650、 550,550、600,500、600,1600、650,1600、600,500、600,1650、600,1600、600,500、600,1650、600,1600、600,550、600,1600、600,500、600,550、600,1600、600,1600、 650,500、600,500、600,1600、650,500、600,1600、600,1650、600,500、600,500、600}; // NEC 4B36D32C //「ReceiverPowerOn」のRAWIR信号を挿入unsignedint irRECpwrON [] ={9000,4400、600,550、600,1600、600,500、600,550、600,1600、600,500、600,1600、650,1600 、600、1600、600、500、650、1600、600、1600、600、500、650、1600、600、1600、600、500、600、550、600、500、600、1600、600、550、600、500、600、500、650、500、600、500、600、1600、650 、1600、600、500、600、1600、650、1600、600、1600、600、1600、600、1600、650}; // NEC 4BB620DF //「ReceiverPowerOff」のRAWIR信号を挿入unsignedint irRECpwrOFF [] ={9000,4400、600,550、550,1650、600,550、550,550、600,1650、550,550、600,1650、550,1650 、600,550、550,550、550,1650、600,1650、600,550、550,1650、600,1650、550,550、600,1650、550,1650、600,1650、600,500、600,550、550,550、600,1650、550,550、600,500 、600,550、550,550、550,1700、550,1650、600,1650、550,550、600,1650、550}; // NEC 4B36E21D //「ReceiverMute」のRAWIR信号を挿入unsignedint irRECmute [] ={9000,4400、650,450、650,1600、600,500、600,500、650,1600、600,500、600,1650、600,1600、 600、1600、650、500、600、1600、650、1600、600、500、600、1600、650、1600、600、500、600、1650、600、500、600、1600、650、500、600、500、600、500、600、500、650、500、600、500、600、 1600、650、500、600、1600、600、1600、650、1600、600、1650、600、1600、600}; // NEC 4BB6A05F //「ReceiverVolumeDown」のRAWIR信号を挿入unsignedint irRECvdn [] ={9150,4250、750,350、700,1550、700,400、700,450、650,1550、700,450、600,1600、650,1600 、600、1650、600、500、600、1650、600、1600、600、550、600、1600、600、1650、600、500、600、1650、600、1600、650、500、600、500、600、500、650、500、600、500、600、500、600、550、600、500 、600、1650、600、1600、600、1650、600、1650、600、1600、600、1650、600}; // NEC 4BB6C03F //「ReceiverVolumeUp」のRAWIR信号を挿入unsignedint irRECvup [] ={9050,4400、650,500、600,1600、600,550、600,500、600,1650、600,500、600,1600、650,1600 、600、1600、600、550、600、1600、600、1600、650、500、600、1600、650、1600、600、500、600、550、600、1600、600、550、600、500、600、550、600、500、600、550、600、500、600、1600、650、500 、600、1600、600、1650、600、1600、600、1650、600、1600、600、1600、600}; // NEC 4BB640BF //「ReceiverSourceCBL / SAT」のRAWIR信号を挿入unsignedint irRECsrc [] ={8950,4450、600,500、600,1650、600,500、600,500、600,1650、600,500、600,1600、600 、1650、600、1600、600、550、600、1600、600、1650、600、500、600、1600、600、1650、600、500、600、500、600、1650、600、1600、600、1650、600、500、600、500、600、500、650、500 、600、1600、600、500、600、550、600、500、600、1600、600、1650、600、1600、600、1650、600}; // NEC 4BB6708F //サーバーのインスタンスを作成します//リッスンするポートを引数として指定しますWiFiServerserver(80); void setup(){Serial.begin(115200); delay(10); irsend.begin(); // WiFiネットワークに接続しますSerial.println(); Serial.println(); Serial.print( "接続中"); Serial.println(ssid); WiFi.begin(ssid、password); while(WiFi.status()!=WL_CONNECTED){delay(500); Serial.print( "。"); } Serial.println( ""); Serial.println( "WiFi接続"); //サーバーを起動しますserver.begin(); Serial.println( "HTTPサーバーが開始されました"); // IPアドレスを出力しますSerial.print( "IP Address:"); Serial.println(WiFi.localIP()); if(mdns.begin( "IRBlasterLR"、WiFi.localIP())){Serial.println( "MDNSレスポンダーが開始されました"); } Serial.println(); Serial.println();} void loop(){//クライアントがWiFiClientに接続しているかどうかを確認しますclient =server.available(); if(!client){return; } //クライアントがデータを送信するまで待つSerial.println( "new client"); while(!client.available()){delay(1); } //リクエストの最初の行を読み取りますStringreq =client.readStringUntil( '\ r'); Serial.println(req); client.flush(); //リクエストに一致if(req.indexOf( "/ irTVpwr")!=-1){irsend.sendRaw(irTVpwr、sizeof(irTVpwr)/ sizeof(irTVpwr [0])、khz); Serial.println( "IRreq irTVpwr send"); } else if(req.indexOf( "/ irTVsrc")!=-1){irsend.sendRaw(irTVsrc、sizeof(irTVsrc)/ sizeof(irTVsrc [0])、khz); Serial.println( "IRreq irTVsrcが送信されました"); } else if(req.indexOf( "/ irTVmute")!=-1){irsend.sendRaw(irTVmute、sizeof(irTVmute)/ sizeof(irTVmute [0])、khz); Serial.println( "IRreq irTVmute send"); } else if(req.indexOf( "/ irTVvdn")!=-1){irsend.sendRaw(irTVvdn、sizeof(irTVvdn)/ sizeof(irTVvdn [0])、khz); Serial.println( "IRreq irTVvdn send"); } else if(req.indexOf( "/ irTVvup")!=-1){irsend.sendRaw(irTVvup、sizeof(irTVvup)/ sizeof(irTVvup [0])、khz); Serial.println( "IRreq irTVvupが送信されました"); } else if(req.indexOf( "/ irTVchup")!=-1){irsend.sendRaw(irTVchup、sizeof(irTVchup)/ sizeof(irTVchup [0])、khz); Serial.println( "IRreq irTVchupが送信されました"); } else if(req.indexOf( "/ irTVchdn")!=-1){irsend.sendRaw(irTVchdn、sizeof(irTVchdn)/ sizeof(irTVchdn [0])、khz); Serial.println( "IRreq irTVchdn send"); } else if(req.indexOf( "/ irALLpwr")!=-1){irsend.sendRaw(irRECpwrON、sizeof(irRECpwrON)/ sizeof(irRECpwrON [0])、khz); irsend.sendRaw(irTVpwr、sizeof(irTVpwr)/ sizeof(irTVpwr [0])、khz); delay(2000); irsend.sendRaw(irRECsrc、sizeof(irRECsrc)/ sizeof(irRECsrc [0])、khz); Serial.println( "IRreq irALLpwr send"); } else if(req.indexOf( "/ irRECpwr")!=-1){irsend.sendRaw(irRECpwr、sizeof(irRECpwr)/ sizeof(irRECpwr [0])、khz); Serial.println( "IRreq irRECpwr send"); } else if(req.indexOf( "/ irRECpwrON")!=-1){irsend.sendRaw(irRECpwrON、sizeof(irRECpwrON)/ sizeof(irRECpwrON [0])、khz); Serial.println( "IRreq irRECpwrONが送信されました"); } else if(req.indexOf( "/ irRECpwrOFF")!=-1){irsend.sendRaw(irRECpwrOFF、sizeof(irRECpwrOFF)/ sizeof(irRECpwrOFF [0])、khz); Serial.println( "IRreq irRECpwrOFFが送信されました"); } else if(req.indexOf( "/ irRECmute")!=-1){irsend.sendRaw(irRECmute、sizeof(irRECmute)/ sizeof(irRECmute [0])、khz); Serial.println( "IRreq irRECmute send"); } else if(req.indexOf( "/ irRECvdn")!=-1){irsend.sendRaw(irRECvdn、sizeof(irRECvdn)/ sizeof(irRECvdn [0])、khz); Serial.println( "IRreq irRECvdn send"); } else if(req.indexOf( "/ irRECvup")!=-1){irsend.sendRaw(irRECvup、sizeof(irRECvup)/ sizeof(irRECvup [0])、khz); Serial.println( "IRreq irRECvupが送信されました"); } else {Serial.println( "無効なリクエスト"); client.stop();戻る; } client.flush(); //応答をクライアントに送信します//client.print(s); client.print( "HTTP / 1.1 200 OK \ r \ n"); delay(1); Serial.println( "クライアントが切断されました"); Serial.println(); //関数が戻り、「client」オブジェクトが破棄されると、//クライアントは実際に切断されます}
script.js JavaScript
webappのjavascript(jqueryが必要)// IRコマンドを送信する関数functionbuttonClick(clicked_id){if(clicked_id =="irTVpwr"){$ .get( "curl.php"、{room: "192.168.1.62" 、ボタン: "irTVpwr"}); } if(clicked_id =="irTVsrc"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irTVsrc"}); } if(clicked_id =="irTVmute"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irTVmute"}); } if(clicked_id =="irTVvdn"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irTVvdn"}); } if(clicked_id =="irTVvup"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irTVvup"}); } if(clicked_id =="irTVchup"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irTVchup"}); } if(clicked_id =="irTVchdn"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irTVchdn"}); } if(clicked_id =="irRECpwr"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irRECpwr"}); } if(clicked_id =="irALLpwr"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irALLpwr"}); } if(clicked_id =="irRECpwrON"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irRECpwrON"}); } if(clicked_id =="irRECpwrOFF"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irRECpwrOFF"}); } if(clicked_id =="irRECmute"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irRECmute"}); } if(clicked_id =="irRECvdn"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irRECvdn"}); } if(clicked_id =="irRECvup"){$ .get( "curl.php"、{部屋: "192.168.1.62"、ボタン: "irRECvup"}); }}
index.html HTML
ボタンを表示するための基本的なHTML。
TV
&nbsp;&nbsp; &nbsp;&nbsp;
レシーバー
curl.php PHP
GETリクエストをESP8266に送信するphpスクリプト<?php $ room =$ _GET ['room']; $ button =$ _GET ['button']; // cURL呼び出しを作成します$ service_url ='http://'。 $ room。 '/'。 $ button; $ curl =curl_init($ service_url); // cURLをYunボードに送信しますcurl_setopt($ curl、CURLOPT_IPRESOLVE、CURL_IPRESOLVE_V4); $ curl_response =curl_exec($ curl); curl_close($ curl); //回答を出力echo $ curl_response;?>
manifest.json JSON
これにより、ウェブページをandroidでネイティブウェブアプリとして実行できるようになります。{"name": "WiFi Remote"、 "icons":[{"src": "remote_icon_36.png"、 "sizes": "36x36" 、 "type": "image / png"、 "density":0.75}、{"src": "remote_icon_48.png"、 "sizes": "48x48"、 "type": "image / png"、 "density" :1.0}、{"src": "remote_icon_128.png"、 "sizes": "128x128"、 "type": "image / png"、 "density":1.0}、{"src": "remote_icon_192.png" 、 "sizes": "192x192"、 "type": "image / png"、 "density":1.0}]、 "scope": "/ remote /"、 "start_url": "/remote/index.html"、 "display": "fullscreen"、 "orientation": "portrait"}
回路図
実際には何もありません。電源と1つのピンをNPNトランジスタに接続して、2つのIR LEDを直列に(抵抗なしで)5V電源電圧から駆動します。 追加のLEDを実行する場合、または3.3vソースからの電圧降下を少なくする必要がある場合は、NPNを使用できます。複数のPNPトランジスタを切り替えるトランジスタ(LEDごとに1つ)。この構成では、ソース電圧が電流を供給できる限り多くのLEDを使用できます。 製造プロセス
- WiFiRTLSの欠点
- 新しいワイヤレステクノロジー2015
- 3ドルのWiFiデバイスに安全な組み込みWebサーバーをインストールする方法
- NodeMCUとRaspberryPi 3 B +間のMQTT通信
- ANDROID SMARTPHONEから制御されるRASPBERRYPI WIFI ROBOT
- RaspberryPiを使用したWifi制御ロボット
- WiFi通話とは何ですか?それはどのように機能しますか?
- IOT-ESP8266、Arduino、超音波センサーを使用したスマートジャー
- Arduino UnoWiFiを使用したWebServerBlink
- Arduino&ESP8266によるWiFiログインページを使用したSmart Door Lock
- ビーズブラストとは?ビーズブラストのガイド