Pages: [1] 2   Go Down
Author Topic: simplest gps clock  (Read 1946 times)
0 Members and 1 Guest are viewing this topic.
Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have searched and found loads of projects with clocks using a gps module, but some have RTC chips too, and some seem very complicated.

What I want to try is ( in its simplest form where the clock can be mounted by a window or wherever there is gps signal ) have a Arduino 328 chip, running a simple 4 digit LED clock.

The display will be latched using TPIC6B595 shift reg drivers.  There are no multiplexing delays in the loop, the display is refreshed once per minute.

The general timing of the minute could be a simple " blink without delay"  millis check to see if the count has reached 60 seconds.

A cheap gps module that churns out NMEA strings , via ttl connections to the Arduino chip UART from which I could mask out the hours and minutes digits.

If the signal lock is high, and there is a change in the ten minutes digit, it must update the display counter of the Arduino chip.

( I suppose I could  get fancy and check the error first to correct the millis counter to fine tune the error )

The next step would be to have the gps module in the window, sending the time every 10 minutes via a rf link to the clock, or clocks across the room, but I just want to start somewhere.

If I wanted to start really simple, I could just mask out the minutes and hours numbers from the NMEA string, updated every second, and send them to the LED displays via a lookup table, and not bother with a timer at all in the micro?

Has anyone played with this?


Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 201
Posts: 8697
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've done parsing of a NEMA message.  In my case I wanted Lat, Lon, and Altitude.  Perhaps my code can be used as a model.

Code:

#include <NewSoftSerial.h>

//  Fault flags
extern const unsigned int GPS_fault;
extern unsigned int Faults;

NewSoftSerial GPS(2, -1);

// Parse GPS message
byte GPS_byteCount = 0;
unsigned char GPS_buff[100];
unsigned long GPS_time = 0;
String GPS_lat = "";
String GPS_long = "";
String GPS_altitude = "";
unsigned long GPS_lastgood = 0;
unsigned long GPS_lasttest = 0;


void GPS_setup(void)
{
  GPS.begin(4800);
}


void GPS_loop(void)
{
  // If any characters are available from the GPS, send them to the parser
  while (GPS.available())
  {
    GPS_parse_char(GPS.read());
  }

  // Check for GPS status
  if ((millis() - GPS_lastgood > 3000))
    Faults |= GPS_fault;   
}

void GPS_log(Print &dest)
{
  // Log GPS data
  dest.print(GPS_time, DEC);
  dest.print(',');
  dest.print(GPS_lat);
  dest.print(',');
  dest.print(GPS_long);     
  dest.print(',');
  dest.print(GPS_altitude);
  dest.print(',');
  dest.print((millis() - GPS_lastgood)/1000);
}


int GPS_parse_char(byte inputChar)
{
  switch (inputChar)
  {
  case '\r':
    return GPS_check_buffer();

  case '$':
    GPS_byteCount = 0;  // Start of message

  default:
    GPS_buff[GPS_byteCount++] = inputChar;
    if (GPS_byteCount == 100)
    {
      GPS_byteCount = 0;  // Start of message
      return -3;  //  Buffer overrun
    }
    return 0; // Not a full message
  }
}


