μWebSockets

websockets for microcontrollers
ORIGINAL POST
By David
details

screenshot-20210707-065911.png 2015-10-12_10-01-21

Simple to use implementation of WebSockets for microcontrollers.

List of supported IDEs:

List of supported MCUs:

  • ATmega328P
  • ATmega2560
  • SAMD21 (ARM Cortex-M0+)
  • STM32 (ARM Cortex-M)
  • ESP8266
  • ESP32-WROOM-32D

WebSocketServer compatible browsers:

  • Chrome
  • Edge
  • Firefox
  • Opera

Installation

Use Arduino Download Manager or follow this guide.

config.h

Change the following definition if you use a different network controller:

...

#define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00
ETHERNET_CONTROLLER_W5X00
ETHERNET_CONTROLLER_ENC28J60
NETWORK_CONTROLLER_WIFI

ETHERNET_CONTROLLER_W5X00 stands for the official Arduino Ethernet library.

Uncomment these if you want additional information on the serial monitor:

//#define _DEBUG
//#define _DUMP_HANDSHAKE
//#define _DUMP_FRAME_DATA
//#define _DUMP_HEADER

Increase the following value if you expect big data frames (or decrease for devices with a small amount of memory).

constexpr uint16_t kBufferMaxSize{ 256 };

Physical connection

If you have a WeMos D1 in the size of Arduino Uno simply attaching a shield does not work. You have to wire the ICSP on an Ethernet Shield to proper pins.

Ethernet Shield
(W5100/W5500)
Arduino
Pro Mini
WeMos D1
(ICSP) MISOPIN 12D12 / MISO
(ICSP) MOSIPIN 11D11 / MOSI
(ICSP) SCKPIN 13D13 / SCK
(SS) PIN 10PIN 10D10 / SS
W5500 /
ENC28j60
Arduino Uno /
Pro Mini
Arduino
Mega2560
MISOPIN 12PIN 50
MOSIPIN 11PIN 51
SCSPIN 10PIN 53
SCLKPIN 13PIN 52

Usage examples

Server

#include <WebSocketServer.h>
using namespace net;

WebSocketServer server{3000};

void setup() {
  // Ethernet/WiFi initialization goes here ...
  // ...

  server.onConnection([](WebSocket &ws) {
    const char message[]{ "Hello from Arduino server!" };
    ws.send(message, strlen(message));

    ws.onClose([](WebSocket &ws, const WebSocket::CloseCode code,
                 const char *reason, uint16_t length) {
      // ...
    });
    ws.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                   const char *message, uint16_t length) {
      // ...
    });
  });

  server.begin();
}

void loop() {
  server.listen();
}

Verify clients

// verifyClient callback is called for every header during handshake
// (except for those required by protocol, like "Connection", "Upgrade" etc.)
server.begin([](const IPAddress &ip, const char *header, const char *value) {
  // verify ip ...

  // verify "Origin" header:
  if (strcmp_P(header, (PGM_P)F("Origin")) == 0)
    if (strcmp_P(value, (PGM_P)F("file://")) == 0) return false;

  return true;
});

Subprotocol negotiation

// If you won't pass callback for `protocolHandler` then server will use the
// first requested subprotocol if any
wss.begin(nullptr, [](const char *protocols) {
  // iterate csv protocols and return the one that is supported by your server
  // or nullptr to ignore
});

// You can check client protocol in other callbacks
wss.onConnection([](WebSocket &ws) {
  const auto protocol = ws.getProtocol();
  // ...
  }
});

Node.js server examples here

Client

#include <WebSocketClient.h>
using namespace net;

WebSocketClient client;

void setup() {
  // Ethernet/WiFi initialization goes here ...
  // ...

  client.onOpen([](WebSocket &ws) {
    const char message[]{ "Hello from Arduino client!" };
    ws.send(message, strlen(message));
  });
  client.onClose([](WebSocket &ws, const WebSocket::CloseCode code,
                   const char *reason, uint16_t length) {
    // ...
  });
  client.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                     const char *message, uint16_t length) {
    // ...
  });

  client.open("echo.websocket.org", 80);
}

void loop() {
  client.listen();
}

Approx memory usage

simple-client.ino example (without debug output, 128 bytes data buffer)

Ethernet.h (W5100 and W5500)

BoardProgram spaceDynamic memory
Arduino Uno24 648 bytes (76%)829 bytes (40%)
Arduino Mega256025 640 bytes (10%)857 bytes (10%)
Arduino Pro Mini24 648 bytes (80%)829 bytes (40%)
Arduino Zero30 596 bytes (11%)3 056 bytes (9%)

EthernetENC.h (ENC28j60)

BoardProgram spaceDynamic memory
Arduino Uno31 062 bytes (96%)1 406 bytes (68%)
Arduino Mega256032 074 bytes (12%)1 406 bytes (17%)
Arduino Pro Mini31 062 bytes (101%)1 406 bytes (68%)
Arduino Zero36 796 bytes (14%)3 684 bytes (11%)

WiFi

BoardProgram spaceDynamic memory
Generic ESP8266286 328 bytes (29%)27 356 bytes (33%)
WeMos D1 mini286 328 bytes (27%)27 356 bytes (33%)
NodeMCU286 328 bytes (27%)27 356 bytes (33%)

