This is the multi-page printable view of this section. Click here to print...

Return to the regular view of this page

As of 2025-07-24

Relay for WebSocket

An explanation of the sample sketch spot-router, which relays data from the end device to a WebSocket server.
This is an explanation of the sample sketch spot-router, which acts as a wireless LAN end device and relays received packet data strings to a WebSocket server on the LAN.

1 - Relay for WebSocket

Latest version
This is an explanation of the sample sketch spot-router, which acts as a wireless LAN client and relays received packet data strings to a WebSocket server on the LAN.

Obtaining the source code

Available from GitHub (monowireless/spot-router).

System overview

spot-router forwards strings output based on data received by the TWELITE parent device (in ModBus ASCII format of App_Wings) to a WebSocket server.

Requirements for development

Environment setup

Installing IDE and toolchain

Please refer to How to set up a development environment with Arduino IDE 1.x.

Installing libraries

First, if there is no libraries folder in the Arduino sketchbook location (specified in Arduino IDE preferences, e.g., C:\Users\foo\Documents\Arduino), create it.

WebSocket library

  1. Download the Zip file from GitHub (Links2004/arduinoWebSockets)
  2. Extract the Zip file and place the arduinoWebSockets-<version> folder into the libraries folder

Obtaining the project files

  1. Download the Zip file from GitHub (monowireless/spot-router)
  2. Extract the Zip file and rename the folder from spot-router-main to spot-router
  3. Place the spot-router folder into the Arduino sketchbook location (specified in Arduino IDE preferences, e.g., C:\Users\foo\Documents\Arduino)

Changing user settings

Open config.h from the top tab in Arduino IDE and modify the wireless LAN and WebSocket server settings (Details).

How to upload the project file

Please refer to How to upload sketches to ESP32.

Sketch

This is an explanation of the Arduino sketch spot-router.ino.

Including libraries

Arduino and ESP32 official libraries

Lines 4-5 include the official Arduino and ESP32 libraries.

#include <Arduino.h>
#include <WiFi.h>
Header fileDescriptionNotes
Arduino.hBasic Arduino librarySometimes can be omitted but included here for completeness
WiFi.hESP32 WiFi

Third-party libraries

Line 8 includes a third-party library.

#include <WebSocketsClient.h>
Header fileDescriptionNotes
WebSocketsClient.hActs as a WebSocket client

MWings library

Line 11 includes the MWings library.

#include <MWings.h>

Defining user settings

Line 14 includes config.h.

#include "config.h"

Defining wireless LAN settings

Lines 4-5 in config.h define wireless LAN settings applied to the ESP32 onboard TWELITE SPOT.

const char* WIFI_SSID = "YOUR SSID";            // Modify it
const char* WIFI_PASSWORD = "YOUR PASSWORD";    // Modify it
NameDescription
WIFI_SSIDSSID of the network to connect to
WIFI_PASSWORDPassword of the network to connect to

Defining WebSocket settings

Lines 8-10 in config.h define WebSocket client settings.

const char* WS_SERVER_IP = "YOUR ADDRESS";    // Modify it
const int WS_SERVER_PORT = 8080;
const char* WS_SERVER_PATH = "/";
NameDescription
WS_SERVER_IPIP address of the server to send to
WS_SERVER_PORTPort number of the server to send to
WS_SERVER_PATHPath of the WebSocket server to send to

Defining pin numbers

Lines 17-21 define pin numbers.

const uint8_t TWE_RST = 5;
const uint8_t TWE_PRG = 4;
const uint8_t LED = 18;
const uint8_t ESP_RXD1 = 16;
const uint8_t ESP_TXD1 = 17;
NameDescription
TWE_RSTPin number connected to TWELITE’s RST pin
TWE_PRGPin number connected to TWELITE’s PRG pin
LEDPin number connected to the ESP32 onboard LED
ESP_RXD1Pin number connected to TWELITE’s TX pin
ESP_TXD1Pin number connected to TWELITE’s RX pin

Defining TWELITE settings

Lines 24-27 define settings applied to the TWELITE parent device onboard TWELITE SPOT.

const uint8_t TWE_CH = 18;
const uint32_t TWE_APPID = 0x67720102;
const uint8_t TWE_RETRY = 2;
const uint8_t TWE_POWER = 3;
NameDescription
TWE_CHTWELITE frequency channel
TWE_APPIDTWELITE application ID
TWE_RETRYTWELITE retry count (when sending)
TWE_POWERTWELITE transmission power

Declaring global objects

Line 30 declares a global object.

WebSocketsClient webSocket;
NameDescription
webSocketWebSocket client interface

Declaring function prototypes

Line 33 declares a function prototype.

String createPacketStringFrom(const BarePacket& packet);
NameDescription
createPacketStringFrom()Reconstructs a formatted string from received packet data

Setting up TWELITE

Lines 42-47 call Twelite.begin() to configure and start the TWELITE parent device onboard TWELITE SPOT.