int GPS_check_buffer()
{
  GPS_buff[GPS_byteCount] = '\0';

  unsigned char *buffp = GPS_buff;

  // Check the message type
  for (int i=0; i<7; i++)
  {
    if (buffp[i] != "$GPGGA,"[i])
      return 0;
  }

  // Verify the checksum before doing any more
  if (GPS_buff[GPS_byteCount-3] != '*')  // Checksum marker
    return -1;  // Bad message format

  byte checksum = 0;
  for (int i=1; i<GPS_byteCount-3; i++)  // Skip '$' and '*'
    checksum ^= GPS_buff[i];
  //  Test the result
  checksum -= hexval(GPS_buff[GPS_byteCount-2]) << 4;
  checksum -= hexval(GPS_buff[GPS_byteCount-1]);

  if (checksum != 0) return -2; // Checksum failure

  //  parse the time field
  buffp += 7;  // Skip over $GPGGA,
  GPS_time = 0;
  while (hexval(*buffp) != -1)  // for each digit
  {
    GPS_time *= 10;
    GPS_time += hexval(*buffp);
    buffp++;
  }

  if (*buffp++ != '.') // Should be a decimal point
    return -1;

  while (*buffp == '0')  // Skip zeros
    buffp++;

  if (*buffp++ != ',') // Should be a comma
    return -1;

  // Parse latitude
  GPS_lat = "";
  for (int i=0; i<20; i++)
  {
    if (*buffp == ',')
      break;
    GPS_lat += *buffp++;
    if (i == 1)
      GPS_lat += ' ';  // Separate degrees from minutes
  }
  buffp++;  // skip the comma

  if (*buffp == 'S')
    GPS_lat = "-" + GPS_lat;
  else
    if (*buffp != 'N')
      return -1;

  buffp++;  // Skip the N or S

  if (*buffp++ != ',') // Should be a comma
    return -1;


  // Parse longitude
  GPS_long = "";
  for (int i=0; i<20; i++)
  {
    if (*buffp == ',')
      break;
    GPS_long += *buffp++;
    if (i == 2)
      GPS_long += ' ';  // Separate degrees from minutes
  }
  buffp++;  // skip the comma

  if (*buffp == 'W')
    GPS_long = "-" + GPS_long;
  else
    if (*buffp != 'E')
      return -1;

  buffp++;  // Skip the E or W

  if (*buffp++ != ',') // Should be a comma
    return -1;

  if (*buffp++ == '0')
  {
    Faults |= GPS_fault;
    return -3; // No view of sattelites
  }

  if (*buffp++ != ',') // Should be a comma
    return -1;

  GPS_lastgood = millis();

  while (*buffp++ != ',') ; // Skip number of satellites
  while (*buffp++ != ',') ; // Skip horizontal dillution
  GPS_altitude = "";
  while (*buffp != ',')
    GPS_altitude += *buffp++;

  //Serial.println((char *)GPS_buff);
  Faults &= ~GPS_fault;
  return 1;  // Good fix
}


