ESP8266でAC電源のスイッチを作る

今回はESP8266にWebサーバーを立ち上げ、そこにスマホ、PCからアクセスしてAC電源をオンオフするスイッチを作ろうと思います。AC電源をオンオフ出来るリモコンの様なものを目指します。

使用した部品リスト

No. ITEM                詳細個数   
1個ESP-WROOM-02 ESP8266シリアルwifiモデル2Mtバイト
リモートトランシーバためESP-13モデルesp wroom 02 4メートル32ビット
1個
10個ESP8266シリアル無線lanモジュールアダプタプレートESP-07に適用
され、ESP-12E、ESP-12Fワイヤレスarduinoの
1個
(要注意)
低損失三端子レギュレーター 3.3V500mA NJU7223DL1 
(4個入)(追加で0.1uFのコンデンサが2個必要)
1個
ソリッド・ステート・リレー(SSR)キット 25A(20A)タイプ1セット
タクトスイッチ2個
トグルスイッチ1個
LED2個
抵抗 10K / 1K5/2個
USB電源アダプタ コンセント 【3個セット-1USBポート】1個
10パナソニック(Panasonic) ベター小型コードコネクタ(グレー)/P WH4515HP
【純正パッケージ品】
1セット
11コンセント 取付金具1個入1枚
12パナソニック 埋込コンセント パック商品 WN1001P1個
13その他ACケーブル/板/木ネジ/STUD/ワイヤー/USBケーブル 等

製作した回路

  • 3.3V電源部
    • 今回は、USBアダプター(5V)とNJU7223を使って3.3Vを作っています。
      • NJU7223の周りに有る2個の電解コンデンサはセラミックコンデンサーでの動作しました
      • 3.3VのACアダプタを使えがNJU7223周りの回路は必要有りません。
      • 今回は、3.3VのACアダプタの価格が高かったので使用しませんでした。
      • 配線の手間を考えたら3.3VのACアダプタの方が良かったかも知れません。
  • SSR部
    • 回路図2つのAC端子にACケーブルを接続します。ACケーブルが太いのでハンダ付けに苦労していました。
    • 秋月さんのHPに下記の方法が載っていたので今回はこれを採用しています。
  • 意外と苦労したのがESP8266周り
    • 部品リストNo.2をESP8266のピッチ変換用に購入したのですが、ピッチが合わない事が分かりました。
    • 違うESP8266用のピッチ変換ボードでした。今回使用しているESP8266用に購入しないで下さい。
    • 結局、自力でピッチを変換しました。
  • GPIOピンの初期状態
    • EN端子の10kプルアップ:この端子をHighにするとチップが有効になります。
    • GPIO0,2,15
      • リセット時に各端子を下記の様に設定してプログラムの書き込み/実行を行います。
        • 書込:GPIO 0/2/15 Low/High/Low
        • 実行:GPIO 0/2/15 High/High/Low
      • 10kオームの抵抗でプルアップ、プルダウンして各ポートのHigh/Low設定
      • プッシュボタンでGPOI 0の状態を切り替えています。
  • 起動時のGPIO4の状態でAP接続とWiFi接続を選択
    • Low: AP接続
    • High: WiFi接続

実機

  • コンセント取り付け金具を折り曲げて埋め込みコンセントを取り付け
  • そこにUSBアダプターを取り付け
  • USBアダプターの下にSSRを本体とトライアックを並べて配置。
  • 前方にESP8266の基板を立て配置。
  • オスのコンセントが入力。メスのコンセントがオンオフされます。

プログラム

開発環境はArduino IDEを使用します。ファイルは、本体のswitch.inoとHP画面の設定を行うswitch.cssの2つです。先ずはswitch.inoの説明。

switch.ino

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "LittleFS.h"

const char *ssid = "ESP8266_sw";
const char *password = "12345678";
IPAddress ap_ip(192, 168, 4, 10);           // IP Address
IPAddress ap_gateway(192,168, 4, 0);         // Gateway Address

const char *SSID = "xxxxxxxxxx";
const char *PASSWORD = "xxxxxxxxxx";
IPAddress ip(192, 168, 3, 220);           // IP Address
IPAddress gateway(192,168, 3, 1);         // Gateway Address
IPAddress subnet(255, 255, 255, 0);       // Subnet Address

