GPS Status Stuck on "GPS waiting to start {gps-starting} {gps-active}"

Hey All!

I am trying to transmit events from my blues starter kit in order to access the location of it at all times. When I check out the events in notehub however it doesn’t use the GPS location, even though I’ve attached the antenna to the notecard. When I check out my event and click on the map, the GPS location is not available and the best location comes from triangulation using cell towers which isn’t very accurate.

After doing some digging I found that this log is constantly being printed out:
{"status":"GPS waiting to start {gps-starting} {gps-active}","mode":"periodic"}

For some reason, my GPS can’t seem to get started.

  • I’ve tried staying outside for 20 minutes
  • I’ve made sure the dip switch is on PASSIVE
  • I’ve made sure I’ve connected the antenna correctly

I would appreciate any support on why this is happening, I’ve attached my code here that I’ve uploaded to the swan. I also include fall detection and that works just fine here.

#include <Wire.h>
#include <Notecard.h>

Notecard notecard;

void setup() {
  delay(3000);        
  Serial.begin(115200); 

  Wire.begin(); 

  notecard.begin();

  notecard.setDebugOutputStream(Serial);

  {
    J *req = notecard.newRequest("hub.set");
    if (req) {
      JAddStringToObject(req, "product", "REDACTED");
      JAddStringToObject(req, "mode", "continuous");
      notecard.sendRequest(req);
    }
  }

  {
    J *req = notecard.newRequest("card.location.mode");
    if (req) {
      JAddStringToObject(req, "mode", "continuous");
      JAddStringToObject(req, "start", "now");
      JAddBoolToObject(req, "gps", true);
      notecard.sendRequest(req);
    }
  }

  {
    J *req = notecard.newRequest("card.location.track");
    if(req){
      JAddBoolToObject(req, "start", true);
      JAddBoolToObject(req, "heartbeat", true);
      JAddIntToObject(req, "hours", 12);
    }
  }
  {
    J *req = notecard.newRequest("card.motion.mode");
    if (req) {
      JAddBoolToObject(req, "start", true);
      JAddNumberToObject(req, "sensitivity", 2);
      notecard.sendRequest(req);
    }
  }
}

void loop() {
  {
    double lat=0, lon=0;
    bool valid = false;

    J *req = notecard.newRequest("card.location");
    if (req) {
      JAddNumberToObject(req, "hours", 1);
      J *rsp = notecard.requestAndResponse(req);
      if (rsp) {
        lat = JGetNumber(rsp, "lat");
        lon = JGetNumber(rsp, "lon");
        valid = JGetBool(rsp, "valid");
        notecard.deleteResponse(rsp);
      }
    }

    J *noteReq = notecard.newRequest("note.add");
    if (noteReq) {
      JAddStringToObject(noteReq, "file", "track.qo");
      JAddBoolToObject(noteReq, "sync", true);

      J *body = JAddObjectToObject(noteReq, "body");
      if (body) {
        if (valid) {
          JAddNumberToObject(body, "lat", lat);
          JAddNumberToObject(body, "lon", lon);
        } else {
          JAddStringToObject(body, "location", "invalid");
        }
      }
      notecard.sendRequest(noteReq);
    }
  }

  {
    J *mreq = notecard.newRequest("card.motion");
    if (mreq) {
      JAddNumberToObject(mreq, "minutes", 1); 
      J *mrsp = notecard.requestAndResponse(mreq);
      if (mrsp) {
        bool alert = JGetBool(mrsp, "alert");  
        if (alert) {
          Serial.println("Fall (free-fall) detected!");
          J *fallReq = notecard.newRequest("note.add");
          if (fallReq) {
            JAddStringToObject(fallReq, "file", "track.qo");
            JAddBoolToObject(fallReq, "sync", true);
            J *body = JAddObjectToObject(fallReq, "body");
            if (body) {
              JAddStringToObject(body, "event", "FALL_DETECTED");
            }
            notecard.sendRequest(fallReq);
          }
        }
        notecard.deleteResponse(mrsp);
      }
    }
  }

  delay(15000);
}

Hi @haalawie,

It looks like you are trying to put the GPS into continuous in your setup() function. Unfortunately the Notecard does not support both a continuous cellular connection {"req":"hub.set", "mode":"continuous"} and continuous GPS {"req":"card.location.mode", "mode":"continuous"}. Here’s a link to our docs explaining that this isn’t possible. You should see an error being returned by the Notecard if you examine the response after your card.location.mode command is sent in your setup().

To get around this, you can set the card.location.mode to periodic, with a value for seconds greater than 300 (5 minutes), which should sample the GPS infrequently enough to allow the modem to switch between cellular and GPS, as well as get a fix for the GPS.

If you require the GPS to run continuously alongside a continuous cellular connection, you’ll need to use an external GPS. This is because the modem used by the Notecard handles both the GPS and cellular connection; it cannot perform both simultaneously and must switch between them.

