Go Down

Topic: GPS: set update frequency (Read 21204 times) previous topic - next topic

petterg


Quote
If I'm lucky my gps will understand the same commands.

I set mine using the touch screen. Your GPS chip is only one part of a GPS. It's a critical component, but not the only one.

I suspect that the walk/drive option is used to tell the GPS chip how often to report data. But, before you try to go there, I think it's important to understand whether the delay is in the time stamp or the time it takes to recognize that your position has changed. If the time stamp updates correctly, but the corresponding position data is not in sync, you have one problem. If the timestamps are incorrect, you have a different problem. Knowing which you have is crucial to solving it.


I thought you were having a gps chip for an arduino project. Sorry, my bad.

I totally see your idea for timestamp debug. Still waiting for the rain to stop as I don't want to fill my laptop with water for this test.

petterg

#76
Oct 22, 2013, 01:56 am Last Edit: Oct 22, 2013, 02:41 am by petterg Reason: 1
Finally a doc!
http://www.rigacci.org/wiki/lib/exe/fetch.php/doc/appunti/hardware/gps/mtk_nmea_packet_0.8_transystem.pdf

Probably not complete, and probably a bunch of commands this particular chip does not support, but its a doc!

Does anyone see a command in there that may be related to the driving vs walking position calculation that Michinyon and PaulS mention some posts ago?

Edit:
Seems to be a more complete version here:
https://www.olimex.com/Products/Modules/GPS/MOD-GPS/resources/MOD-GPS-MTK-NMEA.pdf

petterg

I'm trying to make the gps respond to the PMTK messages as listed in the doc, but I cant find any PMTK_ACK from the gps, and it's output doesn't change either.

Here's the code I'm using:
Code: [Select]

#include <TinyGPS++.h>

static const int GPSBaud = 9600;
int i = 0;
char parity = 0;
bool pmtkend = true;

// The TinyGPS++ object
TinyGPSPlus gps;

//Testmessage
  char *cmd1 = "PMTK000*";
//Enable/disable outputs
  char *cmd2 = "PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*";

void setup()
{
  Serial.begin(115200);
  Serial1.begin(GPSBaud);
delay(10000);
  Serial.println(F("GPS config"));
  Serial.println();
  while (*cmd1) sendPMTK(*cmd1++);
  while (*cmd2) sendPMTK(*cmd2++);
  Serial.println(F("/GPS config"));
}

void loop()
{
  while (Serial1.available() > 0 && i < 50000) {
    i++;
    Serial.print((char)Serial1.read());
  }
}

void sendPMTK(char c)
{
  if(pmtkend)
  {
    pmtkend = false;
    Serial1.print('$');
  }
 
  Serial1.print(c);
 
  if(c == '*')
  {
    Serial1.println(parity);
//    Serial1.print('\r');
//    Serial1.print('\n');
    parity = 0;
    pmtkend = true;
  }
  else
  {
    parity ^= c;
   
  }
}

void displayInfo()
{
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

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

  Serial.println();
}


Does anyone see any problems with the code?
(Changing "Serial1" to "Serial" in function sendPMTK makes the sent messages look correctly on computer)

petterg

I've gotten a tiny bit further on this: I found a forum where a guy starts a thread asking if anyone knows how to enable GLL messages from the SKM53. The thread ends with him telling he solved the problem - not telling how. At least then I know the chip accepts incoming commands.
(I've posted in the thread and sent pm to the guy, without any reply.)

I've also realized that if I walk really slowly, I can walk almost 30m without any change in the position output from the gps.
Also, if I put the gps in a car with a videocamera that records both the pc monitor and showing where I drive, the position output is just a second or so behind. This I think would confirm that there is a "car-mode" enabled in the chip.
(I did these tests running an arduino code that just outputs anything from the Serial1 buffer to Serial.)

I guess the only way to get going on this project is to figure out what kind of commands the SKM53 accepts.

petterg

Today I finally learned something! Even two things.

1) Using a Due (84MHz) is a major improvement over ProMicro (16MHz) when it comes to position delay. Even when not using any library - just passing the serial data directly trough to the pc.
Based on the information that has come out from this thread I have no idea why. Could it be that the gps is powered by 3,3V rather than 5V? Could there be some kind of buffer in the GPS that buffers position data, but not time? If so, why would the MPU speed have any effect on this as long as the baud rate is identical?

