While playing around with websockets, I’m having connection issues between PB and the ESP01s and can’t figure out on which side lies the problem.
On every other attempt I’m getting the following:
[WS] WebsocketsClient::connect: CloseReason_ProtocolError
Can it be that PB gets overwhelmed if the connections happen too often or the client polls too often? I noticed that if I restart PB things are a bit better, but not every time.
I’m pasting my code, please be gentle, it’s a work in progress, I’m trying to learn how to setup server and client, send and receive frames, parse them, etc:)
I got to say, for someone as code-literate as I am, Arduino IDE’s process of having to compile and upload in order to check something is miles away from PB’s real time method:((
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <WebSockets2_Generic.h> . // CLIENT
using namespace websockets2_generic; //CLIENT
WebsocketsClient client; //CLIENT
IPAddress local_IP(192, 168, 1, 95); //SERVER
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
int button = 0;
int auxButtonState = 0; // temporary variable for reading the button pin status
const char MAIN_page[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<body>
<h2>PB Websocket Test Page</h2>
<form action="/action_page">
<p>PB Command:<br /><input name="pbcommand" type="text" value="{getConfig:true}" />
<br /><br />
<input type="submit" value="Submit" /></p>
</form>
</body>
</html>
)=====";
//SSID and Password of your WiFi router
const char* ssid = "COSMOTE-782506";
const char* password = "6sb4r2s46p88psre";
const char* hostname = "CurrentSensor";
const char* websockets_server_host = "192.168.1.12"; //Enter server address CLIENT
const uint16_t websockets_server_port = 81; // Enter server port
ESP8266WebServer server(80); //Server on port 80
const int buttonPin = 0; // the number of the pushbutton pin
int buttonState; // the current reading from the input pin
int lastButtonState = LOW; // the previous reading from the input pin
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50; // the debounce time; increase if the output flickers
void onEventsCallback(WebsocketsEvent event, String data) //CLIENT
{
(void) data;
if (event == WebsocketsEvent::ConnectionOpened)
{
Serial.println("Connnection Opened");
}
else if (event == WebsocketsEvent::ConnectionClosed)
{
Serial.println("Connnection Closed");
}
else if (event == WebsocketsEvent::GotPing)
{
Serial.println("Got a Ping!");
}
else if (event == WebsocketsEvent::GotPong)
{
Serial.println("Got a Pong!");
}
}
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
String s = MAIN_page; //Read HTML contents
server.send(200, "text/html", s); //Send web page
}
//===============================================================
// This routine is executed when you press submit
//===============================================================
void handleForm() {
String PBCommand = server.arg("pbcommand");
client.onMessage([&](WebsocketsMessage message)
{
client.send(PBCommand);
client.poll();
Serial.print("PB Command:");
Serial.println(PBCommand);
});
String s = "<a href='/'> Go Back </a>";
server.send(200, "text/html", s); //Send web page
}
//==============================================================
// SETUP
//==============================================================
void setup(void){
Serial.begin(115200);
pinMode(button, INPUT);
WiFi.mode(WIFI_STA);
WiFi.config(local_IP, gateway, subnet);
WiFi.hostname(hostname);
WiFi.begin(ssid, password); //Connect to your WiFi router
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//If connection successful show IP address in serial monitor
Serial.println("");
Serial.print("Connected to ");
Serial.println("WiFi");
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
server.on("/", handleRoot); //Which routine to handle at root location
server.on("/action_page", handleForm); //form action is handled here
server.begin(); //Start server
Serial.println("HTTP server started");
Serial.print("Connected to Wifi, Connecting to WebSockets Server @"); //CLIENT
Serial.println(websockets_server_host);
// run callback when messages are received
client.onMessage([&](WebsocketsMessage message)
{
//Serial.print("Got Message: ");
//Serial.println(message.data());
});
// run callback when events are occuring
client.onEvent(onEventsCallback);
// try to connect to Websockets server
bool connected = client.connect(websockets_server_host, websockets_server_port, "/");
if (connected)
{
Serial.println("Connected!");
String WS_msg = String("Hello Server!");
client.send(WS_msg);
}
else
{
Serial.println("Not Connected!");
}
}
//==============================================================
// LOOP
//==============================================================
void loop(void){
server.handleClient(); //Handle client requests
// let the websockets client check for incoming messages
if (client.available())
{
client.poll();
}
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if (reading != buttonState) {
buttonState = reading;
// only toggle the LED if the new button state is HIGH
if (buttonState == LOW) {
Serial.print("Button Pressed");
client.send("{getConfig:true}");
//client.poll();
client.onMessage([&](WebsocketsMessage message)
{
String payload = message.data(); //Get the response payload from server
Serial.println(payload); //Print request response payload
const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
DynamicJsonBuffer jsonBuffer(capacity);
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(payload);
if (!root.success()) {
Serial.println(F("Parsing failed!"));
return;
}
// Decode JSON/Extract values
Serial.println(F("Response:"));
Serial.println(root["pixelCount"].as<char*>());
Serial.println(root["maxBrightness"].as<char*>());
});
}
}
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState = reading;
}