screenshot-20210707-065911.png 2015-10-12_10-01-21

Simple to use implementation of WebSockets for microcontrollers.

List of supported IDEs:

List of supported MCUs:

  • ATmega328P
  • ATmega2560
  • SAMD21 (ARM Cortex-M0+)
  • STM32 (ARM Cortex-M)
  • ESP8266
  • ESP32-WROOM-32D

WebSocketServer compatible browsers:

  • Chrome
  • Edge
  • Firefox
  • Opera

Installation

Use Arduino Download Manager or follow this guide.

config.h

Change the following definition if you use a different network controller:

...

#define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00
ETHERNET_CONTROLLER_W5X00
ETHERNET_CONTROLLER_ENC28J60
NETWORK_CONTROLLER_WIFI

ETHERNET_CONTROLLER_W5X00 stands for the official Arduino Ethernet library.

Uncomment these if you want additional information on the serial monitor:

//#define _DEBUG
//#define _DUMP_HANDSHAKE
//#define _DUMP_FRAME_DATA
//#define _DUMP_HEADER

Increase the following value if you expect big data frames (or decrease for devices with a small amount of memory).

constexpr uint16_t kBufferMaxSize{ 256 };

Physical connection

If you have a WeMos D1 in the size of Arduino Uno simply attaching a shield does not work. You have to wire the ICSP on an Ethernet Shield to proper pins.

Ethernet Shield
(W5100/W5500)
Arduino
Pro Mini
WeMos D1
(ICSP) MISOPIN 12D12 / MISO
(ICSP) MOSIPIN 11D11 / MOSI
(ICSP) SCKPIN 13D13 / SCK
(SS) PIN 10PIN 10D10 / SS
W5500 /
ENC28j60
Arduino Uno /
Pro Mini
Arduino
Mega2560
MISOPIN 12PIN 50
MOSIPIN 11PIN 51
SCSPIN 10PIN 53
SCLKPIN 13PIN 52

Usage examples

Server

#include <WebSocketServer.h>
using namespace net;

WebSocketServer server{3000};

void setup() {
  // Ethernet/WiFi initialization goes here ...
  // ...

  server.onConnection([](WebSocket &ws) {
    const char message[]{ "Hello from Arduino server!" };
    ws.send(message, strlen(message));

    ws.onClose([](WebSocket &ws, const WebSocket::CloseCode code,
                 const char *reason, uint16_t length) {
      // ...
    });
    ws.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                   const char *message, uint16_t length) {
      // ...
    });
  });

  server.begin();
}

void loop() {
  server.listen();
}

Verify clients

// verifyClient callback is called for every header during handshake
// (except for those required by protocol, like "Connection", "Upgrade" etc.)
server.begin([](const IPAddress &ip, const char *header, const char *value) {
  // verify ip ...

  // verify "Origin" header:
  if (strcmp_P(header, (PGM_P)F("Origin")) == 0)
    if (strcmp_P(value, (PGM_P)F("file://")) == 0) return false;

  return true;
});

Subprotocol negotiation

// If you won't pass callback for `protocolHandler` then server will use the
// first requested subprotocol if any
wss.begin(nullptr, [](const char *protocols) {
  // iterate csv protocols and return the one that is supported by your server
  // or nullptr to ignore
});

// You can check client protocol in other callbacks
wss.onConnection([](WebSocket &ws) {
  const auto protocol = ws.getProtocol();
  // ...
  }
});

Node.js server examples here

Client

#include <WebSocketClient.h>
using namespace net;

WebSocketClient client;

void setup() {
  // Ethernet/WiFi initialization goes here ...
  // ...

  client.onOpen([](WebSocket &ws) {
    const char message[]{ "Hello from Arduino client!" };
    ws.send(message, strlen(message));
  });
  client.onClose([](WebSocket &ws, const WebSocket::CloseCode code,
                   const char *reason, uint16_t length) {
    // ...
  });
  client.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
                     const char *message, uint16_t length) {
    // ...
  });

  client.open("echo.websocket.org", 80);
}

void loop() {
  client.listen();
}

Approx memory usage

simple-client.ino example (without debug output, 128 bytes data buffer)

Ethernet.h (W5100 and W5500)

BoardProgram spaceDynamic memory
Arduino Uno24 648 bytes (76%)829 bytes (40%)
Arduino Mega256025 640 bytes (10%)857 bytes (10%)
Arduino Pro Mini24 648 bytes (80%)829 bytes (40%)
Arduino Zero30 596 bytes (11%)3 056 bytes (9%)

EthernetENC.h (ENC28j60)

BoardProgram spaceDynamic memory
Arduino Uno31 062 bytes (96%)1 406 bytes (68%)
Arduino Mega256032 074 bytes (12%)1 406 bytes (17%)
Arduino Pro Mini31 062 bytes (101%)1 406 bytes (68%)
Arduino Zero36 796 bytes (14%)3 684 bytes (11%)

WiFi

BoardProgram spaceDynamic memory
Generic ESP8266286 328 bytes (29%)27 356 bytes (33%)
WeMos D1 mini286 328 bytes (27%)27 356 bytes (33%)
NodeMCU286 328 bytes (27%)27 356 bytes (33%)

COMMENTS

Please Login to comment
  Subscribe  
Notify of
POSTED BY
TAGS
Reusable S/W