How to set GPS module XM37-1612 to standby

I believe to have done my research, but I cannot get my GPS module (XM37-1612) to acknowledge my standby command. I have been measuring the voltage before and after executing the standby message, but do not notice any change in amperage. Should I anticipate a response or see the message printed in the Serial monitor? I don't think so, but want to make sure. Let me know if anyone sees anything wrong with my code. I would prefer to use TinyGPSPlus, but I don't think that's a requirement when using SoftwareSerial to submit the command.

#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>

TinyGPSPlus gps;
SoftwareSerial ss(34, 35);

void setup()
{
  Serial.begin(9600);

  ss.begin(9600);

  Serial.println("In GPS standby mode for 30 seconds...");
  ss.print("$PMTK161,0*28");
  delay(30000);
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  // If 5000 milliseconds pass and there are no characters coming in
  // over the software serial port, show a "No GPS detected" error
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println("No GPS detected");
    while(true);
  }
}

void displayInfo()
{
  if (gps.location.isValid())
  {
    Serial.print("Latitude: ");
    Serial.println(gps.location.lat(), 6);
    Serial.print("Longitude: ");
    Serial.println(gps.location.lng(), 6);
    Serial.print("Altitude: ");
    Serial.println(gps.altitude.meters());
  }
  else
  {
    Serial.println("Location: Not Available");
  }
  
  Serial.print("Date: ");
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print("/");
    Serial.print(gps.date.day());
    Serial.print("/");
    Serial.println(gps.date.year());
  }
  else
  {
    Serial.println("Not Available");
  }

  Serial.print("Time: ");
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(":");
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(":");
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(".");
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.println(gps.time.centisecond());
  }
  else
  {
    Serial.println("Not Available");
  }

  Serial.println();
  Serial.println();
  delay(1000);
}

Is that the command, all of it, that the GPS manual\datasheet tells you to send ?

Unfortunately, there are several manuals out there that say either that, or

unsigned char StandbyMode[] = {"$PMTK161,0*28\x0D\x0A"};

But yes, this is the only command.

I did just realize that I did not put it in a char array when I tried the second version I found which contained the carriage return/line feed in hex. I'm not as familiar with sending GPS module commands, but is that the standard, to send these messages this way? Regardless, I'll give that method a shot unless if you think it shouldn't matter.

Yes, the manual/datasheet is correct, the return/line feed is required.

And just to confirm, should it be sent like this?

unsigned char StandbyMode[] = {"$PMTK161,0*28\x0D\x0A"};

ss.print(StandbyMode);

I'll give it a go when I can today if so.

My code above was wrong. I can't figure out how to send specifically an unsigned char via ss.print();

I thought that the below could work since the hex is \r\n, but that did not work either. Thoughts?

ss.print("$PMTK161,0*28\r\n");

Nope.

But;

ss.println("$PMTK161,0*28");

Should work or;

ss.print("$PMTK161,0*28");
ss.write(13);
ss.write(10);

Should work as well.

Was the GPS bought from a trusted source ?

That didn't work for me either, but the issue could be that the module is not what it claims to be (as you're implying -- I've seen that happen a lot to folks on here). I purchased this one ages ago.

It claimed to be NEO-6M, but it looked identical to pictures of the unmarked XM37-1612 (see here: https://sandervandevelde.files.wordpress.com/2015/12/gps01.jpg). Is there a universal command that I can send to receive a response indicating the hardware/firmware version?

Then it would not respond to commands intended for a Mediatk GPS such as $PMTK161.

There are no 'universal' commands for configuring GPSs, they are manufacturer and sometimes model specific.

Damn. I figured since it looked identical to the picture I provided, that would be it. Any suggestions for determining the chip used without desoldering/lifting off the shield?

If it is actually Mediatek, any reason why it's not working? I would imagine that there is something you can send it determine what chipset it is.

Found an old email and it said that it is an XM37-1612 module. With that being said, what else could be wrong with my message or how I'm sending it?

The modules could be fakes, so may not accept proper configuration command.

You need to check the manual\datasheet to see what the response to the standby command should be and then monitor the characters output from the GPS.

Yeah, unfortunately I get zero response at all from either of my devices (let alone no GPTXT messages at startup). I also have a Beitian BN-180 (clearly a Chinese brand) allegedly with the M8030-KT, but uBlox U-Center cannot pull the version or interact correctly with it, other than pulling typical NMEA data. I'll try others and see if I can get proper communication with U-Center, and go from there.

I got my module to enter a lower power state in the above topic, in post 38 I provide a testing sketch using the Neogps library.

Hope it helps and you can reduce current.

Hi itmoto, I've been reading your threads for a while now. :slight_smile: I believe that yours is slightly different due to NeoGPS ignoring those other portions of the message. I can try that library instead, but I think I need to specify the pins separately in the header file, which is strange. Either way, the above you mentioned as well as several variants of the message haven't worked for me so far in TinyGPS. I'll look into NeoGPS again though. Thanks for weighing in!

Whilst it is true that you need delays, or more appropriatly wait for anf check the acknowledgement, between seperate configuration commands, the standby command stops the GPS, so a delay after the standby command serves no purpose.

It was quite a journey for me and still is!

No problem, sorry it hasn’t helped you in finding the answer, I remember the joy of getting mine to a lower current state and hope you get there too.

It was the only way I could get mine to work and it’s good to know that was just for the setup commands and not for standby, thanks.

There is a caveat to that, if your using software serial for the GPS AND you also use a lot of Serial prints to the standard (hardware) serial port, then the hardware Serial prints can interfere or corrupt the software serial coming from the GPS, the appropriate solutions for this are;

  1. Wait for and directly monitor the GPS output for the appropriate reply with no use of Serial prints.
  2. Use an ss.flush(); command after sending the configuration command to the GPS.

More details here;

The SX12XX library link in that article contains example programs for a LoRa based GPS high altitude balloon tracker which has configuration examples (including standby modes) for both Ublox and Quectel\Mediatek GPSs.