セクションの複数ページをまとめています。 印刷またはPDF形式で保存...

もとのページに戻る

2024-04-08 現在

WebSocketによる中継

最新版
    無線 LAN 子機として振る舞い、LAN 上の WebSocket サーバに受信したパケットデータ文字列を中継するサンプルスケッチ spot-router の解説です。

    ソースコードの入手

    GitHub (monowireless/spot-router) から入手できます。

    システムの概要

    spot-router は、TWELITE 親機が受信したデータに基づき出力した文字列(App_Wings の ModBus ASCII 形式)を WebSocket サーバへ転送します。

    開発に必要なもの

    環境整備

    IDE とツールチェインの導入

    Arduino IDE 1.x による開発環境の構築方法 をご覧ください。

    ライブラリの導入

    はじめに、Arduino のスケッチブックの保存場所(Arduino IDE 環境設定に記載。例:C:\Users\foo\Documents\Arduino) に libraries フォルダがない場合は、これを作成します。

    WebSocket ライブラリ

    1. GitHub (Links2004/arduinoWebSockets) から Zip ファイルをダウンロードします
    2. Zip ファイルを展開し、libraries フォルダに arduinoWebSockets-<バージョン> フォルダを配置します

    プロジェクトファイルの入手

    1. GitHub (monowireless/spot-router) から Zip ファイルをダウンロードします
    2. Zip ファイルを展開し、フォルダ名を spot-router-main から spot-router に変更します
    3. Arduino のスケッチブックの保存場所(Arduino IDE 環境設定に記載。例:C:\Users\foo\Documents\Arduino)に spot-router フォルダを配置します

    ユーザ設定の変更

    Arduino IDE 上部のタブから config.h を開き、無線 LAN や WebSocket サーバに関する設定( 詳細 )を変更してください。

    プロジェクトファイルの書き込み方法

    ESP32 へのスケッチの書き込み方法 をご覧ください。

    スケッチ

    Arduino スケッチ spot-router.ino の解説です。

    ライブラリのインクルード

    Arduino および ESP32 公式ライブラリ

    4-5行目では、Arduino および ESP32 の公式ライブラリをインクルードしています。

    #include <Arduino.h>
    #include <WiFi.h>
    ヘッダファイル内容備考
    Arduino.hArduino の基本ライブラリ省略できる場合もあるが念のため記載
    WiFi.hESP32 の WiFi を使う

    サードパーティのライブラリ

    8行目では、サードパーティのライブラリをインクルードしています。

    #include <WebSocketsClient.h>
    ヘッダファイル内容備考
    WebSocketsClient.hWebSocket クライアントになる

    MWings ライブラリ

    11行目では、MWings ライブラリをインクルードしています。

    #include <MWings.h>

    ユーザ設定の定義

    14行目では、config.h をインクルードしています。

    #include "config.h"

    無線 LAN 設定の定義

    config.h の4-5行目では、TWELITE SPOT に搭載された ESP32 に適用する無線 LAN 設定を定義しています。

    const char* WIFI_SSID = "YOUR SSID";            // Modify it
    const char* WIFI_PASSWORD = "YOUR PASSWORD";    // Modify it
    
    名称内容
    WIFI_SSID接続するネットワークの SSID
    WIFI_PASSWORD接続するネットワークの パスワード

    WebSocket 設定の定義

    config.h の8-10行目では、WebSocket クライアントの設定を定義しています。

    const char* WS_SERVER_IP = "YOUR ADDRESS";    // Modify it
    const int WS_SERVER_PORT = 8080;
    const char* WS_SERVER_PATH = "/";
    名称内容
    WS_SERVER_IP送信するサーバの IP アドレス
    WS_SERVER_PORT送信するサーバのポート番号
    WS_SERVER_PATH送信するサーバの WebSocket サーバのパス

    ピン番号の定義

    17-21行目では、ピン番号を定義しています。

    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;
    名称内容
    TWE_RSTTWELITE の RST ピンが接続されているピンの番号
    TWE_PRGTWELITE の PRG ピンが接続されているピンの番号
    LED基板上の ESP32 用 LED が接続されているピンの番号
    ESP_RXD1TWELITE の TX ピンが接続されているピンの番号
    ESP_TXD1TWELITE の RX ピンが接続されているピンの番号

    TWELITE 設定の定義

    24-27行目では、TWELITE SPOT に搭載された TWELITE 親機に適用する設定を定義しています。

    const uint8_t TWE_CH = 18;
    const uint32_t TWE_APPID = 0x67720102;
    const uint8_t TWE_RETRY = 2;
    const uint8_t TWE_POWER = 3;
    名称内容
    TWE_CHTWELITE の 周波数チャネル
    TWE_APPIDTWELITE の アプリケーション ID
    TWE_RETRYTWELITE の 再送回数(送信時)
    TWE_POWERTWELITE の 送信出力

    グローバルオブジェクトの宣言

    30行目では、グローバルオブジェクトを宣言しています。

    WebSocketsClient webSocket;
    名称内容
    webSocketWebSocket クライアントのインタフェース

    関数プロトタイプの宣言

    33行目では、関数プロトタイプを宣言しています。

    String createPacketStringFrom(const BarePacket& packet);
    名称内容
    createPacketStringFrom()受信したパケットデータから書式文字列を再構築します

    TWELITE の設定

    42-47行目では、Twelite.begin() を呼び出し、TWELITE SPOT に搭載された TWELITE 親機の設定と起動を行っています。

    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.");
        }
    引数内容
    Serial2HardwareSerial&TWELITE との通信に使うシリアルポート
    LEDintステータス LED を接続したピンの番号
    TWE_RSTintTWELITE の RST ピンを接続したピンの番号
    TWE_PRGintTWELITE の PRG ピンを接続したピンの番号
    TWE_CHANNELuint8_tTWELITE の 周波数チャネル
    TWE_APP_IDuint32_tTWELITE の アプリケーション ID
    TWE_RETRYuint8_tTWELITE の 再送回数(送信時)
    TWE_POWERuint8_tTWELITE の 送信出力

    イベントハンドラの登録

    49-54行目では、すべてのアプリの子機からのパケットを受信した際に行う処理を登録しています。

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

    ここでは、パケットデータから書式文字列(ModBus ASCII 形式)を再構成し、WebSocket サーバへ送信しています。

    無線 LAN の設定

    57-71行目では、無線 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('!');
        }
    }

    ここでは、無線 LAN 子機として設定したうえで、指定のネットワークへ接続しています。

    WebSocket の設定

    76-77行目では、WebSocket を設定しています。

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

    ここでは、WebSocket サーバと再接続間隔を指定しています。

    また、78-97行目では、サーバとの接続が切断されたとき、サーバと接続したとき、そしてメッセージを受信したときのイベントを登録しています。

    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;
        }
    });

    なかでも、サーバと接続したときには、サーバへメッセージを送るようにしています。

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

    TWELITE のデータの更新

    102行目では、Twelite.update() を呼び出しています。

    Twelite.update();

    Twelite.update() は、TWELITE 親機から送信されるパケットデータ(ModBus ASCII 形式)を順次1バイトずつ読み出す関数です。

    WebSocket のデータの更新

    103行目では、WebSocket のデータを更新する処理を呼び出しています。

    webSocket.loop();

    <付録> WebSocket サーバによる動作確認

    extra/python-websocket-server/server.py は、Python スクリプトによって WebSocket サーバを立て、ESP32 からのパケットデータ文字列を表示するサンプルスクリプトです。このスクリプトを使うことで、スケッチの動作を確認できます。

    # -*- 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()

    coding 変数を指定しているのは、筆者の環境が Emacs だからです。おまじないではありません。

    動作確認の手順

    スクリプトの実行

    依存モジュール をインストールしてから実行します。

    
    
    pip3 install websocket-server
    python3 server.py

    実行すると、下記のようなメッセージが表示されます。

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

    クライアントの接続を確認

    ESP32 が 無線 LAN への接続に成功すると、WebSocket サーバへの接続を試みます。

    接続に成功すると、クライアント側のシリアルコンソールには下記のように出力されます。

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

    一方で、サーバ側のターミナルには下記のように出力されます。

    Received an message:
    This is TWELITE SPOT to ground control

    以降、TWELITE SPOT が子機からのパケットを受信すると、下記のようにサーバ側のターミナルへパケットデータ文字列が出力されます。

    Received an message:
    :80000000DE10098201BC8201800607003400038135001205350401000000113008020A8C1130010203AF0000000180050100020AC60102000211D7AF30
    
    Received an message:
    :80000000E4100A8201BC8201800607003400038135001205350401000000113008020A8C1130010203AC0000000180050100020AC40102000211DB0DCC

    関連情報

    TWELITE

    Arduino

    ESP32

    コミュニティ

    ライブラリ

    プラグイン

    ネットワーク関連

    WebSocket

    コミュニティ