WebSockets_Generic. Now supporting nRF52, SAMD, Teensy, STM32, DUE, etc

How To Install Using Arduino Library Manager

Current Release

Why do we need this library

Many Web services require WebSockets library , which is so far written only for ESP8266/ESP32 boards. The ESP boards rely on this Markus Sattler's WebSockets library to connect to Alexa via Sinric or SinricPro skills.

This library is based on and modified from WebSockets library to provide support to many boards such as Teensy (4.1, 4.0, 3.x, LC), Arduino SAMD21, Adafruit SAMD21/SAMD51, nRF52, STM32, etc. and enable those boards to use WebSockets services, including voice-control Alexa along with Blynk. The WebSockets can be used with ESP's WiFi, WiFiNINA, W5x00 and ENC28J60 Ethernet.

Please see illustrating examples.

New in v2.2.1

  1. Bump up to sync with v2.2.1 of original WebSockets library

New in v2.1.3

  1. Add support to nRF52 boards, such as AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B30_ublox, etc..
  2. Add support to SAM51 (Itsy-Bitsy M4, Metro M4, Grand Central M4, Feather M4 Express, etc.).
  3. Add support to SAMD21 (ZERO, MKR, NANO_33_IOT, M0, M0 Pro, AdaFruit CIRCUITPLAYGROUND_EXPRESS, etc.).
  4. Add support to Teensy (4.1, 4.0, 3.x, LC).
  5. Add support to SAM DUE.

How to use

In your code, select one of the currently supported network connection from the following list:

  1. NETWORK_ESP8266_ASYNC for ESP8266 Async
  2. NETWORK_W5100 for W5x00 Ethernet
  3. NETWORK_ENC28J60 for ENC28J60 Ethernet
  4. NETWORK_ESP32 for ESP32 WiFi
  5. NETWORK_ESP32_ETH for ESP32 Ethernet
  6. NETWORK_WIFININA for WiFiNINA

then add

#define WEBSOCKETS_NETWORK_TYPE

before

#include <WebSocketsClient_Generic.h>

Example Generic_WebSocketServer_W5500

#define _WEBSOCKETS_LOGLEVEL_     3
#define WEBSOCKETS_NETWORK_TYPE   NETWORK_W5100

#include <WebSocketsServer_Generic.h>

WebSocketsServer webSocket = WebSocketsServer(81);

uint8_t mac[6] =  { 0xDE, 0xAD, 0xBE, 0xEF, 0xBE, 0x0A };

// Select the IP address according to your local network
IPAddress ip(192, 168, 2, 222);

