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
  • 一般の信号を、みちびきも出力しています。信号の元が増えるので、精度が良くなります。誤差10m程度

  • サブメータ級測位補強サービス L1S
  • 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:複数の衛星システムを利用して測位している場合