[Spresense] GNSS 衛星から情報取得して経度・緯度・高度と日時を表示するスケッチ
前書き

Spresense で GNSS 衛星から情報を取得して、経度・緯度・高度を表示するスケッチを作って動作確認ができた。
Spresense メインボードには GNSS アンテナが標準搭載されている。GNSS Add-on ボードと呼ばれるボードもあるが、僕はこれは使わないつもりでいる。
写真は動作確認しているときの様子。長めの USB ケーブルを使ってパソコンと接続し、Spresense をなるべく窓に近いところに置いたのだ。
GNSS とは?
Global Navigation Satellite System の略。日本語だと「全地球測位システム」と言うらしい。
世界中には、いくつかの国が運営する GNSS があります。アメリカの GPS (Global Positioning System) はその一つで、他にもロシアの GLONASS や欧州の Galileo、中国の BeiDou などがある。これらのシステムが協力して働くことで、高い精度で位置情報を得ることができるようになっている。by ChatGPT
日本の「みちびき」は日本が運用している「準天頂衛星システム (GZSS)」の一部である。GZSS は Quasi-Zenith Satellite System の略称で、GZSS は GNSS の 1 つではないらしい。GNSS の補完・強化を目的とした衛星システムだそうな。by ChatGPT
で、Spresense メインボードには最初っから GNSS アンテナが内蔵されていて、複数種の衛星システムの信号を同時に受信できるマルチ GNSS 対応になっています。
Spresense 構成
以下の組み合わせで動作確認した。
- Spresense メインボード
- LTE 拡張ボード (LM1)
- HDR カメラボード
今回のスケッチは Spresense メインボードだけでも動作するものと思われる。
注意事項
屋内だと衛星からの電波検知が弱いこともあるので、屋外もしくは屋内であっても窓際などでテストするのがおすすめ。
僕がテストした環境だと、プログラムが動作開始してから 2 – 3 分くらいで経度・緯度・高度情報が表示可能となった。これくらいの時間は掛かるらしい。
あと、衛星とは関係ないが、そもそもの話として、Spresense メインボードと HDR カメラボードは遮光シールを基板に貼り付けないと意図せぬ動作をすることがあるようなので貼っておこう。遮光シールは購入時についている小さな黒いシールだ。
※ Spresense 公式ドキュメントのココ に説明があるよ。

コード
#include <GNSS.h>
static SpGnss Gnss;
// 日時を出力する関数の宣言
void printDateTime(SpNavData &navData);
void setup() {
Serial.begin(115200);
Serial.println("GNSS 位置情報表示プログラムを開始します");
// GNSS (Global Navigation Satellite System) の初期化
if (Gnss.begin() != 0) {
Serial.println("Gnss 初期化エラー");
while (1);
}
// GPS (Global Positioning System) と QZSS (QZSS: Quasi-Zenith Satellite System) を選択
Gnss.select(GPS);
Gnss.select(QZ_L1CA); // QZSS 衛星 (みちびき) から送信される信号の 1 つで GPS と互換性がある
Gnss.select(QZ_L1S); // QZSS 衛星から送信される QZSS 独自の信号
// 測位開始
if (Gnss.start(COLD_START) != 0) {
Serial.println("Gnss 開始エラー");
while (1);
}
}
// GNSS から取得した日時情報の出力フォーマットを定義
void printDateTime(SpNavData &navData) {
char buf[64];
snprintf(buf, sizeof(buf), "日時: %04d/%02d/%02d %02d:%02d:%02d UTC",
navData.time.year,
navData.time.month,
navData.time.day,
navData.time.hour,
navData.time.minute,
navData.time.sec);
Serial.println(buf);
}
void loop() {
// GNSS データの更新を待つ
if (Gnss.waitUpdate(-1)) {
// 位置情報を取得
SpNavData navData;
Gnss.getNavData(&navData);
// 日時を表示
printDateTime(navData);
// GNSS モジュールが十分な制度で位置情報を計算できたら、
if (navData.posDataExist) {
Serial.print("緯度: ");
Serial.println(navData.latitude, 6);
Serial.print("経度: ");
Serial.println(navData.longitude, 6);
Serial.print("高度: ");
Serial.print(navData.altitude, 2);
Serial.println(" m"); // メートル単位
Serial.print("衛星数: ");
Serial.println(navData.numSatellites);
} else {
Serial.println("位置情報が取得できません");
}
delay(5000);
Serial.println("-------------------");
}
}
コードを動かした時のコンソール表示
Arduino IDE でプログラムが動いている時の様子

このように、日時と緯度・経度・高度が表示される。
衛星数が表示されているのは、その時 Spresense が位置情報の計算に使用している衛星の数 (通信している衛星の数) です。

