Tutorial 6

How to parse NS-HP NMEA message in Arduino Uno and Raspberry Pi.

 

Introduction

SkytraqNmeaParser is a C++ library for parsing NMEA data streams provided by SkyTraq GPS/GNSS modules.

This library provides position, date, time, altitude, speed, course , satellites information and  RTK information from SkyTraq GPS/GPS devices. In this tutorial we are going to use an Arduino Uno or Raspberry Pi to receive NMEA data stream from NS-HP, and display position and RTK status in console. A Bluetooth Serial Link is necessary in this tutorial for input RTCM message to NS-HP.

 

Breakout Wiring

For Arduino Uno

Arduino Uno 3.3V - NS-HP (RFVCC33, VCC33, VBAT) - Bluetooth Serial Link (VCC33, PIO2)

Arduino Uno GND - NS-HP (RFGND, GND) - Bluetooth Serial Link (GND, PIO3, PIO4)

Arduino Uno RX - Arduino Digital Pin 2 - NS-HP TX1

NS-HP TX2 - Bluetooth Serial Link TX

NS-HP RX2 - Bluetooth Serial Link RX

NS-HP STS - LED - 220 Ohms resistor - GND

 

For Raspberry Pi

Raspberry Pi 3.3V - NS-HP (RFVCC33, VCC33, VBAT) - Bluetooth Serial Link (VCC33, PIO2)

Raspberry Pi GND - NS-HP (RFGND, GND) - Bluetooth Serial Link (GND, PIO3, PIO4)

Raspberry Pi RX - NS-HP TX1

NS-HP TX2 - Bluetooth Serial Link TX

NS-HP RX2 - Bluetooth Serial Link RX

NS-HP STS - LED - 220 Ohms resistor - GND

The Sketch

For Arduino Uno

Download the NavSpark Example Code Files from our Resources page and open the SkyTraq NMEA Parser demo for Arduino Uno (SkytraqNmeaParserUno)


#include <SoftwareSerial.h>
#include "SkyTraqNmeaParser.h"

// The SkyTraqNmeaParser object
SkyTraqNmeaParser parser;
// The SkyTraqNmeaParser result
const GnssData* gdata;
// Notification of SkyTraqNmeaParser
U32 gnssUpdateFlag = 0;

//Callback function for SkyTraqNmeaParser notification
bool GnssUpdated(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type);
// Display parsing result
bool Display(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type);
// Show satellites information(from GSV token, and need turn on _SUPPORT_GPS_SATELLITES_, 
// _SUPPORT_GLONASS_SATELLITES_ or _SUPPORT_BEIDOU_SATELLITES_)
void ShowSatellites(const SatelliteInfo* si);

void setup()
{
  //Set callback function for parsing result notification
  parser.SetNotify(GnssUpdated);
  
  //For UART interrupt
  pinMode(2, INPUT);
  digitalWrite(2, LOW);
  
  //NS-HP output NMEA message in 115200 bps
  Serial.begin(115200);
  attachInterrupt(0, serialInterrupt, CHANGE);

  Serial.println("Init done!=================================");
}

//Set the flag to true to prevent re-entry of interrupt.
volatile boolean inService = false;
void serialInterrupt()
{
 if (inService) 
 {
   return;
 }
 inService = true;

 interrupts();
 while(!Serial.available());
 parser.Encode(Serial.read());

 inService = false;
}

void loop()
{

}

void ShowSatellites(const SatelliteInfo* si)
{
  bool hasTitle = false;
  int max = GnssData::GetMaxSatelliteNum();
  for(int i = 0; i < max; ++i)
  {
    if(si[i].sv == 0)
      break;
    if(!hasTitle)
    {
      Serial.print("PRN \tAZ  \tEL  \tCN0  \tUsed\r\n");
      hasTitle = true;
    }
    Serial.print(si[i].sv);
    Serial.print('\t');
    Serial.print(si[i].azimuth);
    Serial.print('\t');
    Serial.print(si[i].elevation);
    Serial.print('\t');
    Serial.print(si[i].cno);
    Serial.print('\t');
    Serial.println((si[i].isInUse) ? 'Y' : 'N');
  }
}

