Engineering-Diy

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Sunday, 6 October 2013

Keep your linux clock synchronized with gps time

Posted on 03:39 by Unknown
A big problem for a CarPC is that you need a real time clock to synchronize your system with.
For my CarPC, I don't have any RTC module on Raspberry PI, but I do have a gps always connected, which provide accurate date and UTC time.
I have found some tutorials on how I can set up ntp to update the system clock based on gpsd but they didn't worked with any of my gps devices:
ST22 SkyTraq GPS receiver
Columbus V-800
I have followed some links with no luck. I got:
"gpsd:WARN: can't use GGA time until after ZDA or RMC has supplied a year."
or
"gps data is no good"
or
"unrecognized ... sentence"

I have decided to make my own time synchronization based on parsing raw gps data.
You can download an archive containing the scripts from here.

How does it work?
First connect your gps module:
gpsd /dev/ttyAMA0
Then, to get the raw data I used:
gpspipe -R -n10
This command will get the first 10 lines from gps raw data. I got this:
pi@raspberrypi ~ $ gpspipe -R -n10
{"class":"VERSION","release":"3.6","rev":"3.6","proto_major":3,"proto_minor":7}
{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyAMA0","activated":"2013-10-06T09:42:18.793Z","flags":1,"driver":"Generic NMEA","native":0,"bps":9600,"parity":"N","stopbits":1,"cycle":1.00}]}
{"class":"WATCH","enable":true,"json":false,"nmea":false,"raw":2,"scaled":false,"timing":false}
$GPGGA,094220.784,4425.1141,N,02602.8254,E,1,05,1.6,96.1,M,37.0,M,,0000*6D
$GPGSA,A,3,25,05,29,31,21,,,,,,,,3.1,1.6,2.7*3A
$GPGSV,3,1,09,29,61,061,29,21,58,214,37,25,41,146,38,31,33,245,35*72
$GPGSV,3,2,09,05,25,056,30,16,14,314,,18,09,170,19,12,04,138,20*76
$GPGSV,3,3,09,06,02,278,*49
$GPRMC,094220.784,A,4425.1141,N,02602.8254,E,000.0,191.5,061013,,,A*6E
$GPVTG,191.5,T,,M,000.0,N,000.0,K,A*01
The Shell part.
To set UTC time for our unix system we have to issue a command like this:
date -u -s "2013/10/05 12:48:00"
From the raw gps output, we see that GPRMC gives all the needed information about the date and time(see here what the fields mean).
My idea was to capture just GPRMC data from this output and send it as a parameter to a C program which will parse the string and create a new string as needed to set time.
To get the GPRMC string from the raw gps output I have did the following bash command:
gpspipe -R -n10 | sed -n "/GPRMC/,/*/p"
Decomposition of the command:
gpspipe -R -n10 - this outputs the first 10 lines from the gps raw output.
sed -n "/GPRMC/,/*/p" - extracts the line starting with the string GPRMC
I have used unix pipes(| character) to pass the output from gpspipe -R -n10 to the sed command.
The output from this command will be like this:
pi@raspberrypi ~ $ gpspipe -R -n10 | sed -n "/GPRMC/,/*/p"
$GPRMC,100201.786,A,4425.1179,N,02602.8192,E,000.0,191.5,061013,,,A*61
$GPVTG,191.5,T,,M,000.0,N,000.0,K,A*01
 Now, to pass this as program arguments(assuming the program's name is set_date) we have to do the following:
./set_date 21 $(gpspipe -R -n10 | sed -n "/GPRMC/,/*/p")
The C program part.
In this example, argc will be 4 and argv will be as follows:
argv[0] - "./set_date"
argv[1] - "21"
argv[2] - "$GPRMC,100201.786,A,4425.1179,N,02602.8192,E,000.0,191.5,061013,,,A*61"
argv[3] - "$GPVTG,191.5,T,,M,000.0,N,000.0,K,A*01"

The GPRMC output gives 100201 for time and 061013 for date. This means:
UTC time is 10:02:01 and date is 06 October 2013. GPRMC does not provide the full year, so we have to provide the century as an argument to the C program to compute the correct date.

We are only interested in argv[1] and argv[2], so, in the C program we will convert argv[1] to int using atoi(argv[1]) and we will have the century and after this we have to parse argv[2] using sscanf to get the two numbers for time: 100201 and for date 061013. Let's assume we got these numbers in two uint32_t variables:
rawDate = 61013
rawTime = 100201
To get useful data from here we have to do this:
hour = timeRaw / 10000;
minute = (timeRaw % 10000) / 100;
second = (timeRaw % 10000) % 100;

century = atoi(argv[1]);
day = dateRaw / 10000;
month = (dateRaw % 10000) / 100;
year = (century - 1) * 100 + (dateRaw % 10000) % 100;
After this, to create the command we can use sprintf to put everything in an outputBuffer and then call system(outputBuffer) to execute the command.

Read More
Posted in date, GPS, linux, synchronization | No comments
Newer Posts Older Posts Home
Subscribe to: Posts (Atom)

Popular Posts

  • OpenElec with support for eGalax touch screen
    Hi! Lately I have tested OpenElec for Raspberry PI and found out that it is very very fast, very very small and also it has some great addon...
  • Raspberry PI, Raspbian, XBMC and eGalax 7 inch touchscreen
    Hello! I have spent some time lately trying to find a solution to get my 7 inch eGalax touchscreen to work with  Raspbian(Debian Wheezy) in ...
  • Build XBMC Frodo from source in Raspbian on Raspberry PI
    Hi! After struggling couple of days in finding the best way to build XBMC on Raspberry PI I have finally got a working solution(haven't ...
  • STM32F3 Discovery + Eclipse + OpenOCD
    Hi, ST launched in September a very interesting development board( STM32F3-Discovery ). It is a very cheap one(I have got myself one for ~10...
  • Keep your linux clock synchronized with gps time
    A big problem for a CarPC is that you need a real time clock to synchronize your system with. For my CarPC, I don't have any RTC module ...
  • Car PC project(August 2013 update)
    This is an update for my CarPC project. You can download the latest image from here (username:'pi', password:'a') The main f...
  • STM32F3 Discovery on Windows with Eclipse and OpenOCD
    Hi! Because of a lot of requests, I have decided to make the Windows version of the tutorial for setting up STM32F3-Discovery board, with fr...
  • STM32F3-Discovery Usart with printf
    Hi, The next step after setting up the Development Environment for STM32F3-Discovery was to communicate with computer via serial port. I hav...
  • Control XBMC from the Raspberry PI GPIO's
    I have recently worked on adding external controls for my Raspberry PI CarPC project because while driving it is better to have some physica...
  • Adding 7inch display with touchscreen to Raspberry PI
    Hi! First thing I got in mind when seeing Raspberry PI was "car PC project". The targeted display was 7 inch with touchscreen. I h...

Categories

  • 7 inch
  • calibration
  • car pc
  • compile xbmc
  • controller
  • cortex m4
  • date
  • debian wheezy
  • discovery
  • display
  • eclipse
  • eGalax
  • embedded
  • gpio
  • GPS
  • kernel rebuild
  • linux
  • navigation
  • Navit
  • openElec
  • openocd
  • Openstreetmap
  • printf
  • push button
  • raspberry pi
  • raspbian
  • resistive
  • stm32f3
  • synchronization
  • touch screen
  • touchscreen
  • tutorial
  • ubuntu
  • usart
  • wheezy
  • windows
  • xbmc
  • xbmc 12
  • xbmc 12.2
  • xbmc frodo

Blog Archive

  • ▼  2013 (8)
    • ►  November (1)
    • ▼  October (1)
      • Keep your linux clock synchronized with gps time
    • ►  August (2)
    • ►  July (1)
    • ►  February (2)
    • ►  January (1)
  • ►  2012 (4)
    • ►  December (1)
    • ►  November (3)
Powered by Blogger.

About Me

Unknown
View my complete profile