Serial2.begin(115200, SERIAL_8N1, ESP_RXD1, ESP_TXD1);
    if (Twelite.begin(Serial2,
                      LED, TWE_RST, TWE_PRG,
                      TWE_CH, TWE_APPID, TWE_RETRY, TWE_POWER)) {
        Serial.println("Started TWELITE.");
    }
ParameterTypeDescription
Serial2HardwareSerial&Serial port used for communication with TWELITE
LEDintPin number connected to status LED
TWE_RSTintPin number connected to TWELITE’s RST pin
TWE_PRGintPin number connected to TWELITE’s PRG pin
TWE_CHANNELuint8_tTWELITE frequency channel
TWE_APP_IDuint32_tTWELITE application ID
TWE_RETRYuint8_tTWELITE retry count (when sending)
TWE_POWERuint8_tTWELITE transmission power

Registering event handlers

Lines 49-54 register processing to be performed when packets are received from any client application.

Twelite.on([](const BarePacket& packet) {
    String packetStr = createPacketStringFrom(packet);
    if (not(packetStr.length() <= 0)) {
        webSocket.sendTXT(packetStr.c_str());
    }
});

Here, a formatted string (in ModBus ASCII format) is reconstructed from the packet data and sent to the WebSocket server.

Configuring wireless LAN

Lines 57-71 configure the wireless LAN.

WiFi.mode(WIFI_STA);
WiFi.setAutoReconnect(true);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
    static int count = 0;
    Serial.print('.');
    delay(500);
    // Retry every 5 seconds
    if (count++ % 10 == 0) {
        WiFi.disconnect();
        WiFi.reconnect();
        Serial.print('!');
    }
}

Here, the device is set as a wireless LAN client and connects to the specified network.

Configuring WebSocket

Lines 76-77 configure the WebSocket.

webSocket.begin(WS_SERVER_IP, WS_SERVER_PORT, WS_SERVER_PATH);
webSocket.setReconnectInterval(5000);

Here, the WebSocket server and reconnection interval are specified.

Also, lines 78-97 register events for when the connection to the server is disconnected, connected, and when messages are received.

webSocket.onEvent([](WStype_t type, uint8_t* payload, size_t length) {
    switch (type) {
    case WStype_DISCONNECTED: {
        Serial.println("Disconnected!");
        break;
    }
    case WStype_CONNECTED: {
        Serial.print("Connected to url: ");
        Serial.println(reinterpret_cast<char*>(payload));
        webSocket.sendTXT("This is TWELITE SPOT to ground control");
        break;
    }
    case WStype_TEXT: {
        Serial.print("Got text: ");
        Serial.println(reinterpret_cast<char*>(payload));
        break;
    }
    default: break;
    }
});

In particular, when connected to the server, a message is sent to the server.

webSocket.sendTXT("This is TWELITE SPOT to ground control");

Updating TWELITE data

Line 102 calls Twelite.update().

Twelite.update();

Twelite.update() reads packet data bytes (in ModBus ASCII format) sequentially from the TWELITE parent device.

Updating WebSocket data

Line 103 calls the process to update WebSocket data.

webSocket.loop();

Appendix: Verifying operation with WebSocket server

extra/python-websocket-server/server.py is a Python script that sets up a WebSocket server and displays packet data strings from the ESP32. Using this script, you can verify the sketch operation.

# -*- coding: utf-8-unix -*-
# Python 3.11

import logging
from websocket_server import WebsocketServer

def new_client(client, server):
    server.send_message_to_all("This is ground control to TWELITE SPOT")

def new_message(client, server, message):
    print("Received an message:")
    print(message)

server = WebsocketServer(host="YOUR IP ADDRESS", port=8080, loglevel=logging.INFO)
server.set_fn_new_client(new_client)
server.set_fn_message_received(new_message)
server.run_forever()

The coding variable is specified because the author’s environment is Emacs. It is not a magic spell.

Verification procedure

Running the script

Install dependencies and then run.


pip3 install websocket-server
python3 server.py

When running, the following messages appear.

INFO:websocket_server.websocket_server:Listening on port 8080 for clients..
INFO:websocket_server.websocket_server:Starting WebsocketServer on main thread.

Confirming client connection

When the ESP32 successfully connects to the wireless LAN, it attempts to connect to the WebSocket server.

Upon successful connection, the client-side serial console outputs as follows.

Started TWELITE.
Connecting to WiFi .....
Connected. IP: xxx.xxx.xxx.xxx
Connected to url: /
Got text: This is ground control to TWELITE SPOT

On the server-side terminal, the output is as follows.

Received an message:
This is TWELITE SPOT to ground control

Afterwards, when TWELITE SPOT receives packets from client devices, the packet data strings are output to the server terminal as follows.

Received an message:
:80000000DE10098201BC8201800607003400038135001205350401000000113008020A8C1130010203AF0000000180050100020AC60102000211D7AF30

Received an message:
:80000000E4100A8201BC8201800607003400038135001205350401000000113008020A8C1130010203AC0000000180050100020AC40102000211DB0DCC

TWELITE

Arduino

ESP32

Community

Libraries

Plugins

WebSocket

Community