ESP8266WebServer server(80);

#define   P_Mode      4
#define   Run_LED     12
#define   Ready_LED   13
#define   ON_OFF      14
 
String index_top =
  "<!DOCTYPE html>\n<html>\n<head>\n<meta charset='utf-8'>\n"
  "<meta name='viewport' content='width=device-width,initial-scale=1'>\n"
  "<link rel='stylesheet' type='text/css' href='switch.css'>\n"
  "<title>Switch 1.0</title>\n</head>\n<body>\n<center>\n<div class='b_frame'>\n"
  "<div class='t_font'><u>Switch 1.0</u></div><br>\n"
  "<form method='get'>\n<button type='submit' name='1' value='0' style='background: #";

String index_bottom =
  "</button>\n</form>\n</div>\n</center>\n<script>\nhistory.pushState(null,null,'/');\n</script>\n</body>\n</html>\n";

int switch_flg = 0;

void setup()
{
    pinMode(Run_LED,OUTPUT);
    pinMode(Ready_LED,OUTPUT);
    pinMode(ON_OFF,OUTPUT);
    pinMode(P_Mode,INPUT);
    digitalWrite(Run_LED, LOW);
    digitalWrite(Ready_LED, LOW);
    digitalWrite(ON_OFF, LOW);

    Serial.begin(115200);
    Serial.println();

    LittleFS.begin();
    Serial.println("LittleFS started");
    
    Serial.println("Connecting to WiFi");
    WiFi.disconnect(true);
    WiFi.softAPdisconnect(true);
    delay(500);

    if(digitalRead(P_Mode))
    {
      WiFi.mode(WIFI_STA);
      WiFi.config(ip, gateway, subnet);
      WiFi.begin(SSID, PASSWORD);
      delay(1000);

      // Try forever
      while (WiFi.status() != WL_CONNECTED) 
      {
        Serial.println("...Connecting to WiFi");
        delay(1000);
      }
      Serial.println("Connected");
      Serial.println(SSID);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
    }
    else
    {
      WiFi.softAPConfig(ap_ip, ap_gateway, subnet);
      WiFi.softAP(ssid, password);
      IPAddress myIP = WiFi.softAPIP();
      Serial.print("AP IP address: ");
      Serial.println(myIP);
    }

    server.begin();
    server.on("/", handleRoot);
    server.onNotFound(handleWebRequests); 
    Serial.println("HTTP server started");
    digitalWrite(Ready_LED, HIGH);
}

void loop()
{
  server.handleClient();
}

void handleRoot()
{
  String cmd;

  cmd=server.argName(0);
  switch(cmd.toInt())
  {
    case 1:   // swithc On or Off
            switch_flg = !switch_flg;
            digitalWrite(Run_LED, switch_flg);
            digitalWrite(ON_OFF, switch_flg);
            break;
  }

  cmd = index_top;
  if(switch_flg) cmd += "fc2222'>On";
  else cmd += "228b22'>Off";
  cmd += index_bottom;
  server.send(200, "text/html", cmd);
}