I’ve also noticed that you’re adding key/value pair “hours”:1 to the card.location request in your loop(), this isn’t a valid parameter for the card.location command. What behaviour are you hoping to achieve?

Thanks,
Alex

1 Like

Thank you for your help. I ended up removing the fall detection for now so that I can isolate the GPS issue, I’ve taken your advice and I’m now using a periodic location mode.

#include <Arduino.h>
#include <Notecard.h>
#include <Wire.h>

Notecard notecard;

#define PRODUCT_UID "REDACTED SINCE SHARING"

long previousMillis = 0;
long interval = 60000 * 10;  // 10 minutes
void setup() {
Serial.begin(115200);
while (!Serial) {
; // Wait for USB connection
}

notecard.setDebugOutputStream(Serial);
notecard.begin();

{
   J *req = notecard.newRequest("hub.set");
   if (req) {
     JAddStringToObject(req, "product", PRODUCT_UID);
     JAddStringToObject(req, "mode", "periodic");
     JAddNumberToObject(req, "outbound", 1); // 1 minute
     JAddNumberToObject(req, "inbound", 1);
     notecard.sendRequest(req);
   }
}

{
   J *req = notecard.newRequest("card.location.mode");
   if (req) {
     JAddStringToObject(req, "mode", "periodic");
     JAddNumberToObject(req, "seconds", 300); // 5-minute interval
     JAddBoolToObject(req, "gps", true);      // Enable GPS
     notecard.sendRequest(req);
   }
}

{
   J *req = notecard.newRequest("card.location.track");
   if (req) {
     JAddBoolToObject(req, "start", true);
     JAddBoolToObject(req, "sync", true);
     notecard.sendRequest(req);
   }
}

Serial.println("Notecard configured. Will try sending GPS data every 5 minutes.");
}

void loop()
{
unsigned long currentMillis = millis();

if ((currentMillis - previousMillis > interval)) {
   previousMillis = currentMillis;

   J *req = notecard.newRequest("note.add");
   if (req != NULL) {
     JAddStringToObject(req, "file", "sensors.qo");

     J *body = JCreateObject();
     if (body != NULL) {
       JAddNumberToObject(body, "temp", 1);
       JAddItemToObject(req, "body", body);
     }

     notecard.sendRequest(req);
   }
}
}

I tried uploading the updated code and I am still unable to access the GPS location on the emitted events.

I see events with the body {“temp”: 1} being sent to notehub every 10 minutes and I let it run for 40 minutes near a window, but no GPS location.

Any advice would be really appreciated

Hi @haalawie,

The two values you are using are still too low to make consistent use of both cellular and GPS. With a 1 minute periodic cellular connection, you’re basically never allowing GPS to activate (it can take 5-20 seconds just to establish a cellular connection).

Also with a periodic 300 second interval on GPS, that’s still effectively in continuous mode, again due to the amount of time it takes to identify satellites and ascertain location. So you still have cell and GPS competing with each other.

You have to decide if it’s more important to:

  1. More frequently sync data over cellular (and gather location less frequently)
  2. More frequently gather/save GPS location data (and send it to the cloud less frequently). There is a lot of flash storage on the Notecard, so this is a very valid option.

I would set AT LEAST a 15 minute periodic gap for whichever one you need less frequently.

Alternatively, add an external GPS module and all your problems are solved :slight_smile:

Thanks,
Rob

Hey @RobLauer Thank you for your help!

I just uploaded this code following your advice and I still can’t seem to get a satellite connection after walking outside for 20 minutes (Is that not sufficient? If so what would be?)

#include <Arduino.h>
#include <Notecard.h>
#include <Wire.h>

Notecard notecard;

#define PRODUCT_UID "REDACTED SINCE SHARING"

long previousMillis = 0;
long interval = 60000 * 10;  // 10 minutes (interval for note.add, can keep this or increase as needed)

void setup() {
    Serial.begin(115200);
    while (!Serial) {
        ; // Wait for USB connection
    }

    notecard.setDebugOutputStream(Serial);
    notecard.begin();

    // Set periodic cellular sync to every 15 minutes (less frequently)
    J *req = notecard.newRequest("hub.set");
    if (req) {
        JAddStringToObject(req, "product", PRODUCT_UID);
        JAddStringToObject(req, "mode", "periodic");
        JAddNumberToObject(req, "outbound", 15); // 15 minutes interval for cellular sync
        JAddNumberToObject(req, "inbound", 15);
        notecard.sendRequest(req);
    }

    // Set GPS to periodic every 10 minutes (allows plenty of time for fix)
    req = notecard.newRequest("card.location.mode");
    if (req) {
        JAddStringToObject(req, "mode", "periodic");
        JAddNumberToObject(req, "seconds", 600); // 10 minutes interval for GPS fix
        JAddBoolToObject(req, "gps", true);      // Enable GPS
        notecard.sendRequest(req);
    }

    // Enable location tracking
    req = notecard.newRequest("card.location.track");
    if (req) {
        JAddBoolToObject(req, "start", true);
        JAddBoolToObject(req, "sync", true);
        notecard.sendRequest(req);
    }

    Serial.println("Notecard configured. GPS data every 10 min, cellular sync every 15 min.");
}

