4
\$\begingroup\$

I bought a SKM53 GPS module a few months ago. I tried hard to make it work but couldn't get anything out of it. I was thinking it's a fault with the device (actually i thought i burned it by not properly giving the supply). So I didn't think much and ordered another one (here).

I received the second module (same, SKM53) today. Well.. something is not right, it behaves exactly as the previous one! I'm not familiar with the module, but thought that was something easy to use. I tested with the example sketch "simple_test" that comes with the arduino core library, TinyGPS (see below). When observing the serial monitor, all values are zero. Also, the seemingly LED (i assumed), next to '1206' (see image), is not lighting..

enter image description here

Does all that mean the module is not working? Hoping not, what can I do to make it work?(I tested on a open ground where the sky is clearly visible.)

Sketch (simple_test)

#include <SoftwareSerial.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 10(rx) and 11(tx).
*/

TinyGPS gps;
SoftwareSerial ss(10, 11);

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

  Serial.print("Simple TinyGPS library v. "); 
  Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
}

void loop()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);
    Serial.print("LAT=");
    Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
    Serial.print(" LON=");
    Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
    Serial.print(" SAT=");
    Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
    Serial.print(" PREC=");
    Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
  }

  gps.stats(&chars, &sentences, &failed);
  Serial.print(" CHARS=");
  Serial.print(chars);
  Serial.print(" SENTENCES=");
  Serial.print(sentences);
  Serial.print(" CSUM ERR=");
  Serial.println(failed);
}

Observed output

Simple TinyGPS library v. 12
by Mikal Hart

 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0
 CHARS=0 SENTENCES=0 CSUM ERR=0

EDIT

This is the working code I used, by editing an example that comes with TinyGPS lib. Uses hardware serial, USART1, instead of software serial.

#include <SoftwareSerial.h>

#include <TinyGPS.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
 It requires the use of SoftwareSerial, and assumes that you have a
 4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
 */

TinyGPS gps;

static void gpsdump(TinyGPS &gps);
static bool feedgps();
static void print_float(float val, float invalid, int len, int prec);
static void print_int(unsigned long val, unsigned long invalid, int len);
static void print_date(TinyGPS &gps);
static void print_str(const char *str, int len);

void setup()
{
  Serial1.begin(9600);     //GPS module is connected to USART1
  Serial.begin(9600);

  Serial.print("Testing TinyGPS library v. "); 
  Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
  Serial.print("Sizeof(gpsobject) = "); 
  Serial.println(sizeof(TinyGPS));
  Serial.println();
  Serial.println("Sats HDOP Latitude Longitude Fix  Date       Time       Date Alt     Course Speed Card  Distance Course Card  Chars Sentences Checksum");
  Serial.println("          (deg)    (deg)     Age                        Age  (m)     --- from GPS ----  ---- to London  ----  RX    RX        Fail");
  Serial.println("--------------------------------------------------------------------------------------------------------------------------------------");
}

void loop()
{
  bool newdata = false;
  unsigned long start = millis();

  // Every second we print an update
  while (millis() - start < 1000)
  {
    if (feedgps())
      newdata = true;
  }
  gpsdump(gps);
}

static void gpsdump(TinyGPS &gps)
{
  float flat, flon;
  unsigned long age, date, time, chars = 0;
  unsigned short sentences = 0, failed = 0;
  static const float LONDON_LAT = 51.508131, LONDON_LON = -0.128002;

  print_int(gps.satellites(), TinyGPS::GPS_INVALID_SATELLITES, 5);
  print_int(gps.hdop(), TinyGPS::GPS_INVALID_HDOP, 5);
  gps.f_get_position(&flat, &flon, &age);
  print_float(flat, TinyGPS::GPS_INVALID_F_ANGLE, 9, 5);
  print_float(flon, TinyGPS::GPS_INVALID_F_ANGLE, 10, 5);
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);

  print_date(gps);

  print_float(gps.f_altitude(), TinyGPS::GPS_INVALID_F_ALTITUDE, 8, 2);
  print_float(gps.f_course(), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_float(gps.f_speed_kmph(), TinyGPS::GPS_INVALID_F_SPEED, 6, 2);
  print_str(gps.f_course() == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(gps.f_course()), 6);
  print_int(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0UL : (unsigned long)TinyGPS::distance_between(flat, flon, LONDON_LAT, LONDON_LON) / 1000, 0xFFFFFFFF, 9);
  print_float(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : TinyGPS::course_to(flat, flon, 51.508131, -0.128002), TinyGPS::GPS_INVALID_F_ANGLE, 7, 2);
  print_str(flat == TinyGPS::GPS_INVALID_F_ANGLE ? "*** " : TinyGPS::cardinal(TinyGPS::course_to(flat, flon, LONDON_LAT, LONDON_LON)), 6);

  gps.stats(&chars, &sentences, &failed);
  print_int(chars, 0xFFFFFFFF, 6);
  print_int(sentences, 0xFFFFFFFF, 10);
  print_int(failed, 0xFFFFFFFF, 9);
  Serial.println();
}

static void print_int(unsigned long val, unsigned long invalid, int len)
{
  char sz[32];
  if (val == invalid)
    strcpy(sz, "*******");
  else
    sprintf(sz, "%ld", val);
  sz[len] = 0;
  for (int i=strlen(sz); i<len; ++i)
    sz[i] = ' ';
  if (len > 0) 
    sz[len-1] = ' ';
  Serial.print(sz);
  feedgps();
}

