Tuesday, May 10, 2016

NodeMCU/ESP8266 WebSocketsServer, load html from separate file in flash file system


This example have the same function of "NodeMCU/ESP8266 implement WebSocketsServer to control RGB LED", but the html is saved in separate file in flash file system instead of hard code in ino.


Prepare the html in data directory under sketch directory:

data/home.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>
<b>LED Control 2:</b><br/>
<i>Load html from separate file</i><br/>
<br/>
R: <input id="r" type="range" min="0" max="255" step="1" onchange="sendRGB();" /><br/>
G: <input id="g" type="range" min="0" max="255" step="1" onchange="sendRGB();" /><br/>
B: <input id="b" type="range" min="0" max="255" step="1" onchange="sendRGB();" /><br/>
<br/>
http://arduino-er.blogspot.com/
</body>
</html>

To upload this sketch data of html, refer last post "NodeMCU/ESP8266 read from separate file in Flash File System".

Modify the ino to load String of html from external file.

WebSocketServer_LEDcontrol.ino
//NodeMCU/ESP8266 implement WebSocketsServer to control RGB LED
//arduino-er.blogspot.com

#include <Arduino.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>

#include "FS.h"

#define LED_RED     15
#define LED_GREEN   12
#define LED_BLUE    13

ESP8266WiFiMulti WiFiMulti;

ESP8266WebServer server = ESP8266WebServer(80);
WebSocketsServer webSocket = WebSocketsServer(81);

String html_home;

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {

    switch(type) {
        case WStype_DISCONNECTED:
            Serial.printf("[%u] Disconnected!\n", num);
            break;
        case WStype_CONNECTED: {
            IPAddress ip = webSocket.remoteIP(num);
            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");
        }
            break;
        case WStype_TEXT:
            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 prepareFile(){
  
  Serial.println("Prepare file system");
  SPIFFS.begin();
  
  File file = SPIFFS.open("/home.html", "r");
  if (!file) {
    Serial.println("file open failed");  
  } else{
    Serial.println("file open success");

    html_home = "";
    while (file.available()) {
      //Serial.write(file.read());
      String line = file.readStringUntil('\n');
      html_home += line + "\n";
    }
    file.close();

    Serial.print(html_home);
  }
}

void setup() {
    //Serial.begin(921600);
    Serial.begin(115200);

    //Serial.setDebugOutput(true);

    Serial.println();
    Serial.println();
    Serial.println();

    for(uint8_t t = 4; t > 0; t--) {
        Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
        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);

    
    prepareFile();

    WiFi.softAP("arduino-er", "12345678");
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);

    // start webSocket server
    webSocket.begin();
    webSocket.onEvent(webSocketEvent);

    if(MDNS.begin("esp8266")) {
        Serial.println("MDNS responder started");
    }

    // handle index
    server.on("/", []() {
        // send home.html
        server.send(200, "text/html", html_home);
    });

    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);

    Serial.printf("Server Start\n");

}

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



- more example of "ESP8266 core for Arduino".

6 comments:

  1. During upload of your example at the beginning:
    Sketch uses 287,347 bytes (27%) of program storage space. Maximum is 1,044,464 bytes.
    Global variables use 39,000 bytes (47%) of dynamic memory, leaving 42,920 bytes for local variables. Maximum is 81,920 bytes.
    error: Failed to open COM25
    error: espcomm_open failed
    error: espcomm_upload_mem failed
    error: espcomm_upload_mem failed

    all the other examples work correctly. Any suggestion?

    ReplyDelete
    Replies
    1. It seem that you haven't check to select correct COM port in Arduino IDE-Menu-Tools-Port.

      Delete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Again, a nice job.
    This works ok for me so far.
    Thanks for chairing.
    It is a great step in the wright direction to make clear what is possible with this nice device.
    The files in the data folder seems to work (not for images I think)
    And what if I need to erase that home.html file?
    Can it be overwritten or erased?
    I also wondering why the sliders always begin in the middle?
    So much questions keep popping up every time I explorer the possibilities of the esp chip.
    Thanks again.

    ReplyDelete
  4. I could do it by turning on LEDs with buttons

    ReplyDelete