0

Can't seem to send commands to my Ultimate GPS Feather
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Can't seem to send commands to my Ultimate GPS Feather

by steved0x on Tue Jan 22, 2019 10:37 am

I've got a project going with an M4 Express feather, Ultimate GPS featherwing, and a 128x32 OLED display. Right now it is just a digital speed that also displays the count of satellites being tracked.

My problem is that when I power up the device (USB) it doesn't seem to accept the commands that I send to the GPS, and so the GPS emits all the default sentences at 1 HZ. But if I press the reset button on the GPS Featherwing, it reboots everything?, and then it seems to accept the commands I send to the GPS in the setup method to set the desired sentences, fix rate, and refresh rate.

I have tried adding in delays between commands, I have tried updating the baud rate (when I do that i get garbage from the serial monitor until I press the reset button, then everything works)

I figure I am doing something in the wrong order, or some simple thing, but I have tried moving things around, but the commands in the setup routine to configure the GPS only seem to work after a reboot and not when power is first applied.

Note that I do not have a coin cell battery in the GPS featherwing, for my project I won't be using a battery. Right now my workaround is to just plug in the project and then press the reset button.

Any hot tips or ideas?

Thank you!

Here is my sketch:
Code: Select all | TOGGLE FULL SIZE
// Test code for Adafruit GPS modules using MTK3329/MTK3339 driver
//
// This code shows how to listen to the GPS module in an interrupt
// which allows the program to have more 'freedom' - just parse
// when a new NMEA sentence is available! Then access data when
// desired.
//
// Tested and works great with the Adafruit Ultimate GPS module
// using MTK33x9 chipset
//    ------> http://www.adafruit.com/products/746
// Pick one up today at the Adafruit electronics shop
// and help support open source hardware & software! -ada

#include <Adafruit_GPS.h>
//#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
// For OLED display
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMonoBold24pt7b.h>

#define SINGLE_DIGIT 103
#define DOUBLE_DIGIT 75
#define TRIPLE_DIGIT 47

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define GPSSerial Serial1

Adafruit_GPS GPS(&GPSSerial);

// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences.
#define GPSECHO  true

// Variables to hold the displayed items on the screen
int displayedSats;
int displayedSpeed;

void setup() 
{
  // 9600 NMEA is the default baud rate for Adafruit MTK GPS's- some use 4800
  // Connect at 9600 and send a command to the GPS to use PMTK_SET_BAUD_57600
 
  GPS.begin(9600);
  delay(100);
  /*
  // Experiment with increasing the baud rate
  // Although it all works at 9600, once I reboot the
  // unit after power is applied
  GPS.sendCommand(PMTK_SET_BAUD_57600);
  delay(100);
  GPSSerial.end();
  delay(100);
  GPS.begin(57600);
  //*/
 
  // Turn on RMC (recommended minimum) and GGA (fix data) including altitude
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  delay(100);
  // Set the fix rate and update rate
  GPS.sendCommand(PMTK_API_SET_FIX_CTL_5HZ); // 5Hz fix position rate
  delay(100);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ);   // 5 Hz update rate for NMEA sentence output

  delay(1000);
  // Ask for firmware version
  GPSSerial.println(PMTK_Q_RELEASE);

  // OLED 128x32 init
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Set the font
  display.setFont(&FreeMonoBold24pt7b);
 
  // Clear the display
  display.clearDisplay();
  display.display();
  display.setRotation(2); // My screen is mounted upside down

  // Serial for debugging
  Serial.begin(115200);
  Serial.println("Welcome to Speed display!");

  displayedSats = 0;
  displayedSpeed - 0;
}

uint32_t timer = millis();
void loop()                     // run over and over again
{
  // Read all available characters
  while(GPSSerial.available())
  {
    char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }
 
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences!
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
 
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }

  if(!GPS.fix)
  {
    // SAD 1/21/2019
    // Since we aren't reading GPS in an interrupt, only do this once a second
    // (or whatever interval I have specified below...)
    if (millis() - timer < 1000)
    {
      return;
    }
    // Reset the timer, AFTER we do the work

    // OLED
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setCursor(0,29);
    display.print("Fix");
    display.display();
    delay(250);
    display.println(".");
    display.display();
    // Reset the timer
    timer = millis();
    return;
  }

 

  // We have a fix
  double dspeed = GPS.speed * 1.15078;
  int speed = (int)dspeed;
 
  // Satellites
  int sats = (int)GPS.satellites;

  // If the speed or the sats are different than what is already
  // displayed, refresh the display
  if(sats != displayedSats || speed != displayedSpeed)
  {
    displayedSpeed = speed;
    displayedSats = sats;
    DrawOLED(speed, sats);
  }
}

