WizFi360-EVB-PICOを入手しました

最終更新日:2023/2/13

WizFi360-EVB-PICOを入手しました、PicoWが入手困難だったので取り敢えずです。ただ、Wiznet製のWiFiモジュールに触れるいい機会でもありました。一緒にW5100S-EVB-Picoも入手出来たのですが、残念ながらこちらはNICがまともに動作せず、故障品として倉庫行きとなってしまいました。

Wiznetが提供するライブラリをArduinoIDEにインストールし、“WebServerLed”っているのをビルドして動作確認して見ました。
やはり、シリアルポートが認識されませんでしたので、初期化用のUF2ファイルをブートフォルダにインストールして、シリアルドライバが認識されたら、デバイスマネージャを開いて登録されたCOMポートに対し手動でドライバの更新を行いました。これでなんとかビルドしたバイナリオブジェクトを自動で転送できるようになりました。

“WebServerLed”というサンプルはGETを使うようでちょっと戴けないのですが、動いて何よりでした。提供されているExampleを一つ一つ確認し、このボードの振る舞いを感じたいと思います。

このボードを使う上での注意点ですが、WIZNETのライブラリを使いWIFIモジュールを初期化する際に

SoftwareSerial Serial2(6, 7); // RX, TX
WiFi.init(&Serial2);

と云う点ですWizFi360との接続は6番pin(RX)7番pin(TX)のシリアル接続なのですがGPIO番号ではなく物理pin番号での設定のようです。統一性がないですね。
そしてビルドインLEDの接続先ですがGPIO25であることはメーカのサイトに情報がありました。
https://docs.wiznet.io/Product/Open-Source-Hardware/wizfi360-evb-pico

また、このサンプルを実行し、ブラウザからIPアドレスを叩いて表示した頁を見て【here】をクリックするのですが、反応は良くないです。

17:57:55.750 -> [WizFi360] Initialization successful - 1.1.1.7
17:57:55.750 -> Attempting to connect to WPA SSID: Kingsland
17:57:57.174 -> [WizFi360] Connected to Kingsland
17:57:57.174 -> You're connected to the network
17:57:58.190 -> SSID: Kingsland
17:57:58.190 -> IP Address: 192.168.0.142
17:57:58.190 -> 
17:57:58.190 -> To see this page in action, open a browser to http://192.168.0.142
17:57:58.190 -> 
17:57:58.190 -> [WizFi360] Server started on port 80


ソースを読めば判るのですが、

http://192.168.0.142/H

とアクセスすると、ビルトインLEDが緑点灯し、

http://192.168.0.142/L

とアクセスすると消灯します。


2023年2月9日: Stationモードは一般的ですので、APモード(アクセスポイントモード)は動くのか確認しました。
サンプルスケッチはちゃんと用意されており、早速ビルドしてみました。

18:14:04.379 -> [WizFi360] Initialization successful - 1.1.1.7
18:14:04.379 -> Attempting to start AP wiznet
18:14:05.599 -> [WizFi360] Access point started wiznet
18:14:05.599 -> Access point started
18:14:05.599 -> IP Address: 192.168.36.1
18:14:05.599 -> 
18:14:05.599 -> To see this page in action, connect to wiznet and open a browser to http://192.168.36.1
18:14:05.599 -> 
18:14:05.599 -> [WizFi360] Server started on port 80
18:14:05.599 -> Server started

ソースコードに書かれているパスワード【0123456789】を入力したところ、接続出来ました。

IPアドレス(192.168.36.1)にブラウザからアクセスしてみました。大丈夫みたいです。※実際にはAI_0のポートが間違っていて数値は“0”のままでした。

と云う事で、もう少し凝ったHTMLを記述して挙動を確認したいと思います。


2023年2月10日: WizFi360 example: WebServerAP をレタッチしています。レタッチしたいこととして、

とりあえずのスケッチを示しておきます。

