10.T-Watch S3 Plus でGPSテスト


10.T-Watch S3 Plus でGPSテスト

GPSの初テストです。
LilyGoLib/examples/peripheral/GPSFullExample/GPSFullExample.ino
を元に変更しました。GPSは T-Watch S3 Plus と T-Watch Ultra に搭載で、T-Watch S3 は未搭載です。
lv_conf.hでデフォルトfontとして中日韓16pxのlv_font_simsun_16_cjk を設定します。

GNSS(衛星測位システム)チップ

T-Watch S3 Plus は、
https://github.com/Xinyuan-LilyGO/LilyGoLib/blob/master/docs/hardware/lilygo-t-watch-s3-plus.md
で、GNSS:u-blox製 MIA-M10Q か Quectel製 LS550G を使用しています。

T-Watch Ultra は、
https://github.com/Xinyuan-LilyGO/LilyGoLib/blob/master/docs/hardware/lilygo-t-watch-ultra.md
で、GNSS:u-blox製 MIA-M10Q を使用しています。

MIA-M10Qのチップは、
https://www.u-blox.com/en/product/mia-m10-series
で、対応衛星は、GPS, GLONASS, Galileo, BeiDou, QZSS です。

LS550Gのチップは、
https://www.quectel.com/product/gnss-ls550g-00/
で、対応衛星は、GPS, GLONASS, Galileo, BDS, QZSS です。

GNSSの一覧

・GPS (GP): アメリカ
・GLONASS (GL): ロシア
・Galileo (GA): 欧州連合
・BeiDou (GB): 中国 北斗
・QZSS (GQ): Ver4.11以上 準天頂衛星システム
みちびき:GPSを補完し、日本で高精度な位置情報を得ます
・(GN): 上記の組合せ

NMEAフォーマット

GPSデータのNMEAフォーマットは、
https://skyrail.tech/archives/433
が参考になります。

日本の緯度・経度

緯度は、南へは小さく、北へは大きくなります。日本の北緯35度の地点(千葉県房総半島館山市等)で 1km あたりの緯度の変化は、約0.009度です。

経度は西へは小さく、東へは大きくなります。日本で 1km あたりの経度の変化は、約0.011度です。
https://easyramble.com/latitude-and-longitude-per-kilometer.html

・北海道 宗谷岬: 北緯45.5,東経141.9
・東京駅: 北緯35.7,東経139.8
・那覇空港: 北緯26.2,東経127.6

TinyGPSPlus

LilyGoLib/src/GPS.h では TinyGPSPlus.h を include しています。

TinyGPSPlus
https://github.com/mikalhart/TinyGPSPlus

解説は
https://arduiniana.org/libraries/tinygpsplus/
に出ています。

動作

天井が開けているマンションのベランダで立ち止まって測定しました。起動後、約1分でサテライト数を表示し、約2分後には緯度・経度を表示しました。
1行目: "前回更新から"で、起動時の9999秒は未更新の値です。
2行目: "サテライト数"は、捕捉できている衛星数です。
3行目: "水平精度"は小さいほど良いです。
 衛星が空の広範囲にばらばらと幾何学的配置になっています。
 逆に大きいと、一か所に偏って固まっていて精度が悪いです。
 数値をA~Dに分けました。
 (A): 2未満。優
 (B): 5未満。良
 (C): 10未満。誤差が大きくなる可能性あり
 (D): 10以上。位置が大きくずれている可能性あり
4行目: 日付はUTC時刻(協定世界時)です。日本標準時(JST)は+9Hします。UTC+0はイギリス等です。
5行目: "緯度"は漢字がないため"イ度"としました。
6・7行目: "高度"・"速度"は時々大きくずれてます。

main.cpp


// LilyGoLib/examples/peripheral/GPSFullExample/GPSFullExample.ino より変更
// hdopは、水平精度の係数で、
// 小:良、衛星が空の広範囲にばらばらと幾何学的配置
// 大:悪、一か所に偏って固まっている
// lv_conf.hでデフォルトfont:中日韓16pxのlv_font_simsun_16_cjk を使用
// T-Watch S3 はGPS未搭載
#include <LilyGoLib.h>     // LilyGoLib 0.2.0
#include <LV_Helper.h>     // lvgl by kisvegabor 9.5.0
#define SerialGPS Serial1  //
lv_obj_t *label;           // ラベルを使用

static void smartDelay(unsigned long ms) {  // gpsオブジェクトにデータが確実に供給されるようにします
  unsigned long start = millis();           // 開始時間
  do {
    while (SerialGPS.available()) {  // GPSから送信され、受信しているデータの文字(バイト)数
      int r = SerialGPS.read();      // GPSSerialからのメッセージを読み込む
      instance.gps.encode(r);        // GPSのNMEAフォーマットの文字列をArduinoで読取れるように変換
      //Serial.write(r);
    }
  } while (millis() - start < ms);  // 指定時間が経過するまで
}

void setup() {
  Serial.begin(115200);       // シリアルモニタの通信速度
  instance.begin();           // LilyGoLibを初期化
  beginLvglHelper(instance);  // LVGLを初期化

  label = lv_label_create(lv_scr_act());           // 現在の画面にラベルを作成
  lv_obj_set_style_transform_zoom(label, 320, 0);  // ズーム(=/256)倍 384(1.5) 320(1.25)
  instance.setBrightness(255);                     // T-Watch-S3、S3-Plus、Ultra の輝度は0~255 MAXに設定
}