bool GnssUpdated(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type)
{
  gnssUpdateFlag |= f;
  gdata = parser.GetGnssData();
  Display(f, buf, type);
  //return true to clear the flag in SkyTraqNmeaParseryTraq
  return true;
}

bool Display(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type)
{
  U32 i = 0;
  const GnssData& gnss = *gdata;

  for(; i < 32; ++i)
  {
    U32 mask = (1 << i);
    switch((mask & f))
    {
    case SkyTraqNmeaParser::NoUpdate:
      //Do nothing
      break;
    case SkyTraqNmeaParser::UpdateDate:
      Serial.print("Date:");
      Serial.print(gnss.GetYear());
      Serial.print('/');
      Serial.print(gnss.GetMonth());
      Serial.print('/');
      Serial.println(gnss.GetDay());
      break;
    case SkyTraqNmeaParser::UpdateTime:
      Serial.print("Time:");
      Serial.print(gnss.GetHour());
      Serial.print(':');
      Serial.print(gnss.GetMinute());
      Serial.print(':');
      Serial.println(gnss.GetSecond());      
      break;
    case SkyTraqNmeaParser::UpdateLatitude:
      Serial.print("Latitude:");
      Serial.println(gnss.GetLatitude());
      break;
    case SkyTraqNmeaParser::UpdateLongitude:
      Serial.print("Longitude:");
      Serial.println(gnss.GetLongitude());
      break;
    case SkyTraqNmeaParser::UpdateAltitude:
      Serial.print("Altitude:");
      Serial.println(gnss.GetAltitudeInMeter());
      break;
    case SkyTraqNmeaParser::UpdateCourse:
     Serial.print("Course:");
      Serial.println(gnss.GetCourseInDegree());
      break;
    case SkyTraqNmeaParser::UpdateSpeed:
      Serial.print("Speed:");
      Serial.println(gnss.GetSpeedInKmHr());
      break;
    case SkyTraqNmeaParser::UpdateQualitMode:
      Serial.print("Qualit Mode:");
      Serial.println(gnss.GetQualitMode());
      break;
    case SkyTraqNmeaParser::UpdateNumberOfSv:
      Serial.print("Number Of Sv:");
      Serial.println(gnss.GetNumberOfSv());
      break;
    case SkyTraqNmeaParser::UpdateHdop:
      Serial.print("HDOP:");
      Serial.println(gnss.GetHdop());
      break;
    case SkyTraqNmeaParser::UpdatePdop:
      Serial.print("PDOP:");
      Serial.println(gnss.GetPdop());
      break;
    case SkyTraqNmeaParser::UpdateVdop:
      Serial.print("VDOP:");
      Serial.println(gnss.GetVdop());
      break;
    case SkyTraqNmeaParser::UpdateNavigationMode:
      Serial.print("Navigation Mode:");
      Serial.println(gnss.GetNavigationMode());
      break;
    case SkyTraqNmeaParser::UpdateSatelliteInfo:
#if (_SUPPORT_GPS_SATELLITES_)
      ShowSatellites(gnss.GetGpsSatellites());
#endif
#if (_SUPPORT_GLONASS_SATELLITES_)
      ShowSatellites(gnss.GetGlonassSatellites());
#endif
#if (_SUPPORT_BEIDOU_SATELLITES_)
      ShowSatellites(gnss.GetBeidouSatellites());
#endif
      break;
    case SkyTraqNmeaParser::UpdateEnuVelocity:
      Serial.print("E-Velocity:");
      Serial.print(gnss.GetEVelocity());
      Serial.print("   N-Velocityy:");
      Serial.print(gnss.GetNVelocity());
      Serial.print("   U-Velocity:");
      Serial.println(gnss.GetUVelocity());
     break;
    case SkyTraqNmeaParser::UpdateRtkAge:
      Serial.print("RTK Age:");
      Serial.println(gnss.GetRtkAge());
      break;
    case SkyTraqNmeaParser::UpdateRtkRatio:
      Serial.print("RTK Ratio:");
      Serial.println(gnss.GetRtkRatio());
     break;
    case SkyTraqNmeaParser::UpdateEnuProjection:
      Serial.print("E-Projection:");
      Serial.print(gnss.GetEProjection());
      Serial.print("   N-Projection:");
      Serial.print(gnss.GetNProjection());
      Serial.print("   U-Projection:");
      Serial.println(gnss.GetUProjection());      
      break;
    case SkyTraqNmeaParser::UpdateBaselineLength:
       Serial.print("RTK Baseline Length:");
       Serial.println(gnss.GetBaselineLength());
       break;
    case SkyTraqNmeaParser::UpdateBaselineCourse:
      Serial.print("RTK Baseline Course:");
      Serial.println(gnss.GetBaselineCourse());
      break;
    default:
      break;
    }
  }
  return true;
}

