気の向くままに辿るIT/ICT/IoT
IoT・電子工作

ESP-01/12/ESP32でSHARP AQUOS TVをWiFi操作

ホーム前へ次へ
ESP8266って?

ESP-01/12/ESP32でSHARP AQUOS TVをWiFi操作

ESP-01/12/ESP32でSHARP AQUOS TVをWiFi操作

2019/02/05

 Wi-Fi(wifi)モジュールESP8266/ESP32開発ボードを使ってAC100V含む赤外線リモコン対応家電を操作する、いわゆるスマートリモコンの自作や非IRリモコン家電を無線で遠隔操作できる、いわゆるスマートコンセント・スマートプラグを自作してみるシリーズ。

 ESP8266/ESP-WROOM-32チップ単体やピッチ変換モジュールとの併用はより省スペースではありますが、ESP8266/ESP32開発ボードを使う方が、何かと手間もなく、無難です。

ESP8266 NodeMCUリモコン

 今回は、SHARP AQUOS TV用のスマートリモコンを作りました。

 と言ってもArduinoやESP8266でリモコン送受信回路を作った時に有線や無線でブラウザからエアコンやテレビが一通り動作すること、スマートスピーカーを自作した時にテレビのON/OFFができることは既に確認済み。

 要するに今回は、テレビの操作においてめぼしいボタン機能を一通り反映させた(上でスマートスピーカーで動作させてみたから書いた)に過ぎません。

 当初、パソコンやタブレット、スマホのブラウザから、これら家電を遠隔操作することを想定していましたが、今となっては、自身は、自作スマートスピーカーやメインPCにも搭載の自作スマートスピーカー機能を使って音声で操作するのがメインとなっています。

 よってブラウザからの無線操作のみならず、自作ラズパイスマートスピーカーでテレビを音声操作可能にします。

 ちなみに適当な抵抗220Ωを介し、赤外線LEDは1本、ケースは、100均セリアにあったトレーディングカードケース(半透明?)でフタを閉めた状態で操作可能でした。

ダイソー5個組ミニケースに入れたESP8266自作スマートリモコン発信器

[2019/05/07 追記]
 と思いましたが、ピンヘッダ未ハンダのESP8266開発ボードに直接、抵抗220Ω+赤外線LEDをはんだ付けしてコンパクトに。
 結果、遥かに小ぶりなダイソーのミニケース(5個組108円)に入りました。
 青系の半透明ながら、赤外線信号増幅なし・赤外線LED1個、前掲写真位置あたりで赤外線操作もできました。

操作メニュー

 今回はとりあえず、地上デジタル、BS、CS、アナログ、地上デジタル1〜12各チャンネル、番組表、番組情報、音量上げ下げ、dボタン、赤・青・黄・緑ボタン、上下左右ボタン、決定ボタン、戻るボタン、終了ボタンあたりを実装しました。

 あ、消音忘れた...けどいいか。

 尤もこれはやり過ぎ感があり、実際のところ、スマートスピーカーでのテレビ操作は、ON/OFF、チャンネル切り替えと音量調整ができれば十分だと思いますが。

事前準備

 スマートリモコンを作るにあたっては、全ては「操作(ボタン・メニュー)に対して、どんな並びの赤外線信号を送信するか」であり、基本的に、これら以外の違いはなく、家電による差もない為、ハードウェアもソフトウェアも共通。

 よって作り方の詳細は、冒頭の自作スマートリモコンのリンク先に譲ります。

 事前準備としては、markszabo/IRremoteESP8266などESP8266用の任意のIR信号送受信ライブラリを使い、ESP8266で送受信回路を作って機能させたい家電のリモコンから受信機に信号を送信、これを解析して(読み取って)おき、操作ボタンと信号のリストを作っておきます。

 尚、今回の家電は液晶テレビSHARP AQUOSですが、IRremoteESP8266のIRrecvDump/IRrecvDumpV2では(信号方式としては)、Panasonicと認識され、sendPanasonic()関数を使いました。

回路とスケッチ・プログラム

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <Arduino.h>
#include <FS.h>
 
const char* path_root   = "/index.html";
  const char *ssid = "ssid";
  const char *password = "password";
 
...
#define BUFFER_SIZE 16384
uint8_t buf[BUFFER_SIZE];
 
ESP8266WebServer server ( 80 );
IRsend irsend(4);
#define SOFTAP_SSID "ESPTV"
#define SOFTAP_PW "esp8266tv"
 
boolean readHTML() {
  File htmlFile = SPIFFS.open(path_root, "r");
  if (!htmlFile) {
    Serial.println("Failed to open index.html");
    return false;
  }
  size_t size = htmlFile.size();
  if (size >= BUFFER_SIZE) {
    Serial.print("File Size Error:");
    Serial.println((int)size);
  } else {
    Serial.print("File Size OK:");
    Serial.println((int)size);
  }
//  htmlFile.read(buf, size);
  htmlFile.close();
  return true;
}
 
