Spresenseに実装されているGPSで準天頂衛星システム「みちびき」(QZSS(Quasi-Zenith Satellite System))を捕捉します。「GPSチュートリアル」に従って、Arduino IDEを用いてコードを作成します。
準天頂衛星システム「みちびき」
みちびきの準天頂軌道は、南北非対称の「8の字軌道」になり、北半球に約13時間、南半球に約11時間留まり、日本付近に長く留まります。( 技術情報|みちびき(準天頂衛星システム:QZSS)公式サイト – 内閣府から引用)
準天頂衛星システム「みちびき」の衛星運用状況を次に示します。
コードの「satType 」には
- PNTサービス:QZSS_L1CA
- SLASサービス:QZSS_L1S
と設定します。
Spresenseに実装されているGPS
SPRESENSEのGNSS Domainは、GPS/GLONASS/QZSSに対応し、専用のGNSS受信回路から得た人工衛星の情報を取得、到達する時刻情報を活用し人工衛生のズレを推測、最後に緯度経度情報と時刻情報を推定します。
- 衛星測位サービス L1C/A
- サブメータ級測位補強サービス L1S
一般の信号を、みちびきも出力しています。信号の元が増えるので、精度が良くなります。誤差10m程度
L1C/Aと同じ信号らしいので、機器の対応はしやすい様です。誤差1m以下。
サンプルコード「gnss 」でのGPSデータ取得
Arduino IDE のスケッチ例から次の手順でコードを取得してGPSデータを取得します。
メニュー「ファイル」から→ 「スケッチ例」 →「 GNSS」 → 「gnss」と選択してスケッチを開きます。
取得したスケッチを次のように変更します。
- 24行目でsatType を eSatGpsQz1cQz1S へ変更して、準天頂衛星システム「みちびき」からのデータを取得します。
- 10-20行目にParamSatで設定できるパラメータとその意味を示します。
- 36-65行目にシリアルモニタに表示される衛星タイプを示します。
gnss.ino
・・・
static SpGnss Gnss; /**< SpGnss object */
/**
* @enum ParamSat
* @brief Satellite system
*/
enum ParamSat {
eSatGps, /**< GPS World wide coverage */
eSatGlonass, /**< GLONASS World wide coverage */
eSatGpsSbas, /**< GPS+SBAS North America */
eSatGpsGlonass, /**< GPS+Glonass World wide coverage */
eSatGpsBeidou, /**< GPS+BeiDou World wide coverage */
eSatGpsGalileo, /**< GPS+Galileo World wide coverage */
eSatGpsQz1c, /**< GPS+QZSS_L1CA East Asia & Oceania */
eSatGpsGlonassQz1c, /**< GPS+Glonass+QZSS_L1CA East Asia & Oceania */
eSatGpsBeidouQz1c, /**< GPS+BeiDou+QZSS_L1CA East Asia & Oceania */
eSatGpsGalileoQz1c, /**< GPS+Galileo+QZSS_L1CA East Asia & Oceania */
eSatGpsQz1cQz1S, /**< GPS+QZSS_L1CA+QZSS_L1S Japan */
};
/* Set this parameter depending on your current region. */
static enum ParamSat satType = eSatGpsQz1cQz1S ;
/**
* @brief Turn on / off the LED0 for CPU active notification.
*/
・・・
/* Get satellite type. */
/* Keep it to three letters. */
switch (sattype)
{
case GPS:
pType = "GPS";
break;
case GLONASS:
pType = "GLN";
break;
case QZ_L1CA:
pType = "QCA";
break;
case SBAS:
pType = "SBA";
break;
case QZ_L1S:
pType = "Q1S";
break;
case BEIDOU:
pType = "BDS";
break;
case GALILEO:
pType = "GAL";
break;
default:
pType = "UKN";
break;
}
/* Get print conditions. */
・・・
作成したコードをSPRESENSEに書き込み、実行します。次のようにGPSデータがシリアルモニタ表示されます。
・・・ 17:47:00.797 -> numSatellites: 7 17:47:00.797 -> [ 0] Type:GPS, Id:10, Elv:52, Azm:298, CN0:40.119999 17:47:00.797 -> [ 1] Type:GPS, Id:15, Elv: 0, Azm: 0, CN0:20.160000 17:47:00.797 -> [ 2] Type:GPS, Id:25, Elv:36, Azm:182, CN0:15.969999 17:47:00.797 -> [ 3] Type:GPS, Id:32, Elv:23, Azm:304, CN0:33.779999 17:47:00.797 -> [ 4] Type:Q1S, Id:186, Elv:68, Azm:207, CN0:43.090000 17:47:00.844 -> [ 5] Type:QCA, Id:194, Elv:53, Azm:164, CN0:32.360001 17:47:00.844 -> [ 6] Type:QCA, Id:196, Elv:68, Azm:207, CN0:40.489998 17:47:00.844 -> 2022/09/10 08:47:00.000684, numSat: 7, Fix, Lat=xx, Lon=xx 17:47:01.778 -> 2022/09/10 08:47:01.000675, numSat: 7, Fix, Lat=xx, Lon=xxx 17:47:02.808 -> 2022/09/10 08:47:02.000698, numSat: 7, Fix, Lat=xx, Lon=xx 17:47:03.792 -> 2022/09/10 08:47:03.000687, numSat: 7, Fix, Lat=xx, Lon=xx 17:47:04.820 -> 2022/09/10 08:47:04.000673, numSat: 7, Fix, Lat=xx, Lon=xx ・・・
次のみちびきの衛星が表示されています。
- Type:Q1S, Id:186
- Type:QCA, Id:194
- Type:QCA, Id:196
SpresenseのGPSでNMEA センテンスの出力
GPS受信機で一般的に使用される NMEA0183 形式に従った データをシリアルモニタに出力します。「2.5. NMEA センテンスを出力する」を参考にして次のようにコードを作成します。
- 文字列に変換されたNMEA センテンスはシリアルモニタに表示するために9行目の「outnmea」関数を呼び出します。従って、パラメータで渡された文字列を解析すれば、物理的なフォーマットでシリアルモニタに表示できます。
- 22-26行目で使用する衛星システムを選択します。
- 39行目でシリアルモニタに表示するNMEA センテンスします。GGA+GSA+GSVを選択します。詳細については、「 NMEA マスク値について」に示します。
SpresenseNMEA.ino
・・・
static int outbin(char *buf, uint32_t len)
{
return len;
}
static int outnmea(char *buf)
{
//buf = "$GPGGA,234356.00,3525.9459,N,13938.7785,E,2,09,1.1,36.1,M,39.2,M,,*52";
//GPS_datareceiveNMEA(buf,NMEA_SENTENCE_MAX_LEN);
return printf("%s", buf);
}
void setup()
{
・・・
/* select satellite system */
Gnss.select(GPS);
//Gnss.select(GLONASS);
//Gnss.select(SBAS);
Gnss.select(QZ_L1CA); // Michibiki complement
Gnss.select(QZ_L1S); // Michibiki augmentation(Valid only in Japan)
・・・
/* set interval */
Gnss.setInterval(1);
if (Gnss.start(COLD_START)) {
Serial.println("start error!");
}
/* use NMEA library */
NMEA_InitMask();
NMEA_SetMask(0x0d); // only GGA+GSA+GSV
//NMEA_SetMask(0x5); // only GGA+GSA
//NMEA_SetMask(0x4000); // only QZQSM
NMEA_OUTPUT_CB funcs;
funcs.bufReq = reqbuf;
funcs.out = outnmea;
funcs.outBin = outbin;
funcs.bufFree = freebuf;
NMEA_RegistOutputFunc(&funcs);
}
void loop()
{
/* Check update. */
if (Gnss.waitUpdate(1000)) {
/* Output NMEA */
Gnss.getPositionData(PositionData);
NMEA_Output(&(((GnssPositionData*)PositionData)->Data));
}
}
作成したコードをSPRESENSEに書き込み、実行します。次のようにデータがシリアルモニタ表示されます。
・・・ 17:41:30.828 -> $GNGSA,A,3,10,15,,,,,,,,,,,12.0,4.6,11.0,1*35 17:41:30.828 -> $GNGSA,A,3,02,04,,,,,,,,,,,12.0,4.6,11.0,5*32 17:41:30.828 -> $GPGSV,2,1,06,10,50,301,35,13,04,098,,15,35,102,25,18,06,212,,0*6F 17:41:30.828 -> $GPGSV,2,2,06,22,00,291,,23,68,239,,,,,,,,,,0*6E 17:41:30.828 -> $GQGSV,1,1,03,58,69,208,42,02,52,164,35,04,69,208,40,,,,,0*5C 17:41:31.810 -> $GPGGA,084131.00,3525.9498,N,13938.7724,E,2,04,4.7,26.8,M,39.2,M,,*58 ・・・
次のNMEA「$GQGSV」は、??です。みちびき衛星「02」,「04」は、PRNでなくSVNで示しているように思います。それ以前のデータ群のフォーマットが「xxGSV」と異なっています。
$GQGSV,1,1,03,58,69,208,42, 02,52,164,35, 04,69,208,40,,,,,0*5C
NMEA マスク値について
NMEA 0183 (ver 4.00) 規格で定義されている NMEA センテンスのうち、 出力する NMEA センテンスをビットマスク値を NMEA_SetMask() 関数の引数に指定します。 初期状態では NMEA マスクには 0xef が設定されています。
| NMEA | Bit | Description | |
|---|---|---|---|
| $xxGGA | 0 | 時刻、緯度経度、標高、測位状態、DGPS基地局番号などの基本情報 | |
| $xxGLL | 1 | 時刻、緯度経度、測位状態などGGAの簡易版 | |
| $xxGSA | 2 | 衛星毎の使用不使用、DOP値 | |
| $xxGSV | 3 | 可視衛星の衛星番号、仰角、方位角、信号強度 | |
| $xxGNS | 4 | 時刻、緯度経度、測位状態 | |
| $xxRMC | 5 | 時刻、緯度経度、速度、時期偏差 | |
| $xxVTG | 6 | 移動速度に関する詳細情報 | |
| $xxZDA | 7 | 年月日を含む時刻情報 | |
| $QZQSM | 14 | 災害危機管理通報サービスメッセージ(QZSS独自センテンス) |
xx は、以下を表します。
GP:GPS衛星で測位している場合
GL:GLONASS衛星で測位している場合
GZ:QZS衛星で測位している場合
BD:BeiDou衛星で測位している場合
GA:Galileo衛星で測位している場合
GN:複数の衛星システムを利用して測位している場合