void loop() {
  uint32_t satellites = instance.gps.satellites.isValid() ? instance.gps.satellites.value() : 0;  // 衛星数 u32

  double hdop = instance.gps.hdop.isValid() ? instance.gps.hdop.hdop() : 9999;  // 水平精度係数 i32

  String Mhdop = "D";  // 10以上 位置が大きくずれている可能性が高い
    if (hdop < 2.0) {
    Mhdop = "A";  // 1-2 非常に優れている。精密測位に向いています
  } else if (hdop < 5.0) {
    Mhdop = "B";  // 2-5 良好。通常のナビで十分使えます
  } else if (hdop < 10.0) {
    Mhdop = "C";  // 5-10 低下。誤差が大きくなる可能性があります
  }

  double lat = instance.gps.location.isValid() ? instance.gps.location.lat() : 0; // 緯度(度) 倍精度小数点 8バイト 15桁
  // (C++の文法 条件式 ? 真の場合の値 : 偽の場合の値)
  double lng = instance.gps.location.isValid() ? instance.gps.location.lng() : 0;          // 経度(度) 倍精度
  uint32_t age = instance.gps.location.isValid() ? instance.gps.location.age() : 9999000;  // 前回からの経過時間(mS)
  age = (int)(age / 1000.0 + 0.5);                                                         // (s)
  uint16_t year = instance.gps.date.isValid() ? instance.gps.date.year() : 0;              // 年(2000+) u16
  uint8_t month = instance.gps.date.isValid() ? instance.gps.date.month() : 0;             // 月(1-12) u8
  uint8_t day = instance.gps.date.isValid() ? instance.gps.date.day() : 0;                 // 日(1-31) u8
  uint8_t hour = instance.gps.time.isValid() ? instance.gps.time.hour() : 0;               // 時(0-23) u8
  uint8_t minute = instance.gps.time.isValid() ? instance.gps.time.minute() : 0;           // 分(0-59) u8
  uint8_t second = instance.gps.time.isValid() ? instance.gps.time.second() : 0;           // 秒(0-59) u8
  double meters = instance.gps.altitude.isValid() ? instance.gps.altitude.meters() : 0;    // 高度(m) 倍精度
  double kmph = instance.gps.speed.isValid() ? instance.gps.speed.kmph() : 0;              // 速度(km/h) 倍精度
  lv_label_set_text_fmt(label, "前回更新から : %uS\nサテライト数 : %u個\n水平精度 : %.1f(%s)\n%d/%02d/%02d %02d:%02d:%02d +9H\nイ度 : %09.5f度\n経度 : %09.5f度\n高度 : %04.0fm\n速度 : %06.2fkm/h\n受信 : %u文字",
                        age, satellites, hdop, Mhdop, year, month, day, hour, minute, second, lat, lng, meters, kmph, instance.gps.charsProcessed());

  lv_obj_align(label, LV_ALIGN_TOP_LEFT, 5, 10);  // ラベルの位置
  smartDelay(1000);                               // 指定時間を待ちながら、受信を実行する関数へ
  lv_task_handler();                              // 画面の再描画・イベント等のメインループ処理
}

スケッチの状態

Processing twatchs3 (board: lilygo-t-watch-s3; framework: arduino; platform: https://github.com/pioarduino/platform-espressif32/releases/download/55.03.36-1/platform-espressif32.zip)
PLATFORM: Espressif 32 (55.3.36) > LilyGo T-Watch S3 (16M Flash 8M OPI PSRAM )
- contrib-piohome @ 3.4.4
- framework-arduinoespressif32 @ 3.3.6
- framework-arduinoespressif32-libs @ 5.5.0+sha.f56bea3d1f
- tool-esp-rom-elfs @ 2024.10.11
- tool-esptoolpy @ 5.1.0
- toolchain-xtensa-esp-elf @ 14.2.0+20251107
|-- LilyGoLib @ 0.2.1+sha.9301b6d
|-- lvgl @ 9.5.0
|-- RadioLib @ 7.4.0
|-- XPowersLib @ 0.3.1
|-- SensorLib @ 0.3.3
|-- TinyGPSPlus @ 1.0.3
|-- ESP32 BLE Keyboard Fork @ 0.3.4+sha.20c8b9f
|-- ESP32 BLE Mouse @ 0.3.1+sha.61bcd32
|-- ESP8266Audio @ 2.0.0
|-- NimBLE-Arduino @ 2.2.3
|-- IRremoteESP8266 @ 2.8.6
RAM: [= ] 7.8% (used 25396 bytes from 327680 bytes)
Flash: [== ] 23.6% (used 991767 bytes from 4194304 bytes)
Chip type: ESP32-S3 (QFN56) (revision v0.2)
Features: Wi-Fi, BT 5 (LE), Dual Core + LP Core, 240MHz, Embedded PSRAM 8MB (AP_3v3)
Crystal frequency: 40MHz
USB mode: USB-Serial/JTAG
Changing baud rate to 921600...