George Kartsonas
Published © Apache-2.0

Sony Spresense GPS + Compass

If you're hiking, going on a family trip in the car or just plain curious about where you are, the Spresense is just the device you need.

BeginnerProtip1 hour1,672

Things used in this project

Story

Read more

Code

Arduino GPS+LCD+COMPASS Code

Arduino
#include <Audio.h>
#include <GNSS.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

#define STRING_BUFFER_SIZE  128       /**< %Buffer size */

#define RESTART_CYCLE       (60 * 5)  /**< positioning test term */

float currentLatitude = 11.11111;  /*Your current Latitude here*/
float currentLongitude = 11.11111; /*Your current Longitude here*/

AudioClass *theAudio;

static SpGnss Gnss;                   /**< SpGnss object */

int led = 13;

int getheading(float targetlatitude, float targetlongitude)
{
  float heading = atan2(targetlatitude - currentLatitude, targetlongitude - currentLongitude);

  heading *= (180 / 3.14159);
  heading = (450 - (int)heading) % 360;

  return heading;
}

class Score
{
  public:

    typedef struct {
      int fs;
      int time;
    } Note;

    void init() {
      pos = 0;
    }

    Note get() {
      return data[pos++];
    }

  private:

    int pos;

    Note data[17] =
    {
      {262, 500},
      {294, 500},
      {330, 500},
      {349, 500},
      {392, 500},
      {440, 500},
      {494, 500},
      {523, 1000},

      {523, 500},
      {494, 500},
      {440, 500},
      {392, 500},
      {349, 500},
      {330, 500},
      {294, 500},
      {262, 1000},

      {0, 0}
    };
};

Score theScore;
static void Led_isActive(void)
{
  static int state = 1;
  if (state == 1)
  {
    ledOn(PIN_LED0);
    state = 0;
  }
  else
  {
    ledOff(PIN_LED0);
    state = 1;
  }
}

/**
   @brief Turn on / off the LED1 for positioning state notification.

   @param [in] state Positioning state
*/
static void Led_isPosfix(bool state)
{
  if (state)
  {
    ledOn(PIN_LED1);
  }
  else
  {
    ledOff(PIN_LED1);
  }
}

/**
   @brief Turn on / off the LED3 for error notification.

   @param [in] state Error state
*/
static void Led_isError(bool state)
{
  if (state)
  {
    ledOn(PIN_LED3);
  }
  else
  {
    ledOff(PIN_LED3);
  }
}

/**
   @brief Activate GNSS device and start positioning.
*/
void setup() {
  /* put your setup code here, to run once: */
  theAudio = AudioClass::getInstance();
  theAudio->begin();
  puts("initialization Audio Library");

  theAudio->setPlayerMode(AS_SETPLAYER_OUTPUTDEVICE_SPHP);

  theScore.init();

  pinMode(led, OUTPUT);

  int error_flag = 0;

  /* Set serial baudrate. */
  Serial.begin(115200);

  /* Wait HW initialization done. */
  sleep(3);

  /* Turn on all LED:Setup start. */
  ledOn(PIN_LED0);
  ledOn(PIN_LED1);
  ledOn(PIN_LED2);
  ledOn(PIN_LED3);

  /* Set Debug mode to Info */
  Gnss.setDebugMode(PrintInfo);

  int result;

  /* Activate GNSS device */
  result = Gnss.begin();

  if (result != 0)
  {
    Serial.println("Gnss begin error!!");
    error_flag = 1;
  }
  else
  {
    /* Setup GNSS */
    Gnss.select(QZ_L1CA);  // Michibiki complement
    Gnss.select(QZ_L1S);   // Michibiki augmentation(Valid only in Japan)

    /* Start positioning */
    result = Gnss.start(COLD_START);
    if (result != 0)
    {
      Serial.println("Gnss start error!!");
      error_flag = 1;
    }
    else
    {
      Serial.println("Gnss setup OK");
    }
  }

  /* Turn off all LED:Setup done. */
  ledOff(PIN_LED0);
  ledOff(PIN_LED1);
  ledOff(PIN_LED2);
  ledOff(PIN_LED3);

  /* Set error LED. */
  if (error_flag == 1)
  {
    Led_isError(true);
    exit(0);
  }
}

/**
   @brief %Print position information.
*/
static void print_pos(SpNavData *pNavData)
{
  char StringBuffer[STRING_BUFFER_SIZE];

  /* print time */
  snprintf(StringBuffer, STRING_BUFFER_SIZE, "%04d/%02d/%02d ", pNavData->time.year, pNavData->time.month, pNavData->time.day);
  Serial.print(StringBuffer);

  snprintf(StringBuffer, STRING_BUFFER_SIZE, "%02d:%02d:%02d.%06d, ", pNavData->time.hour, pNavData->time.minute, pNavData->time.sec, pNavData->time.usec);
  Serial.print(StringBuffer);

  /* print satellites count */
  snprintf(StringBuffer, STRING_BUFFER_SIZE, "numSat:%2d, ", pNavData->numSatellites);
  Serial.print(StringBuffer);

  /* print position data */
  if (pNavData->posFixMode == FixInvalid)
  {
    Serial.print("No-Fix, ");
  }
  else
  {
    Serial.print("Fix, ");
  }
  if (pNavData->posDataExist == 0)
  {
    Serial.print("No Position");
    lcd.print("No Position");

  }
  else
  {
    lcd.setCursor(0,0);
    Serial.print("Lat=");
    lcd.print("Lat=");
    Serial.print(pNavData->latitude, 6);
    lcd.print(pNavData->latitude, 6);
    Serial.print(", Lon=");
    Serial.print(pNavData->longitude, 6);

    if ((pNavData->latitude >= 11.111111) && (pNavData->latitude < 11.111111)) //Here you enter your first Geofencing coordinates
    {
      lcd.setCursor(0,1);
      lcd.print("North: ");
      lcd.println(getheading(pNavData->latitude, pNavData->longitude));

      while (1);
    }

    if ((pNavData->latitude >= 11.111111) && (pNavData->latitude < 11.111111)) //Here you enter your second Geofencing coordinates
    {
      puts("loop!!");

      Score::Note theNote = theScore.get();
      if (theNote.fs == 0) {
        puts("End,");
        exit(1);
      }

      theAudio->setBeep(1, -40, theNote.fs);
      usleep(theNote.time * 1000);
      theAudio->setBeep(0, 0, 0);
      usleep(100000);
      /*Morse Code*/
    }
  }

  Serial.println("");
}