static void print_float(float val, float invalid, int len, int prec)
{
  char sz[32];
  if (val == invalid)
  {
    strcpy(sz, "*******");
    sz[len] = 0;
    if (len > 0) 
      sz[len-1] = ' ';
    for (int i=7; i<len; ++i)
      sz[i] = ' ';
    Serial.print(sz);
  }
  else
  {
    Serial.print(val, prec);
    int vi = abs((int)val);
    int flen = prec + (val < 0.0 ? 2 : 1);
    flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
    for (int i=flen; i<len; ++i)
      Serial.print(" ");
  }
  feedgps();
}

static void print_date(TinyGPS &gps)
{
  int year;
  byte month, day, hour, minute, second, hundredths;
  unsigned long age;
  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  if (age == TinyGPS::GPS_INVALID_AGE)
    Serial.print("*******    *******    ");
  else
  {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d   ",month, day, year, hour, minute, second);
    Serial.print(sz);
  }
  print_int(age, TinyGPS::GPS_INVALID_AGE, 5);
  feedgps();
}

static void print_str(const char *str, int len)
{
  int slen = strlen(str);
  for (int i=0; i<len; ++i)
    Serial.print(i<slen ? str[i] : ' ');
  feedgps();
}

static bool feedgps()
{
  while(Serial1.available()>0)
  {
    char c= Serial1.read();
    if (gps.encode(c))
      return true;
  }
  return false;
}
\$\endgroup\$
  • 1
    \$\begingroup\$ What Arduino type do you use? arduino.cc/en/Reference/SoftwareSerial Look at limitations. \$\endgroup\$ – jippie Jan 5 '13 at 14:47
  • 2
    \$\begingroup\$ When you power it up, do you see periodic messages on the TX line? Many GPS devices are configured to automatically send out messages once powered on. \$\endgroup\$ – kenny Jan 5 '13 at 15:43
  • 1
    \$\begingroup\$ Look at TXD and RXD with a voltmeter, are they usually High at 5V? \$\endgroup\$ – Gustavo Litovsky Jan 5 '13 at 16:54
  • 3
    \$\begingroup\$ It should be sending NMEA on TX line. Perhaps you switched between the two? They are usually cross connected (TX to RX of uC and RX to TX of uC) \$\endgroup\$ – Gustavo Litovsky Jan 5 '13 at 17:11
  • 1
    \$\begingroup\$ Update the sketch in your question accordingly, as @GustavoLitovsky suggests, check TX/RX order. A picture can still be helpful. \$\endgroup\$ – jippie Jan 5 '13 at 17:14
1
\$\begingroup\$

First you'd better update the IDE to a latest version (if you haven't already done). There are some bugs in previous IDEs.

As you are using Arduino mega, you have to check the SoftwareSerial library docs and figure out what pins can be used in Mega. As mentioned in one of the comments, there are some limitations in the lib. (you won't be able to directly use the examples that comes with the IDE as they use D2, D3 pins which are not supported in Mega)

However, there are many USART modules in Mega. Why not use hardware serial instead of using virtual ones?

\$\endgroup\$
1
\$\begingroup\$

I had the same problem with that module. This can be useful.

\$\endgroup\$
  • \$\begingroup\$ I've followed that before. However I've figured out the issue. The problem was with the SoftwareSerial library, as some people suggested above, it doesn't support some of the pins of Arduino Mega. After changing the Tx pin to 10, it worked. Thanks for the support anyway! \$\endgroup\$ – Anubis Jan 7 '13 at 8:04
1
\$\begingroup\$

Try to use baudrate 9600. I made it work, but with some limitations. It drops randomly some parts of the sentences (maybe because of the SoftwareSerial/NewSoftwareSerial I'm using. Increasing the buffer size of SoftwareSerial doesn't seem to help).

\$\endgroup\$
  • \$\begingroup\$ Thanks for the answer. The problem is already solved. The issue was that i wasn't using correct pins with Arduino Mega. The module is working perfectly now. However, as Arduino mega got several hardware serial modules, i'm using one of them with the module. I guess what you are using software serial with some heavy code. If you don't read the module fast enough, you may loose some of the incoming bytes.. \$\endgroup\$ – Anubis Feb 1 '13 at 14:43
0
\$\begingroup\$

I found this post very helpful, may be you too. http://hotresistor.blogspot.com/2014/11/arduino-interfacing-with-gps-tutorial.html

\$\endgroup\$
  • 1
    \$\begingroup\$ Can you edit a few more details from that link into your answer? Link-only answers are discouraged because they can become useless in the future if the link dies. \$\endgroup\$ – PeterJ Nov 30 '14 at 11:22
0
\$\begingroup\$

Try powering the GPS with external voltage regulator using the configuration from the following link http://competefornothing.com/l7805-voltage-regulator-for-arduino-5v-1amp/

\$\endgroup\$
  • \$\begingroup\$ Can you edit a few more details from that link into your answer? Link-only answers are discouraged because they can become useless in the future if the link dies. \$\endgroup\$ – PeterJ Dec 5 '14 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.