void DrawOLED(int speed, int sats)
{
  // We always clear the screen when we draw the OLED
  display.clearDisplay();
  display.setTextColor(WHITE);

  // Set the x position based on the # of digits in our speed
  // Safety check...
  if(speed > 999)
  {
    speed = speed % 1000; // Could probably just run this line anyway
  }

  // Default to triple digit positioning
  int sx = TRIPLE_DIGIT;
  if(speed > 9 && speed < 100)
  {
    sx = DOUBLE_DIGIT;
  }
  else if(speed < 10)
  {
    sx = SINGLE_DIGIT;
  }

  // Set the cursor and write our speed
  display.setCursor(sx, 29);
  display.println(speed);

  // Draw the sats before doing display
  DrawSats(sats);

  // Write the display
  display.display();
}

void DrawSats(int sats)
{
  // We draw on the display as is
  // We are configured to draw on a 32 high display
  // We are going to draw 4 pixel blocks staggering to show the satellite count
  // like this
  // X X
  //  X
  // X X
  //  X

  // We can draw 4 per column
  // How many columns?
  int cols = sats / 4;
  if(sats % 4 > 0)
  {
    cols ++;
  }

  // Draw each column of sats
  for(int cc = 0; cc < cols; cc++)
  {
    // 4 sats per column
    for(int ss = 0; ss < 4; ss++)
    {
      // What is the current upper left pixel for this sat
      int sy = ss * 8;
      if(cc % 2 != 0)
      {
        sy += 4;
      }
       
      int sx = cc * 4;

      // Draw the sat
      DrawSat(sx, sy, 4);

      sats--;
      // once we get to zero sats, return;
      if(sats == 0)
      {
        return;
      }
    }
  }
}

void DrawSat(int x, int y, int sz)
{
  display.drawRect(x, y, sz, sz, WHITE);
}



Here is the output if I plug in the device and then attach the serial monitor, note the default NMEA sentences and the 1 HZ refresh rate.

Code: Select all | TOGGLE FULL SIZE
09:26:16.476 -> $GPGGA,235946.799,,,,,0,00,,,M,,M,,*70
09:26:16.510 -> $GPGSA,A,1,,,,,,,,,,,,,,,*1E
09:26:16.543 -> $GPGSV,1,1,00*79
09:26:16.543 -> $GPRMC,235946.799,V,,,,,0.00,0.00,050180,,,N*49
09:26:16.612 -> $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
09:26:17.598 -> $GPGGA,235947.799,,,,,0,00,,,M,,M,,*71
09:26:17.598 -> $GPGSA,A,1,,,,,,,,,,,,,,,*1E
09:26:17.598 -> $GPRMC,235947.799,V,,,,,0.00,0.00,050180,,,N*48
09:26:17.598 -> $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
09:26:18.449 -> $GPGGA,235948.799,,,,,0,00,,,M,,M,,*7E
09:26:18.516 -> $GPGSA,A,1,,,,,,,,,,,,,,,*1E
09:26:18.549 -> $GPRMC,235948.799,V,,,,,0.00,0.00,050180,,,N*47
09:26:18.583 -> $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
09:26:19.471 -> $GPGGA,235949.799,,,,,0,00,,,M,,M,,*7F
09:26:19.504 -> $GPGSA,A,1,,,,,,,,,,,,,,,*1E
09:26:19.538 -> $GPRMC,235949.799,V,,,,,0.00,0.00,050180,,,N*46
09:26:19.605 -> $GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32
09:26:20.456 -> $GPGGA,235950.800,,,,,0,00,,,M,,M,,*78
09:26:20.490 -> $GPGSA,A,1,,,,,,,,,,,,,,,*1E
09:26:20.524 -> $GPRMC,235950.800,V,,,,,0.00,0.00,050180,,,N*41


Here is the output if I plug in the device, and then press the reset button, and then attach the serial monitor:

Code: Select all | TOGGLE FULL SIZE
09:24:33.018 -> $GPGGA,142425.200,3011.0984,N,08238.2128,W,1,05,1.50,51.9,M,-31.0,M,,*65
09:24:33.086 -> $GPRMC,142425.200,A,3011.0984,N,08238.2128,W,0.35,118.12,220119,,,A*70
09:24:33.222 -> $GPGGA,142425.400,3011.0984,N,08238.2127,W,1,05,1.50,51.9,M,-31.0,M,,*6C
09:24:33.290 -> $GPRMC,142425.400,A,3011.0984,N,08238.2127,W,0.38,114.64,220119,,,A*79
09:24:33.427 -> $GPGGA,142425.600,3011.0984,N,08238.2127,W,1,05,1.50,51.9,M,-31.0,M,,*6E
09:24:33.495 -> $GPRMC,142425.600,A,3011.0984,N,08238.2127,W,0.41,112.83,220119,,,A*7A
09:24:33.598 -> $GPGGA,142425.800,3011.0984,N,08238.2127,W,1,05,1.50,51.9,M,-31.0,M,,*60
09:24:33.699 -> $GPRMC,142425.800,A,3011.0984,N,08238.2127,W,0.41,114.32,220119,,,A*78
09:24:33.800 -> $GPGGA,142426.000,3011.0984,N,08238.2127,W,1,05,1.50,51.9,M,-31.0,M,,*6B
09:24:33.886 -> $GPRMC,142426.000,A,3011.0984,N,08238.2127,W,0.42,114.86,220119,,,A*7F
09:24:34.006 -> $GPGGA,142426.200,3011.0984,N,08238.2126,W,1,05,1.50,51.9,M,-31.0,M,,*68
09:24:34.076 -> $GPRMC,142426.200,A,3011.0984,N,08238.2126,W,0.42,115.50,220119,,,A*76
09:24:34.210 -> $GPGGA,142426.400,3011.0984,N,08238.2126,W,1,05,1.50,51.9,M,-31.0,M,,*6E
09:24:34.277 -> $GPRMC,142426.400,A,3011.0984,N,08238.2126,W,0.41,116.50,220119,,,A*70
09:24:34.414 -> $GPGGA,142426.600,3011.0984,N,08238.2126,W,1,05,1.50,51.9,M,-31.0,M,,*6C
09:24:34.482 -> $GPRMC,142426.600,A,3011.0984,N,08238.2126,W,0.40,117.56,220119,,,A*74
09:24:34.618 -> $GPGGA,142426.800,3011.0983,N,08238.2126,W,1,05,1.50,51.9,M,-31.0,M,,*65
09:24:34.685 -> $GPRMC,142426.800,A,3011.0983,N,08238.2126,W,0.39,118.80,220119,,,A*77
09:24:34.820 -> $GPGGA,142427.000,3011.0983,N,08238.2126,W,1,05,1.50,51.9,M,-31.0,M,,*6C
09:24:34.887 -> $GPRMC,142427.000,A,3011.0983,N,08238.2126,W,0.37,120.41,220119,,,A*76
09:24:34.987 -> $GPGGA,142427.200,3011.0983,N,08238.2125,W,1,05,1.50,51.9,M,-31.0,M,,*6D
09:24:35.089 -> $GPRMC,142427.200,A,3011.0983,N,08238.2125,W,0.36,120.00,220119,,,A*73
09:24:35.222 -> $GPGGA,142427.400,3011.0983,N,08238.2125,W,1,05,1.50,51.9,M,-31.0,M,,*6B
09:24:35.291 -> $GPRMC,142427.400,A,3011.0983,N,08238.2125,W,0.34,119.85,220119,,,A*70
09:24:35.426 -> $GPGGA,142427.600,3011.0983,N,08238.2125,W,1,05,1.50,51.9,M,-31.0,M,,*69

steved0x
 
Posts: 3
Joined: Thu Dec 27, 2018 12:25 pm

Re: Can't seem to send commands to my Ultimate GPS Feather

by steved0x on Tue Jan 22, 2019 10:47 am

OK naturally I seem to have found another workaround just moments after posting this, I add a delay(1000); as the first line in my setup routine. That seems to work, maybe it gives the GPS chip time to do whatever cold startup routines it needs to do?

steved0x
 
Posts: 3
Joined: Thu Dec 27, 2018 12:25 pm

Re: Can't seem to send commands to my Ultimate GPS Feather

by adafruit_support_carter on Tue Jan 22, 2019 2:20 pm

That seems likely. That can also happen with the OLED, and we have a notice about that:
https://learn.adafruit.com/adafruit-ole ... ting#faq-1

The delay is a simple solution. If that works cool. If you want to get fancier, maybe you could add a query loop. A loop where you try and read from the GPS, and once that succeeds, then send it the configuration parameters and proceed with the rest of the sketch.

adafruit_support_carter
 
Posts: 12726
Joined: Tue Nov 29, 2016 2:45 pm

Re: Can't seem to send commands to my Ultimate GPS Feather

by steved0x on Tue Jan 22, 2019 2:25 pm

adafruit_support_carter wrote:That seems likely. That can also happen with the OLED, and we have a notice about that:
https://learn.adafruit.com/adafruit-ole ... ting#faq-1

The delay is a simple solution. If that works cool. If you want to get fancier, maybe you could add a query loop. A loop where you try and read from the GPS, and once that succeeds, then send it the configuration parameters and proceed with the rest of the sketch.


Great, thanks for this info. I'll experiment with decreasing the amount of my delay, but 1 second is still pretty short so I might leave it at that :)

Thank you,

Steve

steved0x
 
Posts: 3
Joined: Thu Dec 27, 2018 12:25 pm

Re: Can't seem to send commands to my Ultimate GPS Feather

by adafruit_support_carter on Tue Jan 22, 2019 2:28 pm

Sounds good. I'd keep it simple. If the simple delay is working for you, then I wouldn't try and get fancy.

adafruit_support_carter
 
Posts: 12726
Joined: Tue Nov 29, 2016 2:45 pm

Please be positive and constructive with your questions and comments.