void handleRoot() {
...
  Serial.println("Access");
 
  char message[20];
  String(server.arg(0)).toCharArray(message,20);
  server.send(200, "text/html", (char *)buf);
 
  if(server.arg(0).indexOf("Power") != -1){
    Serial.println("Power");
    on_off();
  }
  else if(server.arg(0).indexOf("ch1") != -1){
    Serial.println("ch1");
    ch1();
  }
  else if(server.arg(0).indexOf("ch2") != -1){
    Serial.println("ch2");
    ch2();
  }
...
//  else if(server.arg(0).indexOf("ch10") != -1){
  else if(server.arg(0).indexOf("10ch") != -1){
    Serial.println("ch10");
    ch10();
  }
...
}
...
void on_off() {
  Serial.println("Power");
  irsend.sendPanasonic(0x555A,0x555AF148688B);
  delay(10);
  irsend.sendPanasonic(0x555A,0x555AF148688B);
  delay(2000);
  server.send(200, "text/html", "Power ON/OFF");
}
...
void ch1() {
  Serial.println("1ch");
  irsend.sendPanasonic(0x555A,0xF148724C);
  delay(10);
  irsend.sendPanasonic(0x555A,0xF148724C);
  delay(2000);
  server.send(200, "text/html", "1ch");
}
...
void vol_up() {
  Serial.println("Volume Up");
  irsend.sendPanasonic(0x555A,0xF148288F);
  delay(10);
  irsend.sendPanasonic(0x555A,0xF148288F);
  delay(2000);
  server.send(200, "text/html", "Volume Up");
}
...
void prog_list() {
  Serial.println("Program List");
  irsend.sendPanasonic(0x555A,0xF148064F);
  delay(10);
  irsend.sendPanasonic(0x555A,0xF148064F);
  delay(2000);
  server.send(200, "text/html", "Program List");
}
...
void handleNotFound() {
 
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
 
  for ( uint8_t i = 0; i < server.args(); i++ ) {
    message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  }
  server.send ( 404, "text/plain", message );
}
 
 
void setup() {
  Serial.begin(115200);
 
  SPIFFS.begin();
  if (!readHTML()) {
    Serial.println("Read HTML error!!");
  }
 
  WiFi.begin(ssid, password);
  irsend.begin();
  Serial.println("");
  // AP+STAモードの設定
  WiFi.mode(WIFI_AP_STA);
  //  WiFi.mode(WIFI_STA);
  // APとして振る舞うためのSSIDとPW情報
  WiFi.softAP(SOFTAP_SSID, SOFTAP_PW);
  Serial.print("Connecting to ");
  Serial.println(SOFTAP_SSID);
  Serial.println("----------");
 
  //wait for connection
  while ( WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  if (!MDNS.begin("espshaquos")) {
    Serial.println("Error setting up MDNS responder!");
    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");
 
...
  server.on("/", handleRoot);
  server.on("/Power", on_off);
  server.on("/ch1", ch1);
...
//  server.on("/ch10", ch10);
  server.on("/10ch", ch10);
...
  server.on("/vol_up", vol_up);
...
  server.on("/prog_info", prog_info);
...
  server.onNotFound(handleNotFound);
 
  server.begin();
  Serial.println("HTTP server started");
 
  // Add service to MDNS-SD
  MDNS.addService("http", "tcp", 80);
}
 
void loop() {
  server.handleClient();
}

 ライブラリには、IRremoteESP8266を使わせて頂きました。

 自身もそうしましたが、この手のESP8266のスケッチ・プログラム概要としては、Webサーバを立てSPIFFSによりESP8266のメモリ上にトップページに各種ボタンを配置した操作画面となるHTMLファイルを置き、他に操作ごとのページ(URLだけあればよくHTMLファイルは不要)を作り、そこにアクセスするとそれぞれの操作信号を送信するという作りにするのが一般的でしょう。

 ESP8266によるアクセスポイントは、仮にESPTVとしたので無線AP一覧にもこれが出てくることになります。

 ただ、家電の数だけSOFT_APを立てると1軒でも結構な数になり、帯域を消費してしまうとしたら、微妙かなと...。

 mDNSは、仮にespshaquosとしたのでespshaquos.localでPCブラウザなどからアクセスでき、SPIFFSでHTMLファイルをアップロードしていれば、例えば、操作画面が表示され、espshaquos.local/Powerにアクセスすると個別に電源ON/OFF操作できるようになっています。

[2019/04/30 訂正・追記:]
 勘違い...、APモードにする(Soft_APを立てる)必要はありませんでした。

[2019/05/05 追記:]
 ESP8266WebServerのメソッドindexOf()でPOSTデータを評価させるにあたり、1ch/10ch/11ch/12chが全て1chと判定されたり、11chが1ch、12chが2chと判定されたりする状況に遭遇しました。
 数値混じりは苦手なのかも...。
 というわけで10ch/11ch/12chのみch10/ch11/ch12としたところ、回避できました。
 ついては、handleRoot()内の当該箇所とESP8266に投げるデータとなるSPIFFSでアップしてあるHTMLファイルの当該箇所(value値)を同様に10chからch10などに変更、ブラウザ上の表記もそうなってしまいますが妥協しました。
 onメソッドの方(GETデータ)は、どちらでも構いません。

操作パネル例

テレビ用ESP8266自作スマートリモコン操作パネル例
[2019/05/05]

 SPIFFSを利用する場合、テレビだと例えば、こんな感じ、メインメニューは、メイン操作パネルのようなイメージ、個々の家電でいうとエアコンの場合、自作スマートリモコンで東芝エアコン大清快を遠隔操作の例のようになります。

 前述の通り、indexOf()の件を回避すべく、操作パネル上でもinputタグのvalue値も10chではなく、ch10のようにしている為、表記も10ch〜12chまでは、あえてch10〜ch12としている一方、GET(≒URL)でのアクセスの場合、espshaquos.local/10chなどとすることは可能です。

リモコンとしてのESP8266

 ESP8266とリモコン参照。

ホーム前へ次へ