void handleWebRequests()
{
  String dataType = "text/plain";
  String path;
  File dataFile;

  path = server.uri();
  if(path.endsWith(".css")) dataType = "text/css";
  else if(path.endsWith(".js")) dataType = "application/javascript";
  delay(5);

  dataFile = LittleFS.open(path.c_str(), "r");
  server.streamFile(dataFile, dataType);
  dataFile.close();
}
  • スマホでDNAが使えない為、HTTPサーバのアドレスを固定します。
    • AP接続時
      • 5行 SSIDの設定。今回は”ESP8266_sw”と設定
      • 6行 PASSWORDの設定。今回は”12345678″と設定
      • 7,8行 IPアドレスとGatewayアドレスの設定。(SubnetアドレスはWiFi接続と同じ)
    • WiFi接続時
      • 10,11行 WiFiルーターのSSIDとPASSWORDを指定
      • 12~13行 IP、Gateway、Subnetアドレスの指定。
  • 16行 ポート80でHTTPサーバを宣言
  • 18から21行 使用GPIOの設定
  • 23から32行 HTTPサーバーのHTMLコード
    • サーバーのHTMLコードをプログラムに埋め込んでいます。
    • HTMLのコードは下記の様に製作しています
      • ボタン定義直前までのコード index_top を読み込む
      • それにボタンの状態に合わせてコードを追加
      • 最後にindex_bottomを追加
  • 49行 LittleFS.begin();
    • HTMLのコードでCSSファイルの読み込みが有ります。
    • この読み込みをSPIFFSを使用したら動きませんでした。今回はLittleFSを使います。
  • 57行 ここで、AP接続とWiFi接続の選択を行っています。
  • 84行 HTTPサーバーを起動
  • 85行 GETの対応をhandleRootで行う
  • 86行 server.onNotFound(handleWebRequests); ここで外部ファイルの読み込みを行う。
  • 88行 準備が出来るとReady LEDを点灯する。
  • 101行 HPでボタンが押されるとID ”1”が送信される
    • 103から107行 送信される度にポートの値を反転する
  • 110から113行 この部分でHTMLを作成
  • 114行 HTMLコードをクライアントに送信
  • 117行 void handleWebRequests()
    • 外部ファイル読み込み関数
    • 今回は、CSSファイルとJavascriptファイルを読み込める様に設定しています。

HTTPサーバ起動時のHTMLコードは以下の様になります。


<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<link rel='stylesheet' type='text/css' href='switch.css'>
<title>Switch 1.0</title>
</head>
<body>
<center>
<div class='b_frame'>
<div class='t_font'><u>Switch 1.0</u></div><br>
<form method='get'>
<button type='submit' name='1' value='0' style='background: #228b22'>Off</button>
</form>
</div>
</center>
<script>
history.pushState(null,null,'/');
</script>
</body>
</html>
ADT7410/AQM1248で温湿度を測定しSPIFFSで値を自身に保存すると共にAQM1248(キャラクターLCD)に表示しす。乾電池駆動で野外でも測定可能なデータロガーです。

下記はHTMLコードで呼び出されるswitch.cssです。

switch.css

@charset "UTF-8";

.t_font {
        font-size: 40px;
        font-weight:bold;
        font-style: italic;
        color: #0ff;
}

.b_frame {
        width: 400px;
        background: #363636;
        padding: 15px;
        border-radius: 10px;
        margin-top: -30px;
        margin-right: 10px;
}

button {
        display: block;
        font-weight:bold;
        font-style: italic;
        margin: 10px;
        line-height: 60px;
        cursor: pointer;
        color: #fff;
        border-radius: 10px;
        font-size: 40px;
	    width:150px;
}

サーバーのHP画面とプログラムは下記の通り。

コンパイルと実行

今回はLittleFSを使うので本体のswitch.inoとswitch.cssを下記の様に保存します。

  • switch フォルダーの下に本体switch.inoの保存とフォルダーdataを作成
  • dataフォルダーの下にswitch.cssを保存。

プログラムの書き込みは

  • 通信用の信号、TXD、RXD、GNDをPCとつなぐ
  • コンセントのオスをAC100Vのコンセントに差し込む。
  • ResetとGPIOボタンで書き込み設定を作る
  • プログラムをコンパイル後ESP8266に焼く
  • switch.cssファイルの転送は、ここを参照下さい。

コンパイルとプログラムの転送が済んだら、

  • リセットボタンを押す。
  • 機器がReadyになるとReady LED(水色)が点灯します。
  • (WiFi接続の場合)ブラウザ(FireFoxを推奨)上げてURL欄に192.168.3.220と入力
  • 下記左が表示されます。この状態がスイッチオフです。
  • OFFボタンを押すとスイッチがオンとなり右の状態になります。後はこれの繰り返しです。

メスのコンセントに60ワットクラスのLED電球を付けてスイッチに合わせてオンオフする事を確認しました。

最後に

今回は、WiFi接続、AP接続可能はHTTPサーバをESP8266で立ち上げ、スマホ、PCからAC100VのLED電球を点灯消灯出来る事を確認出来ました。

注意

  • 今回はAC100Vの配線を行っているので配線には電気工事士の資格が必要です。
  • このスイッチは100V用LED電球等消費電力の少ない機器をつなぐ事を前提としています。
  • 実際の使用に合わせてトライアックの放熱等の処理を行って下さい。