Created
October 30, 2021 05:34
-
-
Save 0x00000FF/07eab3a3b3812b50417526485ca0913a to your computer and use it in GitHub Desktop.
Time Sync with Serial GPS Module
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void SyncGPSTime() | |
{ | |
if (!privileged) | |
privileged = EnableTimesync(); | |
var time = new SYSTEMTIME(); | |
var GPSSerial = new SerialPort() | |
{ | |
PortName = setting.ports.gps, | |
BaudRate = 9600, | |
Parity = Parity.None, | |
DataBits = 8, | |
StopBits = StopBits.One, | |
ReadTimeout = 5000 | |
}; | |
GPSSerial.DataReceived += (obj, arg) => | |
{ | |
var senderPort = (SerialPort)obj; | |
var dataSize = senderPort.BytesToRead; | |
var buffer = new byte[dataSize]; | |
senderPort.Read(buffer, 0, dataSize); | |
lock (nmeaBuffer) | |
{ | |
nmeaBuffer.AddRange(buffer); | |
var nmeaStarted = false; | |
for (var i = 0; i < buffer.Length; ++i) | |
{ | |
if ( !nmeaStarted ) | |
{ | |
if (buffer[i] != '$') continue; | |
else nmeaStarted = true; | |
} | |
nmeaBuffer.Add(buffer[i]); | |
if (buffer[i] == '*') | |
{ | |
nmeaBuffer.Add(buffer[i+1]); | |
break; | |
} | |
} | |
} | |
var NMEA = Encoding.ASCII.GetString(nmeaBuffer.ToArray()); | |
nmeaBuffer.Clear(); | |
if (NMEA.StartsWith("$GPRMC")) | |
{ | |
Program.Log(NMEA); | |
var frags = NMEA.Split('$', ','); | |
if (frags.Length < 3) return; | |
try | |
{ | |
var utc = frags[2]; | |
Program.Log("Parsed UTC: {0}", utc); | |
var hour = int.Parse(utc[0].ToString() + utc[1].ToString()); | |
var minute = int.Parse(utc[2].ToString() + utc[3].ToString()); | |
var second = int.Parse(utc[4].ToString() + utc[5].ToString()); | |
Program.Log("Parsed Time: {0}:{1}:{2}", hour, minute, second); | |
time.wYear = (short)DateTime.Now.Year; | |
time.wMonth = (short)DateTime.Now.Month; | |
time.wDay = (short)DateTime.Now.Day; | |
time.wDayOfWeek = (short)DateTime.Now.DayOfWeek; | |
time.wHour = (short)(hour); | |
time.wMinute = (short)minute; | |
time.wSecond = (short)second; | |
time.wMilliseconds = 0; | |
Program.Log("time Struct data: {0}-{1}-{2} {3}:{4}:{5} UTC", | |
time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond); | |
} | |
catch (IndexOutOfRangeException) | |
{ | |
Program.Log("Received data is invalid, retry"); | |
} | |
catch (FormatException e) | |
{ | |
Program.Log("★★★★★★★★★★★★★★★"); | |
Program.Log(e.Source); | |
Program.Log("★★★★★★★★★★★★★★★"); | |
} | |
catch (Exception e) | |
{ | |
Program.Log("★★★★★★★★★★★★★★★"); | |
Program.Log(e.Source); | |
Program.Log("★★★★★★★★★★★★★★★"); | |
} | |
syncSuccess = SetSystemTime(ref time); | |
Program.Log("Sync Success: {0}, Error Code: {1}", syncSuccess, Marshal.GetLastWin32Error()); | |
} | |
}; | |
try | |
{ | |
syncSuccess = false; | |
GPSSerial.Open(); | |
SpinWait.SpinUntil(() => syncSuccess, 5000); | |
if (!syncSuccess) | |
{ | |
Program.Log("GPS Timeout; ignoring"); | |
} | |
GPSSerial.Close(); | |
SetSystemTime(ref time); | |
} | |
catch (IOException) | |
{ | |
Program.Log("GPS Failure"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment