chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

Platform IO環境を使ってWio Terminal用のHello Worldを作ってみる

目的:Platform IOを理解する。最終的にWioTerminalで動くIoTサンプルコードを開発する
取り組み:PlatformIOを使ってWioTerminal用のサンプルコードを書いて動かしてみる
結果:ビルド段階でエラーになったりいろいろあったけど、最終的にはWiFi接続して特定ホストにPINGを打つまでは実現できた

詳細:
普段はMicroPythonを使っていてArduinoの開発環境は基本使っていないけど、Arduinoの開発環境がどうなっているのか調べる必要が出てきた。ちょっと調べるとPlatform IOが良いと書かれていた。手を動かさないと実感わかないので、Platform IO(以降PIO)を使ってWio Terminal用にシンプルなHello Worldを作ってみる。シンプルと言っても、LCDに文字を表示させるのでドライバ等いろいろ必要なのだが、Arduino(PIO)にはライブラリがそろっているので、ライブラリを使うことでサクッと動くようだ。
もんごんた氏の記事を参考にする。ポイントとしては、LCDに文字や画像を表示するためにコントローラに合ったドライバ(LovyanGFX)を使う。PIOにドライバをインストールして、以下のコードを書くことでHelloWorldと表示されるらしい。

#include <Arduino.h>
#include <LovyanGFX.hpp>

static LGFX lcd;

void setup() {
  lcd.init();
  lcd.println("HelloWorld");
}
void loop() {
}

上記ソースで動かすとエラーが出たり、表示されなかったり多少問題があって、Gitのサンプルを参考に以下とした(defineが必須かどうか未確認)

#include <Arduino.h>


#define LGFX_WIO_TERMINAL
#define LGFX_AUTODETECT
#define LGFX_USE_V1

#include <LovyanGFX.hpp>
#include <LGFX_AUTODETECT.hpp> 
static LGFX lcd;

void setup() {
   uint32_t red = 0xFF0000;
  // put your setup code here, to run once:
  lcd.init();
  lcd.setRotation(1);
  lcd.setBrightness(128);
  lcd.setColorDepth(16); 
  lcd.println("HelloWorld");
  lcd.drawLine( 0, 0, 320, 240 , red); 
  lcd.drawString("Center!?", 320/2, 240/2);
}

void loop() {
  // put your main code here, to run repeatedly:
}

WioTerminalの表示は以下

Platform IOをPCにインストールして、サンプルが動くまで1時間ぐらい。途中大きなトラブルもなく動いた。さすがに作りこまれた環境はすばらしい。

続いて、WiFi接続をやってみる。Seeed Arduino rpcWiFiというライブラリがありそれをロードしてビルドするが、Seeed_FS.hが無いと怒られる。Seeed_FS.hはFileSystem用のヘッダのようで、これも追加ライブラリと想像*1。これも探して入れてみる。

.pio\libdeps\seeed_wio_terminal\Seeed Arduino rpcWiFi\src\WebServer.cpp:30:10: fatal error: Seeed_FS.h: No such file or directory

******************************************************************
* Looking for Seeed_FS.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:Seeed_FS.h"
* Web  > https://registry.platformio.org/search?q=header:Seeed_FS.h
*
******************************************************************

次は、以下のように、Seeed_mbedtls.hが無いと怒られた

.pio\libdeps\seeed_wio_terminal\Seeed Arduino rpcWiFi\src\WebServer.cpp:31:10: fatal error: Seeed_mbedtls.h: No such file or directory

ライブラリ間の依存関係は扱ってくれないのだろうか。。SeeedのWIkiを見ると必要なライブラリ一式が記載されていた。

依存関係にあるモジュールを追加することでビルドは通るようになった。が、サンプルコードを実行するとハングする。
サンプル通りのシンプルな初期化なのだが、どうもWiFiユニット(RTL8720)の初期化でハングするようだ。RTL8720用のドライバを更新する必要があるのかもしれない。

    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
       lcd.drawString("wifi connect loop", 10, y);
        Serial.print("Connecting to ");
        Serial.println(ssid);
        WiFi.begin(ssid, password);
    }

面倒だと読み飛ばしていたが、改めて読み直すと、RTL8720のドライバ更新が必須のようであった。RT8720のドライバ更新手順に従って、Wio内のドライバを更新した。WiFiのサンプルコードも動くようになった。今日作ったサンプルコードは以下(WiFi接続まではできた。今後はMQTT通信をさせるのだが、ここまでできたらあとは汎用モジュールで繋がるのを期待)

#include <Arduino.h>

#define LGFX_WIO_TERMINAL
#define LGFX_AUTODETECT
#define LGFX_USE_V1

#include <LovyanGFX.hpp>
#include <LGFX_AUTODETECT.hpp> 
static LGFX lcd;

#include <rpcWiFi.h>
#include <rpcPing.h>

#define RED (uint32_t)0xFF0000
#define SERIAL_SPEED 115200

const char *SSID = "xxxxxxxxxxx";
const char *PWD = "xxxxx";
const char *HOST = "xxxxxxxx.co.jp";
const char *url = "/index.html";

void setup() {
  // put your setup code here, to run once:
  
  int y = 10;
  lcd.init();
  lcd.setRotation(1);
  lcd.setBrightness(128);
  lcd.setColorDepth(16); 
  lcd.println("HelloWorld");
  lcd.drawLine( 0, 0, 320, 240 , RED); 
  lcd.drawString("Test(v1.1)", 10, y);
  y += 10;
  //Serial.println("can you see this??");

  Serial.begin(SERIAL_SPEED);
  delay(10);

  // We start by connecting to a WiFi network

   Serial.println();
   Serial.println();
   Serial.print("Connecting to ");
   Serial.println(SSID);

    lcd.drawString("wifi set mode", 10, y); y += 10;
    WiFi.mode(WIFI_STA);
    lcd.drawString("wifi disconnn", 10, y); y += 10;
    WiFi.disconnect();
    lcd.drawString("wifi begin", 10, y);
    y += 10;
    WiFi.begin(SSID, PWD);
    lcd.drawString("wifi startedd", 10, y);
    y += 10;

    while (WiFi.status() != WL_CONNECTED)
    {
       lcd.drawString("wifi connect loop", 10, y);
       y += 10;

        Serial.print("Connecting to ");
        Serial.println(SSID);
        WiFi.begin(SSID, PWD);
    }

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    lcd.drawString("wifi connected", 10, y);
    y += 10;

}

void loop() {
  // put your main code here, to run repeatedly:

  static int try_count = 0;
  char str[20];
  try_count ++;

  Serial.println(".");
  lcd.drawString("enter loop", 10, 100);
  sprintf(str, "count: %d", try_count);
  lcd.drawString(str, 50, 100);

  if(try_count >= 10){
     Serial.print("skip Pinging");
  }else{
     Serial.print("Pinging host ");
     Serial.println(HOST);
     bool ret = Ping.ping(HOST);
     if(ret) {
        Serial.println("Success!!");
        Serial.println("TIME: ");
     } else {
        Serial.println("Error :(");
     }
  }
  delay(5000);
}

■まとめ
これまで組み込みシステムの開発はESP32 DevKit + MicroPythonを使っていた。ESP32のAll In Oneな所が、使い手があってそれはそれで良かったのだけど、WioTerminalを使ってみて、絵や文字が出せるのはなかなか楽しいと思った。グラフィカルに表示できたらいろいろやってみたい気になるので、WioTerminalは楽しいデバイスだと思いました。しかもバッテリ拡張ユニットもあるし。
■参考URL
もんごた氏
初心者向けWioTerminalの始め方【VisualStudioCode+PlatformIO編】 | M5Stack沼人の日記
GitHub - lovyan03/LovyanGFX: SPI LCD graphics library for ESP32 (ESP-IDF/ArduinoESP32) / ESP8266 (ArduinoESP8266) / SAMD51(Seeed ArduinoSAMD51)
Wio TerminalをWi-Fiに繋ぐ - Qiita
Overview - Seeed Wiki
MQTT on Wio Terminal - Hackster.io
https://wiki.seeedstudio.com/Wio-Terminal-Network-Overview/

*1:ライブラリ名は、Seeed Arduino FS by Hongtai.liu のようである