/*
 * 2023年2月10日 T.Wanibe
 * WizFi360のサンプルスケッチWebServerAPを最低限のレタッチで動作確認しました。
 * 実際に動かすとアナログ入力の値が0のままですし、余りに寂しいHTMLなのでちょっとレタッチしたいと思っています。
 * 
 *  WizFi360 example: WebServerAP
 *  
 *  アナログ入力の値を表示するシンプルな Web サーバー
 *  WizFi360 モジュールを使用して Web ページ経由でピン留めします。
 *  このスケッチは、アクセス ポイントを開始し、あなたの IP アドレスを出力します。
 *  WizFi360 モジュールをシリアル モニタに接続します。 そこから、開くことができます
 *  そのアドレスを Web ブラウザーに入力して、Web ページを表示します。
 *  Web ページは 20 秒ごとに自動的に更新されます。
 *  
 * 最大1044480バイトのフラッシュメモリのうち、スケッチが62076バイト(5%)を使っています。
 * 最大262144バイトのRAMのうち、グローバル変数が7872バイト(3%)を使っていて、ローカル変数で254272バイト使うことができます。
 */
#include        "arduino_secrets.h"
#include        "WizFi360.h"
// setup according to the device you use
#define         WIZFI360_EVB_PICO
// Emulate Serial1 on pins 6/7 if not present
#ifndef         HAVE_HWSERIAL1
#include        "SoftwareSerial.h"
#if             defined(ARDUINO_MEGA_2560)
                SoftwareSerial Serial1(6, 7); // RX, TX
#elif           defined(WIZFI360_EVB_PICO)
                SoftwareSerial Serial2(6, 7); // RX, TX
#endif
#endif
/* Baudrate */
#define         SERIAL_BAUDRATE         115200
#if             defined(ARDUINO_MEGA_2560)
#define         SERIAL1_BAUDRATE        115200
#elif           defined(WIZFI360_EVB_PICO)
#define         SERIAL2_BAUDRATE        115200
#endif
#define         HTTPPort        80
/* Wi-Fi info */
char    ssid[]          =       SECRET_APSSID;                  // your network SSID (name)
char    pass[]          =       SECRET_APPASS;                  // your network password
int     status          =       WL_IDLE_STATUS;                 // the Wifi radio's status
int     reqCount        =       0;                              // number of requests received
WiFiServer      server(HTTPPort);
RingBuffer      buf(8);                                         // リングバッファを使用して速度を上げ、メモリ割り当てを減らす
//----------------
void sendHttpResponse(WiFiClient client) {
        client.print(
                "HTTP/1.1 200 OK\r\n"
                "Content-Type: text/html\r\n"
                "Connection: close\r\n"                         // the connection will be closed after completion of the response
                "Refresh: 20\r\n"                               // refresh the page automatically every 20 sec
                "\r\n");
        client.print("<!DOCTYPE HTML>\r\n"
                "<html>\r\n"
                "<h1>Hello World!</h1>\r\n"
                "Requests received: ");
        client.print(++reqCount);
        client.print("<br>\r\n"
                "Analog input A0: ");
        client.print(analogRead(0));
        client.print("<br>\r\n"
                "</html>\r\n");
}
//----------------
void printWifiStatus() {
        // print your WiFi shield's IP address
        IPAddress ip = WiFi.localIP();
        Serial.print("IP Address: ");Serial.println(ip);
        // print where to go in the browser
        Serial.println();
        Serial.print("To see this page in action, connect to ");
        Serial.print(ssid);
        Serial.print(" and open a browser to http://");
        Serial.println(ip);
        Serial.println();
}
//----------------
void setup() {
        // initialize serial for debugging
        Serial.begin(SERIAL_BAUDRATE);
        // initialize serial for WizFi360 module
#if defined(ARDUINO_MEGA_2560)
        Serial1.begin(SERIAL1_BAUDRATE);
#elif defined(WIZFI360_EVB_PICO)
        Serial2.begin(SERIAL2_BAUDRATE);
#endif
        // initialize WizFi360 module
#if defined(ARDUINO_MEGA_2560)
        WiFi.init(&Serial1);
#elif defined(WIZFI360_EVB_PICO)
        WiFi.init(&Serial2);
#endif
        // check for the presence of the shield
        if (WiFi.status() == WL_NO_SHIELD) {
                Serial.println("WiFi shield not present");
                while (true); // don't continue
        }
        Serial.print("Attempting to start AP ");Serial.println(ssid);
        // uncomment these two lines if you want to set the IP address of the AP
        //IPAddress localIp(192, 168, 111, 111);
        //WiFi.configAP(localIp);
        // start access point
        status = WiFi.beginAP(ssid, 10, pass, ENC_TYPE_WPA2_PSK);
        Serial.println("Access point started");
        printWifiStatus();
        // start the web server on port 80
        server.begin();
        Serial.println("Server started");
}
//----------------
void loop() {
        WiFiClient client       = server.available();           // listen for incoming clients
        if (client) {                                           // if you get a client,
                Serial.println("New client");                   // print a message out the serial port
                buf.init();                                     // initialize the circular buffer
                while (client.connected()) {                    // loop while the client's connected
                        if (client.available()) {               // if there's bytes to read from the client,
                                char c = client.read();         // read a byte, then
                                buf.push(c);                    // push it to the ring buffer
                                                                // you got two newline characters in a row
                                                                // that's the end of the HTTP request, so send a response
                                if (buf.endsWith("\r\n\r\n")) {
                                        sendHttpResponse(client);
                                        break;
                                }
                        }
                }
                // give the web browser time to receive the data
                delay(10);
                // close the connection
                client.stop();
                Serial.println("Client disconnected");
        }
}