// Only for W5100
#define SDCARD_CS       4

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length)
{
  switch (type)
  {
    case WStype_DISCONNECTED:
      //Serial.println( "[" + String(num) + "] Disconnected!");
      break;
    case WStype_CONNECTED:
      {
        Serial.println( "[" + String(num) + "] 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.println( "[" + String(num) + "] get Text: " + String((char *) payload));

      // send message to client
      webSocket.sendTXT(num, "message here");

      // send data to all connected clients
       webSocket.broadcastTXT("message here");
      break;
    case WStype_BIN:
      Serial.println( "[" + String(num) + "] get binary length: " + String(length));
      
      //hexdump(payload, length);

      // send message to client
      // webSocket.sendBIN(num, payload, length);
      break;

      default:
        break;
  }
}

void setup()
{
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  
  // Serial.begin(921600);
  Serial.begin(115200);
  while (!Serial);

  Serial.println("\nStart Generic_WebSocketServer_W5500");

  for (uint8_t t = 4; t > 0; t--)
  {
    Serial.println("[SETUP] BOOT WAIT " + String(t));
    Serial.flush();
    delay(1000);
  }

  // start the ethernet connection and the server:
  // Use Static IP
  Ethernet.begin(mac, ip);
  //Configure IP address via DHCP
  //Ethernet.begin(mac);

  // server address, port and URL
  Serial.print("WebSockets Server IP address: ");
  Serial.println(Ethernet.localIP());
  
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
}

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

Debug Terminal Output when running nRF52_Blynk_W5500_Alexa

You can see the Adafruit NRF52840_FEATHER Express board, with W5500 Ethernet shield, connects to Blynk using BlynkEthernet_WM Library

It also uses WebSockets_Generic library to communicate with SINRIC skills, and Alexa, to control a relay using Alexa voice control via Amazon Alexa phone APP

Start nRF52_Blynk_W5500_Alexa using W5x00_Shield on NRF52840_FEATHER
LittleFS Flag read = 0xd0d04321
Flag read = 0xd0d04321
No doubleResetDetected
Saving DOUBLERESETDETECTOR_FLAG to DRD file : 0xd0d01234
Saving DRD file OK
SetFlag write = 0xd0d01234
[881] ======= Start Default Config Data =======
[881] Hdr=NonSSL,BName=Air-Control
[881] Svr=account.duckdns.org,Tok=token1
[881] Svr1=blynk-cloud.com,Tok1=<<my real Blynk auth>>
[882] Prt=8080,SIP=
[882] LoadCfgFile 
[883] OK
[883] ======= Start Stored Config Data =======
[883] Hdr=W5X00,BName=Air-Control
[883] Svr=account.duckdns.org,Tok=****
[884] Svr1=blynk-cloud.com,Tok1=****
[884] Prt=8080,SIP=
[884] CCSum=0x262e,RCSum=0x262e
[886] LoadCredFile 
[886] ChkCrR: Buffer allocated, sz=37
[886] ChkCrR:pdata=****,len=36
[886] ChkCrR:pdata=****,len=24
[886] OK
[887] CrCCsum=ea7,CrRCsum=ea7
[887] Buffer freed
[887] Valid Stored Dynamic Data
[889] LoadCredFile 
[889] CrR:pdata=****,len=36
[889] CrR:pdata=****,len=24
[889] OK
[889] CrCCsum=ea7,CrRCsum=ea7
[890] Hdr=W5X00,BName=Air-Control
[890] Svr=account.duckdns.org,Tok=****
[890] Svr1=blynk-cloud.com,Tok1=****
[890] Prt=8080,SIP=
[890] MAC:FE-F8-E0-CB-D0-BD
_pinCS = 0
W5100 init, using SS_PIN_DEFAULT = 10, new ss_pin = 10, W5100Class::ss_pin = 10
W5100::init: W5500, SSIZE =4096
[2577] IP:192.168.2.89
[2577] bg: noConfigPortal = true
[2577] bg: noConfigPortal = true
[2577] bg:ECon.TryB
[2577] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.6.1 on Arduino

[2578] BlynkArduinoClient.connect: Connecting to account.duckdns.org:8080
[2687] Ready (ping: 3ms).
[2754] Connected to Blynk Server = account.duckdns.org, Token = ****
[2754] bg:EBCon

Your stored Credentials :
SINRIC API Key = ****
Device_ID1 = ****
[WSc] Service connected to sinric.com at url: /
Waiting for commands from sinric.com ...
Stop doubleResetDetecting
Saving to DRD file : 0xd0d04321
Saving DRD file OK
LittleFS Flag read = 0xd0d04321
ClearFlag write = 0xd0d04321
[WSc] get text: {"deviceId":"****","action":"setPowerState","value":"ON"}
Turn on for unknown device id: ****
[WSc] get text: {"deviceId":"****","action":"setPowerState","value":"OFF"}
Turn off for unknown device id: ****
[WSc] get text: {"action":"test","sender":"web"}
[WSc] received test command from sinric.com
[WSc] get text: {"action":"test","sender":"web"}
[WSc] received test command from sinric.com
[WSc] get text: {"deviceId":"****","action":"setPowerState","value":"ON"}
Turn on device id: ****
[WSc] get text: {"deviceId":"****","action":"setPowerState","value":"OFF"}
Turn off Device ID: ****

New in v2.3.1

  1. Sync with v2.3.1 of original WebSockets Library
  2. Add support to ENC28J60 using EthernetENC Library
  3. Add and update examples

New in v2.2.3

  1. Add support to all STM32F/L/H/G/WB/MP1 (Nucleo-144 NUCLEO_F767ZI, Nucleo-64 NUCLEO_L053R8, etc.)
  2. Add support to Seeeduino SAMD21/SAMD51 boards (SEEED_WIO_TERMINAL, SEEED_FEMTO_M0, SEEED_XIAO_M0, Wio_Lite_MG126, WIO_GPS_BOARD, SEEEDUINO_ZERO, SEEEDUINO_LORAWAN, SEEED_GROVE_UI_WIRELESS, etc.)
  3. Add support to W5x00's Ethernet2, Ethernet3, EthernetLarge Libraries.
  4. Add sample Packages_Patches for STM32 stm32 Nucleo-144 NUCLEO_F767ZI, Nucleo-64 NUCLEO_L053R8)
  5. Add Packages' Patches and Ethernet Library Patches.

New in v2.2.2

  1. Add support to Teensy boards, such as Teensy 4.1, 4.0. 3.6, 3.5, 3.2/3.1, 3.0, LC.
  2. Add support to STM32 (Nucleo-144, Nucleo-64, Nucleo-32, Discovery, STM32F1, STM32F3, STM32F4, STM32H7, STM32L0, etc.).
  3. Add support to SAM DUE
  4. Add WebSocketServer examples to those supported boards.

===============================

Debug Terminal Output when running Generic_Ethernet_Blinds example on NRF52840_FEATHER with ENC28J60 using EthernetENC Library

You can see the NRF52840_FEATHER board, with ENC28J60 using EthernetENC Library, connects to SinricPro service using SinricPro_Generic Library

It also uses this WebSockets_Generic Library to communicate with SinricPro service, to control Blinds with a Sinric Pro phone APP

Starting Generic_Ethernet_Blinds on NRF52840_FEATHER with ENC28J60 using EthernetENC Library
[SRP] =========================
[SRP] Default SPI pinout:
[SRP] MOSI: 25
[SRP] MISO: 24
[SRP] SCK: 26
[SRP] SS: 5
[SRP] =========================
[SRP] Use default CS/SS pin :  10
Index = 6
Connected!
[Ethernet]: IP-Address is 192.168.2.97
[SRP] Creating new device. No current DeviceId = 123456789012345678901234
[SRP] add(): Adding DeviceId = 123456789012345678901234
[SRP] begin(): App-Key = 12345678-1234-1234-1234-123456789012
[SRP] begin(): App-Secret = 12345678-1234-1234-1234-123456789012-12345678-1234-1234-1234-123456789012
[SRP] Websocket: Connecting to WebSocket Server:  ws.sinric.pro
Websocket: headers:
appkey:12345678-1234-1234-1234-123456789012
deviceids:123456789012345678901234
restoredevicestates:false
platform:NRF52840_FEATHER
version:2.7.0
Connected to SinricPro
[SRP] handleReceiveQueue(): Message(s) in receiveQueue = 1
[SRP] handleReceiveQueue(): Valid Signature. Processing message...
[SRP] extractTimestamp(): Got Timestamp = 1602031564
[SRP] handleReceiveQueue(): Message(s) in receiveQueue = 1
[SRP] handleReceiveQueue(): Valid Signature. Processing message...
[SRP] extractTimestamp(): Got Timestamp = 1602031575
[SRP] handleRequest(): handling request
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setPowerState",
    "clientId": "sinricpro-web",
    "createdAt": 1602031575,
    "deviceAttributes": [],
    "deviceId": "123456789012345678901234",
    "replyToken": "4a2080b4-ca92-4fb7-aec1-3aa8d108a818",
    "type": "request",
    "value": {
      "state": "Off"
    }
  },
  "signature": {
    "HMAC": "PttsGuF4w4xfwzJHA6C5WDOmQmBgHXv9eTMSg8hYHXM="
  }
}
Device 123456789012345678901234 power turned off
[SRP] handleSendQueue(): Sending Number of Message(s) in sendQueue = 1
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setPowerState",
    "clientId": "sinricpro-web",
    "createdAt": 1602031575,
    "deviceId": "123456789012345678901234",
    "message": "OK",
    "replyToken": "4a2080b4-ca92-4fb7-aec1-3aa8d108a818",
    "success": true,
    "type": "response",
    "value": {
      "state": "Off"
    }
  },
  "signature": {
    "HMAC": "42vn7js8X+KvuHHPZSrGeJt7dtwP8VVl9Y3cZsYtXOA="
  }
}
[SRP] handleSendQueue: Sending to WebSocket
[SRP] handleSendQueue(): Message sent.
[SRP] handleReceiveQueue(): Message(s) in receiveQueue = 1
[SRP] handleReceiveQueue(): Valid Signature. Processing message...
[SRP] extractTimestamp(): Got Timestamp = 1602031577
[SRP] handleRequest(): handling request
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setPowerState",
    "clientId": "sinricpro-web",
    "createdAt": 1602031577,
    "deviceAttributes": [],
    "deviceId": "123456789012345678901234",
    "replyToken": "81a2433d-957d-481e-a9f7-2dea5c2e6c78",
    "type": "request",
    "value": {
      "state": "On"
    }
  },
  "signature": {
    "HMAC": "ir18LAhlUVCWHY5hA8QdGY8bzHE/s4XBeX8cwHTaPQI="
  }
}
Device 123456789012345678901234 power turned on
[SRP] handleSendQueue(): Sending Number of Message(s) in sendQueue = 1
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setPowerState",
    "clientId": "sinricpro-web",
    "createdAt": 1602031577,
    "deviceId": "123456789012345678901234",
    "message": "OK",
    "replyToken": "81a2433d-957d-481e-a9f7-2dea5c2e6c78",
    "success": true,
    "type": "response",
    "value": {
      "state": "On"
    }
  },
  "signature": {
    "HMAC": "9Z1uVUjeaCf1T2Ol6Fv4wXkz8gaJvEYmmIRfRcDnOgA="
  }
}
[SRP] handleSendQueue: Sending to WebSocket
[SRP] handleSendQueue(): Message sent.
[SRP] handleReceiveQueue(): Message(s) in receiveQueue = 1
[SRP] handleReceiveQueue(): Valid Signature. Processing message...
[SRP] extractTimestamp(): Got Timestamp = 1602031578
[SRP] handleRequest(): handling request
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setRangeValue",
    "clientId": "sinricpro-web",
    "createdAt": 1602031578,
    "deviceAttributes": [],
    "deviceId": "123456789012345678901234",
    "replyToken": "16d6fd59-dfd1-4017-ab51-ff8bb85fc806",
    "type": "request",
    "value": {
      "rangeValue": 100
    }
  },
  "signature": {
    "HMAC": "KfAwQ6z5XGvoZaspBVBP+CXnryW0YsEILqyxesHDhJo="
  }
}
Device 123456789012345678901234 set position to 100
[SRP] handleSendQueue(): Sending Number of Message(s) in sendQueue = 1
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setRangeValue",
    "clientId": "sinricpro-web",
    "createdAt": 1602031578,
    "deviceId": "123456789012345678901234",
    "message": "OK",
    "replyToken": "16d6fd59-dfd1-4017-ab51-ff8bb85fc806",
    "success": true,
    "type": "response",
    "value": {
      "rangeValue": 100
    }
  },
  "signature": {
    "HMAC": "CNYG9Or+ZH+R2S1Ouvd2bqX8lT/8Siu23T8LycZVtTk="
  }
}
[SRP] handleSendQueue: Sending to WebSocket
[SRP] handleSendQueue(): Message sent.
[SRP] handleReceiveQueue(): Message(s) in receiveQueue = 1
[SRP] handleReceiveQueue(): Valid Signature. Processing message...
[SRP] extractTimestamp(): Got Timestamp = 1602031579
[SRP] handleRequest(): handling request
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setRangeValue",
    "clientId": "sinricpro-web",
    "createdAt": 1602031579,
    "deviceAttributes": [],
    "deviceId": "123456789012345678901234",
    "replyToken": "864b1a6b-d539-49e0-bad8-48fa27d80d7f",
    "type": "request",
    "value": {
      "rangeValue": 0
    }
  },
  "signature": {
    "HMAC": "8CsQ57297F9lzrKBopsE8Xga2RdT9pgJpA8moGQFBTs="
  }
}
Device 123456789012345678901234 set position to 0
[SRP] handleSendQueue(): Sending Number of Message(s) in sendQueue = 1
{
  "header": {
    "payloadVersion": 2,
    "signatureVersion": 1
  },
  "payload": {
    "action": "setRangeValue",
    "clientId": "sinricpro-web",
    "createdAt": 1602031579,
    "deviceId": "123456789012345678901234",
    "message": "OK",
    "replyToken": "864b1a6b-d539-49e0-bad8-48fa27d80d7f",
    "success": true,
    "type": "response",
    "value": {
      "rangeValue": 0
    }
  },
  "signature": {
    "HMAC": "AF7bO1deIYIh3VLvVuLaRx6n1ACVYgk2Evl3NgiZ0pg="
  }
}
[SRP] handleSendQueue: Sending to WebSocket
[SRP] handleSendQueue(): Message sent.