void loop() {
    unsigned long currentMillis = millis();

    if ((currentMillis - previousMillis > interval)) {
        previousMillis = currentMillis;

        J *req = notecard.newRequest("note.add");
        if (req != NULL) {
            JAddStringToObject(req, "file", "sensors.qo");

            J *body = JCreateObject();
            if (body != NULL) {
                JAddNumberToObject(body, "temp", 1);
                JAddItemToObject(req, "body", body);
            }

            notecard.sendRequest(req);
        }
    }
}

I’m not sure what’ is the issue with this code now, but I see this event got emitted with “status”: “no-sat”

{
“jcount”: 5,
“journey”: 1742407940,
“motion”: 615,
“seconds”: 90,
“status”: “no-sat”,
“temperature”: 24.125,
“voltage”: 4.8320312
}

Hi @haalawie,

The no-sat code means the Notecard is not seeing any GPS/GNSS satellites. Please check out our guide on diagnosing GPS issues and let me know if any of those help!

Rob

I decided to use an external GPS since it should be easier :')

After 15 minutes, I’m still unable to see the GPS location, and I see the following logs:

[INFO] {"req":"card.location","crc":"0023:F0AE3444"}
[INFO] {"status":"GPS inactive {gps-inactive}","mode":"periodic"}
[INFO] {"req":"note.add","file":"track.qo","sync":true,"body":{"temp":1},"crc":"0024:A6644DB2"}
[INFO] {"total":1}

I’ve attached my code here:

#include <Notecard.h>
#include <Wire.h>

#define usbSerial Serial
#define txRxPinsSerial Serial1
#define productUID "REDACTED"

#define IIC_ADDR  uint8_t(0x76)

Notecard notecard;

long previousMillis = 0;
long interval = 6000 * 10;

void setup()
{
  usbSerial.begin(115200);

  notecard.setDebugOutputStream(usbSerial);
  notecard.begin();

  J *req = notecard.newRequest("hub.set");
  JAddStringToObject(req, "product", productUID);
  JAddStringToObject(req, "mode", "periodic");
  JAddNumberToObject(req, "outbound", 60);
  JAddNumberToObject(req, "inbound", 720);
  notecard.sendRequest(req);

  req = notecard.newRequest("card.aux.serial");
  JAddStringToObject(req, "mode", "gps");
  notecard.sendRequest(req);

  req = notecard.newRequest("card.location.mode");
  JAddStringToObject(req, "mode", "periodic");
  JAddNumberToObject(req, "seconds", 3600);
  notecard.sendRequest(req);

  req = notecard.newRequest("card.location.track");
  JAddBoolToObject(req, "sync", true);
  JAddBoolToObject(req, "heartbeat", true);
  JAddNumberToObject(req, "hours", 12);
  notecard.sendRequest(req);

  req = notecard.newRequest("card.motion.mode");
  JAddBoolToObject(req, "start", true);
  notecard.sendRequest(req);
  Serial.println("Setup Complete");
}

void loop()
{
  double lat=0, lon=0;
  unsigned long currentMillis = millis();
  if (currentMillis % 10000 == 0){
    Serial.println(currentMillis);
    Serial.println(previousMillis);
  }
  if ((currentMillis - previousMillis > interval)) {
    previousMillis = currentMillis;

  J *req = notecard.newRequest("card.location");
      if (req) {
        J *rsp = notecard.requestAndResponse(req);
        if (rsp) {
          lat = JGetNumber(rsp, "lat");
          lon = JGetNumber(rsp, "lon");
          notecard.deleteResponse(rsp);
        }
      }

    req = notecard.newRequest("note.add");
    if (req != NULL) {
      JAddStringToObject(req, "file", "track.qo");
      JAddBoolToObject(req, "sync", true);
      J *body = JCreateObject();
      if (body != NULL) {
        JAddNumberToObject(body, "temp", 1);

        JAddItemToObject(req, "body", body);
      }

      notecard.sendRequest(req);
    }
  }
}

Here are some pictures to show the wiring:



I am right beside a window, I am not sure how to approach solving this.

Hi @haalawie,

You’ve joined many of us who grew tired of trying to get cellular to compete with GPS :slight_smile:.

A couple of notes:

  1. You’re using card.location.track AND manually creating “tracking” Notes with note.add. I would choose one or the other. Your entire loop is effectively recreating what can be done with card.location.track alone. I would start by literally using what TJ put together in his blog post here.
  2. Even having a view outside a window is often not enough to get a GPS signal. I’ve found you literally have to be outside with a clear view of the sky (or be able to run your GPS module/antenna outdoors). Very hard to develop/test with GPS!

Rob