このサンプルスケッチを見て思った点


※2023年2月13日 MQTTのサンプルスケッチがあったので動作確認しました。

比較項目

MQTT

HTTP

同期有無

非同期

同期

送受信の対象

多対多

1対1

通信モデル

パブリッシャー/サブスクライバー型

サーバ/クライアント型

データ量

小さい(軽い)

大きい(重い)

通信が不安定

○(再送受信可能)

×(送受信不可)

MQTT(Message Queuing Telemetry Transport)は、接続が不安定な状態でもTCP/IP通信できるように軽量なプロトコルとして設計された通信規格です。
HTTPと比較されることが多いです。IO制御なんかをHTTPで実現するArduinoサンプルスケッチがあるように見た目使いやすい仕組みなのですが、やりたいことに比較して余りにコストの掛かる仕組みだとのことです。その対策としてIBMがMQTTという仕組みを構築したとのことです。
Brokerと呼ばれるサーバを介した通信となります。ルータのような存在があれば、そこにBrokerを立てれば良いことになります。

上記テスト環境において、サンプルスケッチをArduinoIDEでビルドしシリアル接続したWizFi360-EVV-PICOにバイナリオブジェクトを書き込んだ上で、
WizFi360-EVV-PICOは作業環境内のWIFIに接続します。そのとき取得したIPアドレスがシリアルコンソールに表示されているので、そのIPアドレスに対して、PCのコマンドプロンプトを開き、コマンドを叩くことでMQTTの確認をするというモノです。
手順については、https://wizfi.github.io/Document/docs/basic_guides/mqtt_client に記載があるので とりあえずそれに従って【感じをつかみ取る】ことが必要なのかと思います。

予めPC側にmosquitto(モスキート)ツールをインストールしておく必要があるようです。Brokerソフトと云われるもので、Windows環境では一番ポピュラーのようです。
バイナリデータはhttps://mosquitto.org/files/binary/にあります。
PCにインストール後、PCを再起動して、コンソールを立上げ、パスをmosquittoのインストールパスに変更し、コマンド

mosquitto -c mosquitto.conf -p 1883 -v

を実行すると、mosquittoが動作中となります。“1883”はMQTT用のポート番号です。

あとはBrokerを介して複数のクライアント間でのメッセージ通信を実行することになります。

WizFi360-EVB-PICO側からBrokerにmessageを送るには、port1883に対して接続する必要があります。そのためその環境に於けるBrokerのIPアドレスを調査した上でWizFi360-EVV-PICO側スケッチをレタッチする必要があります。
※Brokerを起動したPCのIPアドレスをスケッチに含めないといけません。スケッチをレタッチ後にビルドし直し、WizFi360-EVB-PICOに書き込んでください。
WizFi360-EVB-PICOもMQTTクライアントですから、Brokerを介してメッセージの遣り取りが出来ます。
動作確認ですが、WizFi360-EVB-PICOを起動した後にシリアルモニタを開くと以下のようなmessageを得ました。brokerに接続出来ませんでした。