int hexval(char digit)
{
  if (digit >= '0' && digit <= '9')
    return digit - '0';

  if (digit >= 'A' && digit <= 'F')
    return digit - 'A' + 10;

  if (digit >= 'a' && digit <= 'f')
    return digit - 'a' + 10;

  return -1;
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Newcastle, England
Offline Offline
Sr. Member
****
Karma: 3
Posts: 489
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've played with a GPS module before, using this code:

Code:
char data[300];
char GPSsignature[7] = "$GPRMC";
int comma[13];
int ledPin = 13;                  // LED test pin
int GPSbyte;
int count;
int correctData;

void setup() {
  pinMode(ledPin, OUTPUT);       // Initialize LED pin
  Serial.begin(4800); 
}

void loop() {
  digitalWrite(ledPin, HIGH);

  if (Serial.available() > 0){
    GPSbyte=Serial.read();         // Read a byte of the serial port
   
    data[count]=GPSbyte;        // If there is serial port data, it is put in the array
    count++;                     

    if (GPSbyte==13){            // If the received byte is = to 13, end of transmission
      digitalWrite(ledPin, LOW);
      count=0;
      correctData=1;

      for (int i=1;i<7;i++){     // Verifies if the received command starts with $GPR
        if (data[i]!=GPSsignature[i-1])
          correctData=0;
      }

      if(correctData){               // If yes, countinue and process the data
        for (int i=0;i<300;i++){
          if (data[i]==','){    // check for the position of the  "," separator
            comma[count]=i;
            count++;
          }
          if (data[i]=='*'){    // ... and the "*"
            comma[12]=i;
            count++;
          }
        }
          count = 0;

          Serial.println("---------------");
          for (int i=0;i<8;i++){
            switch(i){
            case 0 : Serial.print("Time in UTC (HhMmSs): "); break;
            case 1 : Serial.print("Status (A=OK,V=!OK): "); break;
            case 2 : Serial.print("Latitude: "); break;
            case 3 : Serial.print("Direction (N/S): "); break;
            case 4 : Serial.print("Longitude: "); break;
            case 5 : Serial.print("Direction (E/W): "); break;
            case 6 : Serial.print("Velocity in knots: "); break;
            case 7 : Serial.print("Heading in degrees: "); break;
            case 8 : Serial.print("Date UTC (DdMmAa): "); break;
            }

           for (int j=comma[i];j<(comma[i+1]-1);j++){
             Serial.print(data[j+1]);
           }
            Serial.println("");
          }
        }   
      }
    }
  else delay(100);
}


It takes in all the data from the GPS via the serial port, then extrancs the data and prints out each individual part. If you wanted, you could ignore the lat,lon,altitude,n/s,e/w bits and just look at the time, which will not be too hard.
I managed to find a decent GPS module for £20, but I cannot find it in the shop I bought it from, so no links... It had good accuracy though, quick to find sattelites, and worked indoors!

Onions.
Logged

My website: http://www.harryrabbit.co.uk/electronics/home.html Up and running now! (Feel free to look round!) smiley-grin

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks guys, that helps a lot. 

There are some cheap GPS modules here, I will get one and try it out if I get some time this weekend, I must make sure it has ttl connections though.

I will first try the simplest displaying the hhmm barebones version, and post any results
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

New River, Arizona
Offline Offline
God Member
*****
Karma: 19
Posts: 928
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I did this, but a bit more elaborately.  I needed a time standard for my entire house.  I have several devices (thermostats, timers, etc) around the house that needed the time, and originally, I was getting the time over the internet from NIS.  This wasn't as good an idea as I thought it would be.  Seems the NIS servers sometimes don't respond and sometimes the internet doesn't work (duh !).  So I got a GPS module, hooked an arduino to it with an ethernet shield and had a LAN based clock that was synced to the satellites.  This was cool, but I still had some problems with the ethernet.  So, I built an XBee network and modified the satellite clock to work over it as well.

Now, I have a clock that is synced with the satellites and transmits the time over the LAN on request and also transmits over the XBee network to sync the various devices around the house.  Oh, it also has a serial LCD display that shows the time on the front of it.

However, I almost never see the display, it is in an attic room that also houses my router, phone and TV distribution stuff as well as my comic book collection (total geek I am).  The code is online at my blog (see signature line) or get to it directly http://www.desert-home.com/p/house-clock.html

Feel free to snag anything you want.
Logged

Trying to keep my house under control http://www.desert-home.com/

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thats a cool house/lab you have there !
I looked at your code and have to admit it makes me realise how little I know yet about programming !  but I am learning all the time.

I am sure with all the sketches you guys have supplied I will find a way to get the time from the NMEA string.

  Sending to the LED displays I am an old hat with now :-)
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Dubuque, Iowa, USA
Offline Offline
Edison Member
*
Karma: 45
Posts: 2469
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Use a TLC5916 or STP16C596 instead of the TPIC6B59. The outputs are current-controlled so you can avoid all the resistors.
Logged

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thats a far better chip,, but I still have a few hundred of the TPIC595 ones to use up first .
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

New River, Arizona
Offline Offline
God Member
*****
Karma: 19
Posts: 928
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Few HUNDRED ???  Wow, you believe in stocking up....

Regarding code, don't take mine as an example of how it should be.  Even though it works pretty well, I keep finding things I should have done differently.  I don't know about other folk, but sometimes I'm a-feared of showing my code because people will laugh at it.  They haven't yet, but I'm sure it's coming.

shudder
Logged

Trying to keep my house under control http://www.desert-home.com/

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I use a lot of them in my business, so I choose them for the hobby experimantal stuff too.

I asked a good friend who sells components for a quote on them a few months ago, and his supplier in Hong Kong thought he was ordering them, and sent them in the next container, so I am sort of committed to buying these chips until they are used up !

