Hello all,
I'm trying to get some webSocket frames from a server, and the way I've setup my sketch this is happening within setup() and not loop(). I need to leave the connection open for a bit so that I receive a few frames and parse the ones of interest, then close it but at the moment I only get the first one. I can't use delay(), so I thought of doing it with millis() but it doesn't change anything, I guess because this can only happen within loop()? Is there another non-blocking way of doing it within setup? I tried moving the whole part of code in loop() but that created new issues I couldn't resolve-the connection would stay open forever. I'm completely inexperienced with coding btw:)
This is the bit in setup:
// run callback when messages are received
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["brightness"].as<char*>());
client.close();
});
This is the whole sketch:
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <ArduinoWebsockets.h>
using namespace websockets;
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
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 = 3;
int auxButtonState = 0; // temporary variable for reading the button pin status
int period = 4000;
unsigned long time_now = 0;
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-xxx";
const char* password = "xxxx";
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 = 3; // 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");
}
}
//===============================================================
// This routine is executed when you open its IP in browser
//===============================================================
void handleRoot() {
String s = MAIN_page; //Read HTML contents
server.send_P(200, "text/html", MAIN_page, sizeof(MAIN_page) );
}
//===============================================================
// This routine is executed when you press submit
//===============================================================
void handleForm() {
String PBCommand = server.arg("pbcommand");
// try to connect to Websockets server
bool connected = client.connect(websockets_server_host, websockets_server_port, "/");
if (connected)
{
client.send(PBCommand);
Serial.print("PB Command:");
Serial.println(PBCommand);
}
else
{
Serial.println("Not Connected!");
}
String s = "<a href='/'> Go Back </a>";
server.send(200, "text/html", s); //Send web page
}
//==============================================================
// SETUP
//==============================================================
void setup(void){
Serial.begin(115200,SERIAL_8N1,SERIAL_TX_ONLY);
while (!Serial) {
// will pause Zero, Leonardo, etc until serial console opens
delay(1);
}
Wire.begin(0, 2);
uint32_t currentFrequency; //INA219
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");
// run callback when messages are received
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["brightness"].as<char*>());
client.close();
});
// run callback when events are occuring
client.onEvent(onEventsCallback);
if (! ina219.begin()) {
Serial.println("Failed to find INA219 chip");
while (1) { delay(10); }
}
Serial.println("Measuring voltage and current with INA219 ...");
}
//==============================================================
// LOOP
//==============================================================
void loop(void){
server.handleClient(); //Handle client requests
// let the websockets client check for incoming messages
if (client.available())
{
client.poll();
}
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);
// 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");
// try to connect to Websockets server
bool connected = client.connect(websockets_server_host, websockets_server_port, "/");
if (connected)
{
client.send("{getConfig:true}");
Serial.print("PB Command: {getConfig:true}");
}
else
{
Serial.println("Not Connected!");
}
}
}
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState = reading;
if((unsigned long)(millis() - time_now) > period){
time_now = millis();
Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V");
Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.println("");
}
}
Thanks!