ESP8266とブラウザ上で動作するWebアプリとを、WebSocketで接続し、ブラウザ上に表示されているスライダーにより、ESP8266に接続したRGBフルカラーLEDの色を変更します。ESP8266は、「TRIAL-ESP8266-LEAFキットでWi-Fi接続」TRIAL-ESP8266-LEAFキットを使用します。また、「Raspberry PiにNode.jsのインストールしてWebSocketを実装」では、Raspberry PiでNode.jsによりWebSocketを実装しました。
ESP8266の結線
TRIAL-ESP8266-LEAFキットのSV4の信号ピンに、次のように結線します。電源はアルカリ電池3本(4.5V)を接続します。
SV4の信号ピン | 接続先 |
---|---|
3.3V | 電池+ |
D12 | LED(G) |
D13 | LED(B) |
D15 | LED(R) |
GND | 電池-とLED(カソード) |
RGBフルカラーLEDの信号割り当てを次に示します。
WebSocketライブラリのインストール
WebSocketライブラリは、「arduinoWebSockets」を使用します。GitHub からダウンロードしたZIP形式のArduinoライブラリを、次の手順でインストールします。
- Arduino IDE を開いて、メニューバーの「スケッチ」⇒「ZIP形式のライブラリをインストール」をクリックします。
- ダイアログが表示されるので、ダウンロードしたZIP形式のArduinoライブラリを選択します。
- メニューバーの「ファイル」⇒「スケッチ例」から次のようにWebSocketライブラリを使用したスケッチ例が登録されていることを確認します。
ESP8266側プログラム作成
サーバとして作成するESP8266側プログラム「WebSocketServerAllFunctionsDemo.ino」を次に示します。このプログラムは「WebSocketServerAllFunctionsDemo.ino」を参考に作成しています。
- 93行目でIPアドレスを「192.168.10.20」に固定します。
- 109行目で、イベントのコールバック「webSocketEvent」をメソッド「onEvent」により登録します。35行目のコールバック「webSocketEvent」で接続、切断、受信時のイベントを受け取ります。
- 148行目で、10秒ごとに「sendTXT」メソッドを使ってクライアントに「ping TomoSoft」を送信します。クライアントのソケットIDは、47行目で接続時にパラメータで渡される値「num」を変数「socketid」に保存します。
WebSocketServerAllFunctionsDemo.ino
/* WebSocketServerAllFunctionsDemo.ino Created on: 10.05.2018 */ #include <Arduino.h> #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include <WebSocketsServer.h> #include <ESP8266WebServer.h> #include <ESP8266mDNS.h> #include <Hash.h> #define LED_RED 15 #define LED_GREEN 12 #define LED_BLUE 13 #define USE_SERIAL Serial IPAddress ip(192, 168, 10, 20); //ip IPAddress gateway(192, 168, 10, 1); IPAddress subnet(255, 255, 255, 0); IPAddress DNS(192, 168, 10, 1); ESP8266WiFiMulti WiFiMulti; ESP8266WebServer server(80); WebSocketsServer webSocket = WebSocketsServer(81); int socketid; void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch (type) { case WStype_DISCONNECTED: USE_SERIAL.printf("[%u] Disconnected!\n", num); break; case WStype_CONNECTED: { IPAddress ip = webSocket.remoteIP(num); USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); // send message to client webSocket.sendTXT(num, "Connected TomoSoft"); socketid = num; } break; case WStype_TEXT: USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); if (payload[0] == '#') { // we get RGB data // decode rgb data uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); } break; } } void setup() { //USE_SERIAL.begin(921600); USE_SERIAL.begin(115200); //USE_SERIAL.setDebugOutput(true); USE_SERIAL.println(); USE_SERIAL.println(); USE_SERIAL.println(); for (uint8_t t = 4; t > 0; t--) { USE_SERIAL.printf("[SETUP] BOOT01 WAIT %d...\n", t); USE_SERIAL.flush(); delay(1000); } pinMode(LED_RED, OUTPUT); pinMode(LED_GREEN, OUTPUT); pinMode(LED_BLUE, OUTPUT); digitalWrite(LED_RED, 1); digitalWrite(LED_GREEN, 1); digitalWrite(LED_BLUE, 1); WiFi.config(ip, gateway, subnet, DNS); //static_ip delay(100); WiFiMulti.addAP("SSID, "PASS"); while (WiFiMulti.run() != WL_CONNECTED) { delay(100); } USE_SERIAL.printf("Module IP: "); //USE_SERIAL.printf(WiFi.localIP()[0]); ip = WiFi.localIP(); USE_SERIAL.println(ip); // start webSocket server webSocket.begin(); webSocket.onEvent(webSocketEvent); if (MDNS.begin("esp8266")) { USE_SERIAL.println("MDNS responder started"); } // handle index server.on("/", []() { // send index.html //server.send(200, "text/html", "<html><head><script>var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);connection.onopen = function () { connection.send('Connect ' + new Date()); }; connection.onerror = function (error) { console.log('WebSocket Error ', error);};connection.onmessage = function (e) { console.log('Server: ', e.data);};function sendRGB() { var r = parseInt(document.getElementById('r').value).toString(16); var g = parseInt(document.getElementById('g').value).toString(16); var b = parseInt(document.getElementById('b').value).toString(16); if(r.length < 2) { r = '0' + r; } if(g.length < 2) { g = '0' + g; } if(b.length < 2) { b = '0' + b; } var rgb = '#'+r+g+b; console.log('RGB: ' + rgb); connection.send(rgb); }</script></head><body>LED Control:<br/><br/>R: <input id=\"r\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>G: <input id=\"g\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/>B: <input id=\"b\" type=\"range\" min=\"0\" max=\"255\" step=\"1\" oninput=\"sendRGB();\" /><br/></body></html>"); }); server.begin(); // Add service to MDNS MDNS.addService("http", "tcp", 80); MDNS.addService("ws", "tcp", 81); digitalWrite(LED_RED, 0); digitalWrite(LED_GREEN, 0); digitalWrite(LED_BLUE, 0); } unsigned long last_10sec = 0; unsigned int counter = 0; void loop() { unsigned long t = millis(); webSocket.loop(); server.handleClient(); if ((t - last_10sec) > 10 * 1000) { counter++; bool ping = (counter % 2); int i = webSocket.connectedClients(ping); USE_SERIAL.printf("%d Connected websocket clients ping: %d\n", i, ping); last_10sec = millis(); webSocket.sendTXT(socketid, "ping TomoSoft"); } }
Webアプリの作成
クライアントとして作成するWebアプリ「index.html」を次に示します。WebSocket オブジェクトのメソッド等の説明については「WebSocket」を参照してください。
- 6行目で、接続時にサーバ側にメソッド「send」を使って現在時刻を送信します。
- 11行目で、クライアントから送信したデータをメソッド「onmessage」で受信します。
- 29行目で、スライダを移動させたときにサーバ側にメソッド「send」を使ってRGB色コードを送信します。
index.html
<html> <head> <script> var connection = new WebSocket('ws://' + '192.168.10.20' + ':81/', ['arduino']); connection.onopen = function () { connection.send('Connect ' + new Date()); }; connection.onerror = function (error) { console.log('WebSocket Error ', error); }; connection.onmessage = function (e) { console.log('Server: ', e.data); }; function sendRGB() { var r = parseInt(document.getElementById('r').value).toString(16); var g = parseInt(document.getElementById('g').value).toString(16); var b = parseInt(document.getElementById('b').value).toString(16); if (r.length < 2) { r = '0' + r; } if (g.length < 2) { g = '0' + g; } if (b.length < 2) { b = '0' + b; } var rgb = '#' + r + g + b; console.log('RGB: ' + rgb); connection.send(rgb); } </script> </head> <body> LED Control:<br/><br/> R: <input id="r" type="range" min="0" max="255" step="1" oninput="sendRGB();" /><br/> G: <input id="g" type="range" min="0" max="255" step="1" oninput="sendRGB();" /><br/> B: <input id="b" type="range" min="0" max="255" step="1" oninput="sendRGB();" /><br/> </body> </html>
WebSocketでの接続
ESP8266に作成したプログラムを書き込み実行します。作成したWebアプリをサーバにアップロードしてアクセスするとブラウザに次のように表示されます。ブラウザでJavaScriptからのメッセージを表示できるようにし、表示されているRスライダーを上げます。
JavaScriptから次のメッセージが表示されます。
Connected TomoSoft (index):12 Server: ping TomoSoft (index):28 RGB: #808087 (index):28 RGB: #808089 (index):28 RGB: #80808c (index):28 RGB: #80808e (index):28 RGB: #808090 (index):28 RGB: #808093 (index):28 RGB: #808095 (index):28 RGB: #808097 (index):28 RGB: #808099 (index):28 RGB: #80809c (index):28 RGB: #80809e (index):28 RGB: #8080a0 32(index):12 Server: ping TomoSoft
ESP8266に接続されたRGBフルカラーLEDが青く点灯します。