-
Notifications
You must be signed in to change notification settings - Fork 0
GPS_RMC
簡易的GPS位置/時刻情報取得支援クラス。
UART接続 GPSの NMEAフォーマットの内$**RMC
行だけを解析し、
位置情報と時刻情報を取得する。
他の情報は解析しないため実装コード量は必要最低限である。
ただしlong
型乗除算を含む。
浮動小数点演算は使われない。
取得される緯度/経度は、1/6,000,000
度を最小単位とするlong
符号付整数値である。
この最小単位で割るとWeb地図で使用できる浮動小数点値を直接得られる。
ただし AVR-GCC/AVR-LIBC では普通float
単精度浮動小数点数しかサポートされないため、
精度落ちがあることに注意されたい。
本来の正確な GPS取得精度を維持してセンサー送信する場合には元のlong
型のままとするのが良い。
取得される年月日/時分秒は、BCD表現のUTC
世界協定時である。
最小精度は秒。
UNIX epoch
への変換や、地域時への時差加減算には
<bcddatetime.h>
を使用すると良い。
#include <GPS_RMC.h>
GPS_RMC_Class GPS_RMC; /* クラスインスタンス作成 */
void setup (void) {
Serial.begin(CONSOLE_BAUD); /* to PC console */
Serial1.begin(9600); /* from GPS NMEA */
}
void loop (void) {
/* 注:RMC以外の出力を抑制していないのなら 1024 は必要だろう */
/* 抑制されているなら 1行読めれば良い */
char buff[ 80 ];
/* GPSシリアルから NMEAを読取 */
size_t length = Serial1.readBytes(&buff, sizeof(buff));
if (0 < length && '$' == buff[0]) {
/* 行頭が`$`文字ならば */
if (GPS_RMC.update(&buff, length)) {
/* 解析に成功したならば */
/* 情報を構造体に取得 */
gpsdata_t gpsdata = GPS_RMC.getData();
/* 時刻情報が更新されたなら */
if (gpsdata.update.stamp) {
/* BCD表現値をそのまま 16進プリント */
Serial
.print(gpsdata.stamp.date, HEX)
.print('-')
.print(gpsdata.stamp.time, ZHEX, 6)
.print(' ')
;
/* 位置情報が取得されたなら */
if (gpsdata.update.coordinate) {
/* Web地図表現に変換してプリント */
Serial
.print(gpsdata.coordinate.latitude / 6000000.0, 7)
.print(',')
.print(gpsdata.coordinate.longitude / 6000000.0, 7)
.ln()
;
}
/* 位置情報なし */
else {
Serial.println(F("(no latlon)"));
}
return;
}
}
/* 時刻/位置情報なし */
Serial.println(F("(no time) (no latlon)"));
}
}
具体的な用例は [M5_GPS_LatLonサンプル] が詳しい。
GPS_RMC_Class
を定義する。
依存性:<bcddatetime.h>
NEMA
解析結果を返す構造体定義。
gpsdata_t | 型 | 説明 | 備考 | ||
---|---|---|---|---|---|
.coordinate | .latitude | long | 緯度 | LSB:1/6000000.0度 | |
.longitude | long | 経度 | LSB:1/6000000.0度 | ||
.stamp | .time | bcdtime_t | BCD時分秒 | 0x123456 等 | |
.date | bcddate_t | BCD年月日 | 0x20221231 等 | ||
.update | .coordinate | bool | 位置情報更新 | 更新で真 | |
.stamp | bool | 時刻情報更新 | 更新で真 |
NMEA
テキストを含む_buffer
を先頭から最大_limit
量まで解析し、
チェックサムを計算/照合し、
$**RMC
行の取得に成功したなら真を返す。
bool result = GPS_RMC.update(&buff, length);
update
で取得された$**RMC
行の解析結果をgpsdata_t
構造体で返す。
gpsdata_t gpsdata = GPS_RMC.getData();
long latitude = gpsdata.coordinate.latitude;
long longitude = gpsdata.coordinate.longitude;
bcdtime_t time = gpsdata.stamp.time;
bcddate_t date = gpsdata.stamp.date;
bool coordinate = gpsdata.update.coordinate;
bool stamp = gpsdata.update.stamp;
NMEA
行を_buffer
とその長さ_limit
で与え、計算されたチェックサムを返す。
与える行は$
で始まり*
で終わる範囲である。
char nmea[] = "$PCAS03,0,0,0,0,1,0,0,0*";
uint8_t chksum = GPS_RMC.calcCheckSum(&nmea, sizeof(nmea-1)); // Return the 0x03
NMEA
行を_buffer
とその長さ_limit
で与え、末尾のチェックサムを照合した結果を真理値で返す。
char nmea[] = "$PCAS03,0,0,0,0,1,0,0,0*03";
bool result = GPS_RMC.calcCheckSum(&nmea, sizeof(nmea-1)); // Return the true
Twitter(X): @askn37
BlueSky Social: @multix.jp
GitHub: https://github.com/askn37/
Product: https://askn37.github.io/
Copyright (c) 2022,2023 askn (K.Sato) multix.jp
Released under the MIT license
https://opensource.org/licenses/mit-license.php
https://www.oshwa.org/
multix.jp/てくにかるむ(休眠中)
Multix Zinnia Product SDK [*AVR]
AVR.JP(日本語訳)
AVR-LIBC(日本語訳)