/**
   @brief %Print satellite condition.
*/
static void print_condition(SpNavData *pNavData)
{
  char StringBuffer[STRING_BUFFER_SIZE];
  unsigned long cnt;

  /* Print satellite count. */
  snprintf(StringBuffer, STRING_BUFFER_SIZE, "numSatellites:%2d\n", pNavData->numSatellites);
  Serial.print(StringBuffer);

  for (cnt = 0; cnt < pNavData->numSatellites; cnt++)
  {
    const char *pType = "---";
    SpSatelliteType sattype = pNavData->getSatelliteType(cnt);

    /* 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;

      default:
        pType = "UKN";
        break;
    }

    /* Get print conditions. */
    unsigned long Id  = pNavData->getSatelliteId(cnt);
    unsigned long Elv = pNavData->getSatelliteElevation(cnt);
    unsigned long Azm = pNavData->getSatelliteAzimuth(cnt);
    float sigLevel = pNavData->getSatelliteSignalLevel(cnt);

    /* Print satellite condition. */
    snprintf(StringBuffer, STRING_BUFFER_SIZE, "[%2d] Type:%s, Id:%2d, Elv:%2d, Azm:%3d, CN0:", cnt, pType, Id, Elv, Azm );
    Serial.print(StringBuffer);
    Serial.println(sigLevel, 6);
  }
}

/**
   @brief %Print position information and satellite condition.

   @details When the loop count reaches the RESTART_CYCLE value, GNSS device is
            restarted.
*/
void loop()
{
  /* put your main code here, to run repeatedly: */

  static int LoopCount = 0;
  static int LastPrintMin = 0;

  lcd.begin();

  // Turn on the blacklight and print a message.
  lcd.backlight();
  /* Blink LED. */
  Led_isActive();

  /* Check update. */
  if (Gnss.waitUpdate(-1))
  {
    /* Get NaviData. */
    SpNavData NavData;
    Gnss.getNavData(&NavData);

    /* Set posfix LED. */
    bool LedSet = (NavData.posDataExist && (NavData.posFixMode != FixInvalid));
    Led_isPosfix(LedSet);

    /* Print satellite information every minute. */
    if (NavData.time.minute != LastPrintMin)
    {
      print_condition(&NavData);
      LastPrintMin = NavData.time.minute;
    }

    /* Print position information. */
    print_pos(&NavData);
  }
  else
  {
    /* Not update. */
    Serial.println("data not update");
  }

  /* Check loop count. */
  LoopCount++;
  if (LoopCount >= RESTART_CYCLE)
  {
    int error_flag = 0;

    /* Turn off LED0 */
    ledOff(PIN_LED0);

    /* Set posfix LED. */
    Led_isPosfix(false);

    /* Restart GNSS. */
    if (Gnss.stop() != 0)
    {
      Serial.println("Gnss stop error!!");
      error_flag = 1;
    }
    else if (Gnss.end() != 0)
    {
      Serial.println("Gnss end error!!");
      error_flag = 1;
    }
    else
    {
      Serial.println("Gnss stop OK.");
    }

    if (Gnss.begin() != 0)
    {
      Serial.println("Gnss begin error!!");
      error_flag = 1;
    }
    else if (Gnss.start(HOT_START) != 0)
    {
      Serial.println("Gnss start error!!");
      error_flag = 1;
    }
    else
    {
      Serial.println("Gnss restart OK.");
    }

    LoopCount = 0;

    /* Set error LED. */
    if (error_flag == 1)
    {
      Led_isError(true);
      exit(0);
    }
  }
}

Morse Code

Arduino
int dotDelay = 200;
int led = PIN_LED0;

char* numbers[] = {"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "----."};

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  char longtitude;

  longtitude = 12345; /*Put your coordinates here*/ 
  
  if (longtitude >=  '0' && longtitude <= '9')
  {
    flashSequence(numbers[longtitude - '0']);
  }

}

void flashSequence(char* sequence)
{
  int i = 0;
  while (sequence[i] != '\0')
  {
    flashDotOrDash(sequence[i]);
    i++;
  }
  delay (dotDelay * 3);
}

void flashDotOrDash(char dotOrDash)
{
  digitalWrite(led, HIGH);
  if (dotOrDash == '.')
  {
    delay(dotDelay);
  }
  else
  {
    delay(dotDelay * 3);
  }
  digitalWrite(led, LOW);
  delay(dotDelay);
}

Credits

George Kartsonas

George Kartsonas

19 projects • 46 followers

Comments