For Raspberry Pi

Download the NavSpark Example Code Files from our Resources page and open the SkyTraq NMEA Parser demo for Raspberry Pi (SkytraqNmeaParserPi). In this sketch, we use arduPi from cooking-hacks.com is a C++ library that lets you write programs for Raspberry Pi as if you were writing an arduino program. 

#include "arduPi.h"
#include "SkyTraqNmeaParser.h"

// The SkyTraqNmeaParser object
SkyTraqNmeaParser parser;
// The SkyTraqNmeaParser result
const GnssData* gdata;
// Notification of SkyTraqNmeaParser
U32 gnssUpdateFlag = 0;

//Callback function for SkyTraqNmeaParser notification
bool GnssUpdated(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type);
// Display parsing result
bool Display(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type);
// Show satellites information(from GSV token, and need turn on _SUPPORT_GPS_SATELLITES_, 
// _SUPPORT_GLONASS_SATELLITES_ or _SUPPORT_BEIDOU_SATELLITES_)
void ShowSatellites(const SatelliteInfo* si);

void setup()
{
  //Set callback function for parsing result notification
  parser.SetNotify(GnssUpdated);
  
  //For UART interrupt
  pinMode(2, INPUT);
  digitalWrite(2, LOW);
  
  //NS-HP output NMEA message in 115200 bps
  Serial.begin(115200);
  //attachInterrupt(0, serialInterrupt, CHANGE);

  Serial.println("Init done!=================================");
}
/*
//Set the flag to true to prevent re-entry of interrupt.
volatile boolean inService = false;
void serialInterrupt()
{
 if (inService) 
 {
   return;
 }
 inService = true;

 interrupts();
 while(!Serial.available());
 parser.Encode(Serial.read());

 inService = false;
}
*/
void loop()
{
 if(Serial.available())
   parser.Encode(Serial.read());

 //inService = false;

}

void ShowSatellites(const SatelliteInfo* si)
{
  bool hasTitle = false;
  int max = GnssData::GetMaxSatelliteNum();
  for(int i = 0; i < max; ++i)
  {
    if(si[i].sv == 0)
      break;
    if(!hasTitle)
    {
      printf("PRN \tAZ  \tEL  \tCN0  \tUsed\r\n");
      hasTitle = true;
    }
    printf("%d\t%d\t%d\t%d\t%c\r\n", si[i].sv, si[i].azimuth, si[i].elevation, si[i].cno, (si[i].isInUse) ? 'Y' : 'N');
  }
}

bool GnssUpdated(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type)
{
  gnssUpdateFlag |= f;
  gdata = parser.GetGnssData();
  Display(f, buf, type);
  //return true to clear the flag in SkyTraqNmeaParseryTraq
  return true;
}

bool Display(U32 f, const char* buf, SkyTraqNmeaParser::ParsingType type)
{
  U32 i = 0;
  const GnssData& gnss = *gdata;

  for(; i < 32; ++i)
  {
    U32 mask = (1 << i);
    switch((mask & f))
    {
    case SkyTraqNmeaParser::NoUpdate:
      //Do nothing
      break;
    case SkyTraqNmeaParser::UpdateDate:
      printf("Date:%04d/%02d/%02d\r\n", gnss.GetYear(), gnss.GetMonth(), gnss.GetDay());
      break;
    case SkyTraqNmeaParser::UpdateTime:
      printf("Time:%02d:%02d:%2.3f\r\n", gnss.GetHour(), gnss.GetMinute(), gnss.GetSecond());
      break;
    case SkyTraqNmeaParser::UpdateLatitude:
      printf("Latitude:%3.7f\r\n", gnss.GetLatitude());
      break;
    case SkyTraqNmeaParser::UpdateLongitude:
      printf("Longitude:%3.7f\r\n", gnss.GetLongitude());
      break;
    case SkyTraqNmeaParser::UpdateAltitude:
      printf("Altitude:%5.1f\r\n", gnss.GetAltitudeInMeter());
      break;
    case SkyTraqNmeaParser::UpdateCourse:
      printf("Course:%3.1f\r\n", gnss.GetCourseInDegree());
      break;
    case SkyTraqNmeaParser::UpdateSpeed:
      printf("Speed:%5.2f km/hr\r\n", gnss.GetSpeedInKmHr());
      break;
    case SkyTraqNmeaParser::UpdateQualitMode:
      printf("Qualit Mode:%d\r\n", gnss.GetQualitMode());
      break;
    case SkyTraqNmeaParser::UpdateNumberOfSv:
      printf("Number Of Sv:%d\r\n", gnss.GetNumberOfSv());
      break;
    case SkyTraqNmeaParser::UpdateHdop:
      printf("HDOP:%3.1f\r\n", gnss.GetHdop());
      break;
    case SkyTraqNmeaParser::UpdatePdop:
      printf("PDOP:%3.1f\r\n", gnss.GetPdop());
      break;
    case SkyTraqNmeaParser::UpdateVdop:
      printf("VDOP:%3.1f\r\n", gnss.GetVdop());
      break;
    case SkyTraqNmeaParser::UpdateNavigationMode:
      printf("Navigation Mode:%d\r\n", gnss.GetNavigationMode());
      break;
    case SkyTraqNmeaParser::UpdateSatelliteInfo:
#if (_SUPPORT_GPS_SATELLITES_)
      ShowSatellites(gnss.GetGpsSatellites());
#endif
#if (_SUPPORT_GLONASS_SATELLITES_)
    (  ShowSatellites(gnss.GetGlonassSatellites());
#endif
#if (_SUPPORT_BEIDOU_SATELLITES_)
      ShowSatellites(gnss.GetBeidouSatellites());
#endif
      break;
    case SkyTraqNmeaParser::UpdateEnuVelocity:
      printf("E-Velocity:%5.2f   N-Velocity:%5.2f   U-Velocity:%5.2f\r\n", gnss.GetEVelocity(), gnss.GetNVelocity(), gnss.GetUVelocity());
      break;
    case SkyTraqNmeaParser::UpdateRtkAge:
      printf("RTK Age:%f\r\n", gnss.GetRtkAge());
      break;
    case SkyTraqNmeaParser::UpdateRtkRatio:
      printf("RTK Ratio:%f\r\n", gnss.GetRtkRatio());
      break;
    case SkyTraqNmeaParser::UpdateEnuProjection:
      printf("E-Projection:%5.2f   N-Projection:%5.2f   U-Projection:%5.2f\r\n", gnss.GetEProjection(), gnss.GetNProjection(), gnss.GetUProjection());
      break;
    case SkyTraqNmeaParser::UpdateBaselineLength:
      printf("RTK Baseline Length:%5.1f\r\n", gnss.GetBaselineLength());
      break;
    case SkyTraqNmeaParser::UpdateBaselineCourse:
      printf("RTK Baseline Course:%3.1f\r\n", gnss.GetBaselineCourse());
      break;
    default:
      break;
    }
  }
  return true;
}

int main() {
  setup();
  while(1) {
    loop();
  }
}

The Sketch in Action

This demo will show the NMEA data streams parsing result in console.

© 2023 by Barista. Proudly created with Wix.com

公司logo1-4(600x139).png