2) PMTK-messages work for configuring the skm53  - if checksum is sent correctly.
Say if the checksum is 0b 0100 1101 (4D) I sent those exact bits, but I should have sent 0b 0011 0100 0100 0100 (That is ascii '4' followed by ascii 'D'). After this discovery configuration seems to work with ProMicro, but not with Due - probably it's serial input requires 5V. (I'm surprised that it works on 3,3V at all.)

lar3ry

#80
Nov 18, 2013, 05:23 am Last Edit: Nov 18, 2013, 05:25 am by lar3ry Reason: 1
For some reason, I missed this thread. Here's a little thing I whipped up to configure my SKM53. NOte the usage in the first comment, which tells you that you enter the line from $ to *, inclusive. The checksum will be calculated for you.

Code: [Select]

/*
Enter a packet starting with $PMTK, and ending with a *
In this sketch the * indicates the end of transmission.
The sketch takes the packet, adds a checksum and sends it to
the GPS.

Note: If you change the baud rate of the GPS, you will have to
close the Serial monitor, change the baud rate in Serial1
(or whatever Serial port you use) and restart it.

Set your Serial Monitor to No Line Endings. The sketch supplies those too,
and if you send them, they will get you out of sync.

This sketch assumes you are running an Arduino Mega2560, and
have a serial GPS on Serial1. Change this to suit your own
configuration. (Software Serial for Uno, etc.)

One packet type not mentioned in the document at
http://api.ning.com/files/L30xp1HTxtEUhhmBj4yYWIB31IDKs*xJNecJYvcEKZofuHJcZ3wnTMuZL5FeJC535I6DJbBZZE7FpJwnQPxgT9yKLCibZaZj/NMEA_Packet_Userl.pdf
is packet type 220. Here are a couple of samples, as you
would enter them into the Serial Monitor

$PMTK220,200*
$PMTK220,500*
$PMTK220,1000*
$PMTK220,2000*

These will set the reporting interval to 200, 500, 1000,
and 2000 milliseconds, or 5, 2, 1, .5 Hz,  respectively.
*/

char sentence[80];
int idx = 0;

void setup() {
 // initialize both serial ports:
 Serial.begin(57600);
 Serial1.begin(9600);
}

void loop() {
 // read from Serial1, send to Serial:
 if (Serial1.available()) {
   Serial.write(Serial1.read());
 }

 if (Serial.available())  {
   char inbyte = Serial.read();
   sentence[idx++] = inbyte;
   sentence[idx] = 0;
   if (inbyte == '*') {
     for (int i=0; i < strlen(sentence); i++) {
       Serial.print(sentence[i]);
     }
     Serial.println();
     sendConfig ();
     sentence[0] = 0;
     idx = 0;
   }
 }
}

void sendConfig () {
 unsigned char CS = 0;
 for (int i=1; i< strlen(sentence)-1; i++) {
   CS ^= sentence[i];
 }
 Serial1.print(sentence);
 if (CS < 10) Serial1.print("0");
 Serial1.print(CS,HEX);
 Serial1.println();
}

petterg

Thank you for that information on 220. Your code is much like the one I got working yesterday.

lar3ry

I wonder if youe slowness has anything to do with the library. I often take a critical look at what a library is doing for me, and sometimes find that there is only a small part of it I need. In those cases, I will sometimes write my own routine, or grab a chunk of code out of the library, and modify it.

If I get a chance later today, and if it warms up a bit, I'll try the walking experiment to see how far I have to walk to get a change.

I did check to see if it would go faster than 5 Hz, and yes, I managed to get it to 10Hz for sure, and I think it went o 20 Hz, but I couldn't be sure.

petterg

I would appreciate very much to know if you experience the same.

I can't blame the library as there is delay even when I forward the raw gps messages to pc.
There were significantly less delay when using the Due (3,3V/84MHz) than when using the ProMicro (5V/16MHz). I haven't got to test the effect of custom configuration of the gps, as when I finally got it to respond to the PMTK messages, it had started to rain, and it's been raining ever since.

I hope the delay will be minor after combining 220, 300, 301, 313 and 314-messages in some way., and make a vlotage shifter so config can be done from the Due.

lar3ry

I tried to do the walking experiment, with the Arduino attached to my laptop. But it's dark, cold, and we have about 20 cm. of snow on the ground. It did seem to lag some, but I'll try again tomorrow, when I have time. I did a few calculations, and at my latitude, the fourth decimal place in latitude represents about 18.5 cm, and in longitude, about 12 cm.

Go Up