Re your code, thats fine its a great starting point, I often start with a section of code from someones example, and mess around experimenting with it to help me learn......  I have been playing with the Arduino for a year now, and have made dozens of projects, and I feel I probably know 1% of it all now !
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Its 3 am , passing through the office, brain still asleep,  wondering how I am going to Serial.print("Velocity in knots: "); when I have the gps module connected to the serial port ???
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

New River, Arizona
Offline Offline
God Member
*****
Karma: 19
Posts: 928
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

read about NewSoftSerial when you wake up.
Logged

Trying to keep my house under control http://www.desert-home.com/

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah,  now that rings a bell, thanks
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Back on the project again, finally got the cheapy GPS receiver module, hooked it up on a bit of stripboard and used NewSerailSoft  and the sketch from Onions ( thank you ) and its working fine from the 3v3 supply from the Arduino board.

The time comes on correct immediately , even while its waiting for the satellite fixes ?   Theres no back up battery, but thats fine.  I guess it only needs the first satellite for the time.

I dont know if I have found why it was cheap, but it places my house about 100 Km up the coast , every time !

I couldnt give a hoot about the position for my clock project, and will find out if they have a whole bucket of these cheap :-)
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Cape Town South Africa
Offline Offline
Edison Member
*
Karma: 19
Posts: 1217
A newbie with loads of posts, and still so much to learn !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, while it runs fine for 10 minutes, reading out the time etc, it freezes after 10 minutes or so.
Am I filling some buffer or something?

Heres the test sketch :-
Code:
#include <NewSoftSerial.h>

NewSoftSerial GPS1(14, 15);


char data[300];
char GPSsignature[7] = "$GPRMC";
int comma[13];
int ledPin = 13;                  // LED test pin
int GPSbyte;
int count;
int correctData;

void setup() {
  pinMode(ledPin, OUTPUT);       // Initialize LED pin
  Serial.begin(115200); 
   GPS1.begin(9600);
 
}

void loop() {
  digitalWrite(ledPin, HIGH);

  if (GPS1.available() > 0){
    GPSbyte=GPS1.read();         // Read a byte of the serial port
   
    data[count]=GPSbyte;        // If there is serial port data, it is put in the array
    count++;                     

    if (GPSbyte==13){            // If the received byte is = to 13, end of transmission
      digitalWrite(ledPin, LOW);
      count=0;
      correctData=1;

      for (int i=1;i<7;i++){     // Verifies if the received command starts with $GPR
        if (data[i]!=GPSsignature[i-1])
          correctData=0;
      }

      if(correctData){               // If yes, countinue and process the data
        for (int i=0;i<300;i++){
          if (data[i]==','){    // check for the position of the  "," separator
            comma[count]=i;
            count++;
          }
          if (data[i]=='*'){    // ... and the "*"
            comma[12]=i;
            count++;
          }
        }
          count = 0;

          Serial.println("---------------");
          for (int i=0;i<9;i++){
            switch(i){
            case 0 : Serial.print("Time in UTC (HhMmSs): "); break;
            case 1 : Serial.print("Status (A=OK,V=!OK): "); break;
            case 2 : Serial.print("Latitude: "); break;
            case 3 : Serial.print("Direction (N/S): "); break;
            case 4 : Serial.print("Longitude: "); break;
            case 5 : Serial.print("Direction (E/W): "); break;
            case 6 : Serial.print("Velocity in knots: "); break;
            case 7 : Serial.print("Heading in degrees: "); break;
            case 8 : Serial.print("Date UTC (DdMmAa): "); break;
            }

           for (int j=comma[i];j<(comma[i+1]-1);j++){
             Serial.print(data[j+1]);
           }
            Serial.println("");
          }
        }   
      }
    }
  else delay(100);
}
Logged

With my mobile phone I can call people and talk to them -  how smart can you get ?

Pages: [1] 2   Go Up
Jump to: