🖥️

W6300-EVB-PICO2にArduinoVNCを移植する話

に公開

はじめに

公開されているRaspberry pi pico w用のArduinoVNCを修正して、Raspberry pi 4上のTightVNCサーバーへの接続に成功しました。

https://zenn.dev/kazueda/articles/1eba964004530f

また、W6300-EVB-PICO2をインターネットに接続するArduinoスケッチの修正に成功しました。

https://zenn.dev/kazueda/articles/2c07552f1605c8

これらの成果をまとめて、W6300-EVB-PICO2上のArduinoVNCで、Raspberry pi 4上のTigerVNCサーバーへの接続に成功しました。
複数のcppファイルやヘッダファイルを扱いやすいGemini-cliを併用し、Gemini-cliで修正できない部分をCopilotで修正しました。

修正したArduinoVNC-pico.inoのW6300-EVB-PICO2への移植

移植の際、以下の作業を行いました。

  • Wi‑Fiから有線Ethernetへの変更
  • Touchスクリーンの無効化
  • I2Cキーボード接続の無効化
    まずは、W6300のQSPI接続とLCDのSPI接続を成功することを目指しました。

1) 通信スタックの切替(Wi‑Fi → W6300有線Ethernet)

  • Wi‑Fi系の #include <WiFi.h> と接続処理WiFi.mode(WIFI_STA)WiFi.begin(...)WiFi.status() 等)を削除
  • W6300ライブラリを導入:
    #include <W6300lwIP.h>
    #define W6300_CS_PIN  16
    #define W6300_RST_PIN 22
    Wiznet6300lwIP eth(W6300_CS_PIN);
    
    eth.begin()eth.connected() でDHCP接続を待つロジックへ置換。
  • RSTピン制御を追加:LOW→100ms→HIGH→100ms十分なリセットパルス後に eth.begin() を実行(安定化のため)。

2) 画面(Arduino_GFX)の固定設定化(SPI1を明示)

  • 元のスケッチは create_default_Arduino_DataBus() でボードに応じた自動設定を行っていましたが、W6300‑EVB‑Pico系はSPI0がW6300で使われるため、LCDはSPI1を使うよう固定ピンで明示:
    #define LCD_SCLK 10
    #define LCD_MOSI 11
    #define LCD_MISO 12
    #define LCD_CS   13
    #define LCD_DC   8
    #define LCD_RST  9
    Arduino_DataBus *bus = new Arduino_RPiPicoSPI(LCD_DC, LCD_CS, LCD_SCLK, LCD_MOSI, LCD_MISO, spi1);
    Arduino_GFX *gfx = new Arduino_ILI9341(bus, LCD_RST, 3 /* rotation */, false /* IPS */);
    
    ※ SPI1の有効ピン(SCK=10、MOSI=11、MISO=12、CS=9/13など)に合わせて安全に固定。

3) タッチ/キーボード機能の一時無効化

  • #include "touch.h"#include "keyboard.h" をコメントアウトし、
    touch_init(...)keyboard_init()handle_touch()handle_keyboard() の呼び出しをコメントアウト。
  • W6300の固定ピン(GPIO16〜21、22、15)はW6300専用のため、他機能で使うと衝突します。暫定的に無効化してから、後段で安全なピンに振り直して再有効化する方針にしています。

4) ステータス画面メッセージの整備

  • TFTnoWifi()TFTnoEthernet() に刷新(有線前提のメッセージ)。
  • 接続完了時には、eth.localIP() を表示。

動作しました

ルーターを経由して、W6300-EVB-PICOとRaspberry pi 4を接続しています。

おわりに

現時点では、タッチパッドとI2Cキーボード接続が無効になっています。
これらの機能を有効化に成功したら、報告いたします。
また、設定をスケッチに記入しなくてはいけない設定なので、DNSからIPアドレスを発行してもらい、VNCのサーバー名を指定して接続できる機能を追加します。
さらに、Thinclientとしての可能性を探っていきたいと思います。
折りたたんだらキーボードサイズのThinClientが出来たら素敵ですね。

おまけ

パッチファイルを公開します。
注意点は、修正したArduinoVNC-pico.inoへのパッチだという点です。
また、個人の設定部分は上手くパッチできないかもしれません。
参考にしてください。

--- ArduinoVNC-pico.ino	2025-12-13 12:00:00
+++ ArduinoVNC-pico.ino	2025-12-13 12:40:00
@@
-/* WiFi settings */
-const char *SSID_NAME = "Your Access Point";
-const char *SSID_PASSWORD = "Your Access ";
-const char *VNC_IP = "VNCServerIP";
-const uint16_t VNC_PORT = 5901;
-const char *VNC_PASSWORD = "your VNCServer password";
+/* VNC server settings (Ethernet) */
+const char *VNC_IP = "YourVNCServerIP";
+const uint16_t VNC_PORT = 5901;
+const char *VNC_PASSWORD = "your VNCServer password";
@@
-#include "touch.h"
+#if 0  // Touch disabled for Ethernet bring-up
+// #include "touch.h"
+#endif
@@
-#include "keyboard.h"
+#if 0  // Keyboard disabled for Ethernet bring-up
+// #include "keyboard.h"
+#endif
@@
-#include <Arduino_GFX_Library.h>
-#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
-#if defined(DISPLAY_DEV_KIT)
-Arduino_GFX *gfx = create_default_Arduino_GFX();
-#else /* !defined(DISPLAY_DEV_KIT) */
-Arduino_DataBus *bus = create_default_Arduino_DataBus();
-Arduino_GFX *gfx = new Arduino_ILI9341(bus, DF_GFX_RST, 3 /* rotation */, false /* IPS */);
-#endif /* !defined(DISPLAY_DEV_KIT) */
+#include <Arduino_GFX_Library.h>
+#define GFX_BL DF_GFX_BL
+// Use SPI1 for LCD (SPI0 is reserved for W6300 QSPI)
+#define LCD_SCLK 10
+#define LCD_MOSI 11
+#define LCD_MISO 12
+#define LCD_CS   13
+#define LCD_DC   8
+#define LCD_RST  9
+Arduino_DataBus *bus = new Arduino_RPiPicoSPI(LCD_DC, LCD_CS, LCD_SCLK, LCD_MOSI, LCD_MISO, spi1);
+Arduino_GFX     *gfx = new Arduino_ILI9341(bus, LCD_RST, 3 /* rotation */, false /* IPS */);
@@
-#if defined(ESP32)
-#include <WiFi.h>
-#elif defined(ESP8266)
-#include <ESP8266WiFi.h>
-#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
-#include <WiFi.h>
-#elif defined(RTL8722DM)
-#include <WiFi.h>
-#endif
+#include <W6300lwIP.h>
+#define W6300_CS_PIN  16
+#define W6300_RST_PIN 22
+Wiznet6300lwIP eth(W6300_CS_PIN);
@@
 VNC_GFX *vnc_gfx = new VNC_GFX(gfx);
 arduinoVNC vnc = arduinoVNC(vnc_gfx);
-void TFTnoWifi(void)
+void TFTnoEthernet(void)
 {
   gfx->fillScreen(RGB565_BLACK);
   gfx->setCursor(0, ((gfx->height() / 2) - (5 * 8)));
   gfx->setTextColor(RGB565_RED);
   gfx->setTextSize(5);
-  gfx->println("NO WIFI!");
+  gfx->println("NO ETHERNET!");
   gfx->setTextSize(2);
   gfx->println();
 }
@@
-void handle_touch()
-{
-  if (touch_has_signal())
-  {
-    if (touch_touched())
-    {
-      vnc.mouseEvent(touch_last_x, touch_last_y, 0b001);
-    }
-    else if (touch_released())
-    {
-      vnc.mouseEvent(touch_last_x, touch_last_y, 0b000);
-    }
-  }
-}
+// Touch disabled
+// void handle_touch() { /* omitted */ }
@@
-void handle_keyboard()
-{
-  int key = keyboard_get_key();
-  if (key > 0)
-  {
-    switch (key)
-    {
-      case 8:  key = 0xff08; break; // BackSpace
-      case 9:  key = 0xff09; break; // Tab
-      case 13: key = 0xff0d; break; // Enter
-      case 27: key = 0xff1b; break; // Escape
-      case 180: key = 0xff51; break; // Left
-      case 181: key = 0xff52; break; // Up
-      case 182: key = 0xff54; break; // Down
-      case 183: key = 0xff53; break; // Right
-    }
-    vnc.keyEvent(key, 0b001);
-    vnc.keyEvent(key, 0b000);
-  }
-}
+// Keyboard disabled
+// void handle_keyboard() { /* omitted */ }
@@
-Serial.println("Arduino_GFX VNC example");
-// Init keyboard device
-keyboard_init();
+Serial.println("Arduino_GFX VNC example (Ethernet)");
+// Keyboard disabled
+// keyboard_init();
@@
-// Init touch device
-touch_init(gfx->width(), gfx->height(), gfx->getRotation());
-TFTnoWifi();
-Serial.println("Init WiFi");
-gfx->println("Init WiFi");
-#if defined(ESP32)
-  WiFi.mode(WIFI_STA);
-  WiFi.begin(SSID_NAME, SSID_PASSWORD);
-#elif defined(ESP8266)
-  WiFi.setSleepMode(WIFI_NONE_SLEEP);
-  WiFi.mode(WIFI_STA);
-  WiFi.begin(SSID_NAME, SSID_PASSWORD);
-#elif defined(ARDUINO_RASPBERRY_PI_PICO_W)
-  WiFi.mode(WIFI_STA);
-  WiFi.begin(SSID_NAME, SSID_PASSWORD);
-#elif defined(RTL8722DM)
-  WiFi.begin((char *)SSID_NAME, (char *)SSID_PASSWORD);
-#endif
-while (WiFi.status() != WL_CONNECTED)
-{
-  delay(500);
-  Serial.print(".");
-  gfx->print(".");
-}
-Serial.println(" CONNECTED");
-gfx->println(" CONNECTED");
-Serial.println("IP address: ");
-gfx->println("IP address: ");
-Serial.println(WiFi.localIP());
-gfx->println(WiFi.localIP());
+// Touch disabled
+// touch_init(gfx->width(), gfx->height(), gfx->getRotation());
+TFTnoEthernet();
+Serial.println("Initializing Ethernet with W6300...");
+gfx->println("Init Ethernet");
+// W6300 manual reset (extended for stability)
+pinMode(W6300_RST_PIN, OUTPUT);
+digitalWrite(W6300_RST_PIN, LOW);  delay(100);
+digitalWrite(W6300_RST_PIN, HIGH); delay(100);
+Serial.println("Calling eth.begin()...");
+if (!eth.begin()) {
+  Serial.println("!!! FAILED to initialize Ethernet hardware.");
+  while (1) { delay(1000); }
+}
+Serial.println("eth.begin() successful. Waiting for connection...");
+int connect_wait_count = 0;
+while (!eth.connected()) {
+  connect_wait_count++;
+  Serial.print(".");
+  if ((connect_wait_count % 80) == 0) { Serial.println(); }
+  gfx->print(".");
+  delay(500);
+}
+Serial.println(" CONNECTED");
+gfx->println(" CONNECTED");
+Serial.println("IP address: ");
+gfx->println("IP address: ");
+Serial.println(eth.localIP());
+gfx->println(eth.localIP());
@@
- if (WiFi.status() != WL_CONNECTED)
+ if (!eth.connected())
  {
-   vnc.reconnect();
-   TFTnoWifi();
-   delay(100);
+   vnc.reconnect();     // request reconnect on next loop
+   TFTnoEthernet();
+   delay(1000);
  }
  else
  {
    if (vnc.connected())
    {
-     handle_touch();
-     handle_keyboard();
+     // Touch/Keyboard disabled
+     // handle_touch();
+     // handle_keyboard();
    }
    vnc.loop();
    if (!vnc.connected())
    {
      TFTnoVNC();
      delay(5000);
    }
  }

Discussion