15:19:38.514 -> [WizFi360] Connected to Kingsland
15:19:38.514 -> You're connected to the network
15:19:38.514 -> SSID: Kingsland
15:19:38.514 -> IP Address: 192.168.0.142
15:19:38.546 -> Signal strength (RSSI):-60 dBm
15:19:38.546 ->
15:19:38.546 -> Starting connection to broker...
15:19:38.546 -> [WizFi360] Connecting to 192.168.0.107
15:19:38.546 -> Can't Connected to broker

理由を検討しているのですが判りません。

if (client.connect("arduino", "public", "public")){

で失敗していることが明らかなのですが、サンプルスケッチに何もコメントがなく、パラメータをどう設定するのが正解なのか?
mosquitto.exe側の情報/設定が必要な気もしているのですが、現時点では検討がつかないです。記録としてスケッチを残します。

/*
 * 2023年2月13日 T.Wanibe
 *  WizFi360 example: MqttClient
 *  このスケッチは、WizFi360 モジュールを使用してブローカーに接続し、単純なパブリッシュとサブスクライブを実行します。
 *  MQTTは、TCP / IPプロトコルの上で使用するための軽量メッセージングプロトコルです。“小さなコードフットプリント”
 *  が必要であるか、ネットワーク帯域幅が限られているリモートの場所との接続用に設計されています。
 *  これは、ほとんどすべてのネットワークオブジェクトを 外部、それはセンサーとして使用されます。
 *  
 */
#include        "Arduino_secrets.h"
#include        "WizFi360.h"
#include        "WizFi360Mqtt.h"
// setup according to the device you use
#define         WIZFI360_EVB_PICO
// Emulate Serial1 on pins 6/7 if not present
#ifndef         HAVE_HWSERIAL1
#include        "SoftwareSerial.h"
#if             defined(ARDUINO_MEGA_2560)
                SoftwareSerial Serial1(6, 7);   // RX, TX
#elif           defined(WIZFI360_EVB_PICO)
                SoftwareSerial Serial2(6, 7);   // RX, TX
#endif
#endif
/* Baudrate */
#define         SERIAL_BAUDRATE         115200
#if             defined(ARDUINO_MEGA_2560)
#define         SERIAL1_BAUDRATE        115200
#elif           defined(WIZFI360_EVB_PICO)
#define         SERIAL2_BAUDRATE        115200
#endif
/* Wi-Fi info */
char    ssid[]  = SECRET_SSID;                  // your network SSID (name)
char    pass[]  = SECRET_PASS;                  // your network password
int     status  = WL_IDLE_STATUS;               // the Wifi radio's status
//注: ローカル ドメイン名 (OSX の "Computer.local" など) は、Arduino ではサポートされていません。
//IP アドレスを直接設定する必要があります。
char    broker[] = SECRET_BROKERIP;
unsigned long lastMillis = 0;
// イーサネット クライアント オブジェクトを初期化する
WiFiClient      net;
MQTTClient      client;
//----------------
void printWifiStatus() {
        // print the SSID of the network you're attached to
        Serial.print("SSID: ");
        Serial.println(WiFi.SSID());
        // print your WiFi shield's IP address
        IPAddress ip = WiFi.localIP();
        Serial.print("IP Address: ");
        Serial.println(ip);
        // print the received signal strength
        long rssi = WiFi.RSSI();
        Serial.print("Signal strength (RSSI):");
        Serial.print(rssi);
        Serial.println(" dBm");
}
//----------------
void messageReceived(String &topic, String &payload) {
        Serial.println(topic + " - " + payload.length() + "," + payload);
        //注: コールバックでクライアントを使用してパブリッシュ、サブスクライブ、またはサブスクライブ解除しないでください。
        //確認の送受信中に他のものが到着したときにデッドロックが発生する可能性があるためです。
        //代わりに、グローバル変数を変更するか、キューにプッシュして `client.loop()` を呼び出した後にループ内で処理します。
}
//----------------
void setup() {
        // initialize serial for debugging
        Serial.begin(SERIAL_BAUDRATE);
        if(!Serial){delay(1000);}
        // initialize serial for WizFi360 module
#if defined(ARDUINO_MEGA_2560)
        Serial1.begin(SERIAL1_BAUDRATE);
#elif defined(WIZFI360_EVB_PICO)
        Serial2.begin(SERIAL2_BAUDRATE);
#endif
        // initialize WizFi360 module
#if defined(ARDUINO_MEGA_2560)
        WiFi.init(&Serial1);
#elif defined(WIZFI360_EVB_PICO)
        WiFi.init(&Serial2);
#endif
        // check for the presence of the shield
        if (WiFi.status() == WL_NO_SHIELD) {
                Serial.println("WiFi shield not present");
                // don't continue
                while (true);
        }
        // attempt to connect to WiFi network
        while ( status != WL_CONNECTED) {
                Serial.print("Attempting to connect to WPA SSID: ");
                Serial.println(ssid);
                // Connect to WPA/WPA2 network
                status = WiFi.begin(ssid, pass);
        }
        // you're connected now, so print out the data
        Serial.println("You're connected to the network");
        printWifiStatus();
        Serial.println();
        Serial.println("Starting connection to broker...");
        client.begin(broker, net);                                      //void begin(const char _hostname[], Client &_client)
        //if (client.connect("arduino", "sub_client", "pub_client")){             //bool connect(const char clientID[], const char username[], const char password[], bool skip = false);
        if (client.connect("roger","sub_client","pub_client")){
                Serial.println("Connected to broker");
                client.subscribe("/world");
                client.onMessage(messageReceived);
        }else{
                Serial.println("Can't Connected to broker");
        }
}
//----------------
void loop() {
        client.loop();
        // publish a message roughly every second.
        if (millis() - lastMillis > (1000 * 10)){                       // 10 seconds
                lastMillis = millis();
                client.publish("/hello", "world");
        }
}

WizFi360とRP2040はソフトウエアシリアル接続のようです。ボーレート115200bpsでは十分な通信帯域を確保出来ないようで、Werserverで大きなデータを扱おうとするとフリーズしてしまいます。ちょっと使い物にならないです。

UDPでNTPによる時刻取得をする場合も、タイマ待ちはうまくゆかないです。有線なら1000msec待てば十分だったのに、WiFiでは応答が返るまでチェックしないとなかなかうまくゆきません。


Modbusを移植してみようと思いましたが、これはそれなりに大変ですね。


戯言(nonsense)に戻る


問い合わせ頁の表示


免責事項

本ソフトウエアは、あなたに対して何も保証しません。本ソフトウエアの関係者(他の利用者も含む)は、あなたに対して一切責任を負いません。
あなたが、本ソフトウエアを利用(コンパイル後の再利用など全てを含む)する場合は、自己責任で行う必要があります。

本ソフトウエアの著作権はToolsBoxに帰属します。
本ソフトウエアをご利用の結果生じた損害について、ToolsBoxは一切責任を負いません。
ToolsBoxはコンテンツとして提供する全ての文章、画像等について、内容の合法性・正確性・安全性等、において最善の注意をし、作成していますが、保証するものではありません。
ToolsBoxはリンクをしている外部サイトについては、何ら保証しません。
ToolsBoxは事前の予告無く、本ソフトウエアの開発・提供を中止する可能性があります。

商標・登録商標

Microsoft、Windows、WindowsNTは米国Microsoft Corporationの米国およびその他の国における登録商標です。
Windows Vista、Windows XPは、米国Microsoft Corporation.の商品名称です。
LabVIEW、National Instruments、NI、ni.comはNational Instrumentsの登録商標です。
I2Cは、NXP Semiconductors社の登録商標です。
その他の企業名ならびに製品名は、それぞれの会社の商標もしくは登録商標です。
すべての商標および登録商標は、それぞれの所有者に帰属します。