-->
Page 1 of 1

Using websockets in AP-mode?

PostPosted: Sat Dec 15, 2018 6:31 am
by burton666
have taken som existing code which reads a sensor and outputs to a webserver using websockets (running on an ESP8266) that connects to a wifi-network. I tried to modify the code so that instead of connecting to an existing wifi it creates a AP that I can connect to login to the webserver to show the data.

I can connect to the AP and also connect to the webserver after logging in to the AP. But ít only shows a empty table. If I look at the serial monitor the sensor outputs all data correctly.

Have I done anything wrong modifying the code?

Code: Select all// ESP8266 Pins
//  4(SDA) --- AMG8833 SDA
//  5(SCL) --- AMG8833 SCL
//  13     --- LED (Anode) via 100ohm

#include <pgmspace.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WebSocketsServer.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <Wire.h>
#include <Adafruit_AMG88xx.h>

Adafruit_AMG88xx amg;

const char* ssid = "Jacksson";
const char* password = "mandelvatten";

const int pin_led = 13;

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

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
  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);
      break;
  }
}

void toggle() {
  static bool last_led = false;
  last_led = !last_led;
  digitalWrite(pin_led, last_led);
}

void handleRoot() {
 auto ip = WiFi.localIP();
 String ip_str = String(ip[0]) + "." + ip[1] + "." + ip[2] + "." + ip[3];
 server.send(200, "text/html", String(ws_html_1()) +  ip_str + ws_html_2());
 // server.send(200, "text/html", "<h1>You are connected</h1>");
}

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 WiFiEvent(WiFiEvent_t event) {
    switch(event) {
     
      case WIFI_EVENT_STAMODE_DISCONNECTED:
        digitalWrite(pin_led, LOW);
        Serial.println("WiFi lost connection: reconnecting...");
        WiFi.begin();
        break;
      case WIFI_EVENT_STAMODE_CONNECTED:
        Serial.print("Connected to ");
        Serial.println(ssid);
        break;
      case WIFI_EVENT_STAMODE_GOT_IP:
        digitalWrite(pin_led, HIGH);
        Serial.print("IP address: ");
        Serial.println(WiFi.localIP());
        if (MDNS.begin("esp8266-amg8833")) {
          Serial.println("MDNS responder started");
        }
        enableOTA();
        break;
    }
}

void enableOTA() {
  // Port defaults to 8266
  // ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
  // ArduinoOTA.setHostname("myesp8266");

  // No authentication by default
  // ArduinoOTA.setPassword((const char *)"123");

  ArduinoOTA.onStart([]() {
    Serial.println("Start");
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
    else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
    else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
    else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
    else if (error == OTA_END_ERROR) Serial.println("End Failed");
  });
  ArduinoOTA.begin();
}

void setup(void) {
 delay(1000);
  Serial.begin(115200);
  Serial.println();
  Serial.print("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.on("/", handleRoot);
  server.begin();
  Serial.println("HTTP server started");

  server.on("/current", [](){
    String str;
    server.send(200, "text/plain", get_current_values_str(str));
  });

  server.onNotFound(handleNotFound);

  server.begin();

  webSocket.begin();
  webSocket.onEvent(webSocketEvent);

  Serial.println("HTTP server started");

  amg.begin(0x69);
  delay(100); // let sensor boot up
}

void loop(void) {
  ArduinoOTA.handle();
  server.handleClient();
  webSocket.loop();

 

  static unsigned long last_read_ms = millis();
  unsigned long now = millis();
  if (now - last_read_ms > 100) {
    last_read_ms += 100;
    String str;
    get_current_values_str(str);
    Serial.println(str);
    webSocket.broadcastTXT(str);
  }
}

String& get_current_values_str(String& ret)
{
  float pixels[AMG88xx_PIXEL_ARRAY_SIZE];
  amg.readPixels(pixels);
  ret = "[";
  for(int i = 0; i < AMG88xx_PIXEL_ARRAY_SIZE; i++) {
    if( i % 8 == 0 ) ret += "\r\n";
    ret += pixels[i];
    if (i != AMG88xx_PIXEL_ARRAY_SIZE - 1) ret += ", ";
  }
  ret += "\r\n]\r\n";
  return ret;
}

const __FlashStringHelper* ws_html_1() {
  return F("<!DOCTYPE html>\n"
    "<html>\n"
    "<head>\n"
    "<title>thermo</title>\n"
    "<style>\n"
    "body {\n"
    "    background-color: #667;\n"
    "}\n"
    "table#tbl td {\n"
    "    width: 64px;\n"
    "    height: 64px;\n"
    "    border: solid 1px grey;\n"
    "    text-align: center;\n"
    "}\n"
    "</style>\n"
    "</head>\n"
    "<body>\n"
    "<h1>Exjobbsgrejs</h1>"
    "<table border id=\"tbl\"></table>\n"
    "<script>\n"
    "function bgcolor(t) {\n"
    "    if (t < 0) t = 0;\n"
    "    if (t > 30) t = 30;\n"
    "    return \"hsl(\" + (360 - t * 12) + \", 100%, 80%)\";\n"
    "}\n"
    "\n"
    "var t = document.getElementById('tbl');\n"
    "var tds = [];\n"
    "for (var i = 0; i < 8; i++) {\n"
    "    var tr = document.createElement('tr');\n"
    "    for (var j = 0; j < 8; j++) {\n"
    "        var td = tds[i*8 + 7 - j] = document.createElement('td');\n"
    "        tr.appendChild(td);\n"
    "    }\n"
    "    t.appendChild(tr);\n"
    "}\n"
    "var connection = new WebSocket('ws://");
}

const __FlashStringHelper* ws_html_2() {
  return F(":81/');\n"
    "connection.onmessage = function(e) {\n"
    "    const data = JSON.parse(e.data);\n"
    "    for (var i = 0; i < 64; i++) {\n"
    "        tds[i].innerHTML = data[i].toFixed(2);\n"
    "        tds[i].style.backgroundColor = bgcolor(data[i]);\n"
    "    }\n"
    "};\n"
    "</script>\n"
    "</body>\n"
    "</html>\n");
}


Re: Using websockets in AP-mode?

PostPosted: Sat Dec 15, 2018 1:38 pm
by rudy
Do you know if the server and the ESP8266 are using the same channel?

If you create an access point with the ESP8266, default is to use channel 1.

If the Access Point the ESP is to connect to is not on channel 1 then it will switch to the channel the Computer/Network is using. And connection that was to the ESP on channel 1 is lost.

You need to use the same channel as the computer is on for the ESP8266's access point.

WiFi.softAP(ssid, password, channel);

Re: Using websockets in AP-mode?

PostPosted: Sat Dec 15, 2018 4:49 pm
by burton666
I think I did explain badly. I meant that I could connect to the webserver on the ESP8266 but that I only get the headline and an empty grid to show.
When I run the original sketch which connects to an existing wifi I get the grid populated with data continiously.