Major Release v2.4.0

  1. Add support to Teensy 4.1 using NativeEthernet.
  2. Add support to STM32F/L/H/G/WB/MP1 using built-in LAN8742A.
  3. Sync with v2.3.4 of original WebSockets library
  4. Add Teensy, Teensy 4.1 NativeEthernet and STM32 LAN8742A examples.
  5. Fix bugs in and optimize examples.

Release v2.3.4

  1. Add SSL support to boards using WiFiNINA (Nano-33-IoT, etc.)
  2. Add SSL support to boards using Realtek RTL8720DN WiFi and Seeed_Arduino_rpcWiFi (WIO_Terminal, etc.)
  3. Upgrade WS and WSS examples.

Release v2.3.3

  1. Fix compile errors for boards (nRF52, SAMD, etc.) using libraries with lib64, such as EthernetWebServer
  2. Fix SeeedStudio SEEED_WIO_TERMINAL compile errors.
  3. Add file to SeeedStudio SAMD Packages' Patches.
  4. Fix compiler warnings for duplications in WS_LOG with WiFiWebServer

Release v2.3.2

  1. Add support to Realtek RTL8720DN WiFi using Seeed_Arduino_rpcWiFi and Seeed_Arduino_rpcUnified libraries. This RTL8720DN supports Dual-Band 2.4GHz / 5GHz Wi-Fi (802.11 a/b/g/n) as well as BLE/BLE 5.0 and is currently used in SeeedStudio SEEED_WIO_TERMINAL.
  2. Add examples for SeeedStudio SEEED_WIO_TERMINAL and update all examples
  3. Add Version string definition

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.