I am trying to set up a network of 4 esp8266 programmed via the Arduino IDE. The Network will have 1 server (esp8266 running in AP mode) and 3 clients (esp8266 running in STA mode). I would like to do two things on the network.
Each client signals the server when a certain event happens (event is different for each client) and
Server broadcasts a byte of data to ALL clients on a regular basis (e.g. 1 second)
I have adapted various code to come up with the following (most examples I have seen do not use a standalone server).
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>
#define USE_SERIAL Serial
const char *ssid = "MyNetwork";
const char *password = "MyPassword";
unsigned long last_10sec = 0;
unsigned int counter = 0;
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
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");
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload);
break;
}
}
void setup() {
WiFi.disconnect();
USE_SERIAL.begin(115200);
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFi.softAP(ssid, password,10,false,8); // setup AP on channel 10 and set 8 possible connections
IPAddress myIP = WiFi.softAPIP();
USE_SERIAL.print("AP IP address: ");
USE_SERIAL.println(myIP);
// start webSocket server
USE_SERIAL.println("start websockets");
webSocket.begin();
webSocket.onEvent(webSocketEvent);
USE_SERIAL.println("websockets started");
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>");
});
USE_SERIAL.println("start server");
server.begin();
USE_SERIAL.println("end setup and goto main loop");
}
void loop() {
unsigned long t = millis();
//;
server.handleClient();
if((t - last_10sec) > 30000) {
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();
}
}
client code is
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h>
#include <Hash.h>
const char *ssid = "MyNetwork";
const char *password = "MyPassword";
bool isConnected = false;
ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
#define USE_SERIAL Serial
#define MESSAGE_INTERVAL 10000
#define HEARTBEAT_INTERVAL 15000
uint64_t messageTimestamp = 0;
uint64_t heartbeatTimestamp = 0;
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
USE_SERIAL.printf("[WSc] Disconnected!\n");
isConnected=false;
break;
case WStype_CONNECTED: {
USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload);
isConnected = true;
// send message to server when Connected
webSocket.sendTXT("Connected");
}
break;
case WStype_TEXT:
USE_SERIAL.printf("[WSc] get text: %s\n", payload);
// send message to server
// webSocket.sendTXT("message here");
break;
case WStype_BIN:
USE_SERIAL.printf("[WSc] get binary length: %u\n", length);
hexdump(payload, length);
// send data to server
// webSocket.sendBIN(payload, length);
break;
/* case WStype_PING:
// pong will be send automatically
USE_SERIAL.printf("[WSc] get ping\n");
break;
case WStype_PONG:
// answer to a ping we send
USE_SERIAL.printf("[WSc] get pong\n");
break;
}*/
}
}
void setup() {
USE_SERIAL.begin(115200);
//Serial.setDebugOutput(true);
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] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// was WiFiMulti.addAP("SSID", "passpasspass");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
USE_SERIAL.printf(".");
}
USE_SERIAL.println("start websocket");
// server address, port and URL
webSocket.begin("192.168.4.1", 81, "/");
// event handler
webSocket.onEvent(webSocketEvent);
delay(10000);
// try ever 5000 again if connection has failed
webSocket.setReconnectInterval(5000);
USE_SERIAL.println("end of setup. Goto Main loop");
}
void loop() {
webSocket.loop();
if(isConnected) {
USE_SERIAL.printf("Connected\n");
uint64_t now = millis();
if(now - messageTimestamp > MESSAGE_INTERVAL) {
messageTimestamp = now;
USE_SERIAL.printf("send message\n");
// example socket.io message with type "messageType" and JSON payload
webSocket.sendTXT("42[\"messageType\",{\"greeting\":\"hello\"}]");
}
if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) {
heartbeatTimestamp = now;
USE_SERIAL.printf("heartbeat\n");
// socket.io heartbeat message
webSocket.sendTXT("2");
}
}
else
{
USE_SERIAL.printf("not connected\n");
delay(10000);
}
}
The debug output for server is
19:38:30.671 -> SDK:2.2.1(cfd48f3)/Core:2.5.2=20502000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020
19:38:30.671 ->
19:38:30.671 -> [SETUP] BOOT WAIT 4...
19:38:31.657 -> [SETUP] BOOT WAIT 3...
19:38:32.689 -> [SETUP] BOOT WAIT 2...
19:38:33.673 -> [SETUP] BOOT WAIT 1...
19:38:34.657 -> [AP] softap config unchanged
19:38:34.704 -> AP IP address: 192.168.4.1
19:38:34.704 -> start websockets
19:38:34.704 -> [WS-Server] Server Started.
19:38:34.704 -> websockets started
19:38:34.704 -> start server
19:38:34.704 -> end setup and goto main loop
19:38:58.354 -> wifi evt: 7
19:38:58.495 -> wifi evt: 7
19:38:58.635 -> wifi evt: 7
19:39:00.606 -> 0 Connected websocket clients ping: 1
19:39:00.935 -> add 1
19:39:00.935 -> aid 1
19:39:00.935 -> station: xx:xx:xx:xx:xx:xx join, AID = 1
19:39:00.935 -> wifi evt: 5
19:39:01.075 -> wifi evt: 9
19:39:03.102 -> wifi evt: 7
19:39:03.257 -> wifi evt: 7
19:39:03.377 -> wifi evt: 7
19:39:03.527 -> wifi evt: 7
19:39:03.837 -> wifi evt: 7
19:39:30.567 -> 0 Connected websocket clients ping: 0
19:40:00.595 -> 0 Connected websocket clients ping: 1
19:40:30.573 -> 0 Connected websocket clients ping: 0
19:41:00.577 -> 0 Connected websocket clients ping: 1
and debug output for client is
19:13:45.235 -> SDK:2.2.1(cfd48f3)/Core:2.5.2=20502000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1-7-g82abda3/BearSSL:a143020
19:13:45.235 ->
19:13:45.235 ->
19:13:45.235 ->
19:13:45.235 -> [SETUP] BOOT WAIT 4...
19:13:46.267 -> [SETUP] BOOT WAIT 3...
19:13:46.642 -> wifi evt: 2
19:13:47.251 -> [SETUP] BOOT WAIT 2...
19:13:48.095 -> scandone
19:13:49.032 -> state: 0 -> 2 (b0)
19:13:49.032 -> [SETUP] BOOT WAIT 1...
19:13:49.032 -> state: 2 -> 3 (0)
19:13:49.079 -> state: 3 -> 5 (10)
19:13:49.079 -> add 0
19:13:49.079 -> aid 1
19:13:49.079 -> cnt
19:13:49.079 ->
19:13:49.079 -> connected with MyNetwork, channel 10
19:13:49.079 -> dhcp client start...
19:13:49.079 -> wifi evt: 0
19:13:49.219 -> ip:192.168.4.2,mask:255.255.255.0,gw:192.168.4.1
19:13:49.219 -> wifi evt: 3
19:13:50.626 -> ....scandone
19:13:52.641 -> .start websocket
19:13:59.062 -> pm open,type:2 0
19:14:02.624 -> end of setup. Goto Main loop
19:14:02.624 -> [WS-Client] connect ws...
19:14:02.624 -> [hostByName] Host: 192.168.4.1 is a IP!
19:14:02.671 -> [WS-Client] connected to 192.168.4.1:81.
19:14:02.671 -> [WS-Client][sendHeader] sending header...
19:14:02.671 -> [WS-Client][sendHeader] handshake GET / HTTP/1.1
19:14:02.671 -> Host: 192.168.4.1:81
19:14:02.671 -> Connection: Upgrade
19:14:02.671 -> Upgrade: websocket
19:14:02.671 -> Sec-WebSocket-Version: 13
19:14:02.671 -> Sec-WebSocket-Key: 8L/m+WcjssjBS/Sa8a0Qvg==
19:14:02.671 -> Sec-WebSocket-Protocol: arduino
19:14:02.671 -> Origin: file://
19:14:02.671 -> User-Agent: arduino-WebSocket-Client
19:14:02.671 ->
19:14:02.671 -> [write] n: 241 t: 17509
19:14:02.671 -> [WS-Client][sendHeader] sending header... Done (23209us).
19:14:02.671 -> not connected
19:14:12.661 -> not connected
19:14:22.659 -> not connected
19:14:32.664 -> not connected
19:14:42.687 -> not connected
19:14:52.671 -> not connected
19:15:02.657 -> not connected
19:15:12.692 -> not connected
19:15:22.677 -> not connected
19:15:32.674 -> not connected
I am reading this as the client connecting to the AP but not connecting via websockets. Can anyone assist?
server(80)
and the client you set aswebSocket.begin(ip, 81,...)
.why you do that? Try to use same port. – abu-ahmed al-khatiri Sep 2 at 10:30