我从连接到我的电脑的GPS设备接收纬度和经度值。我需要设置timeinterval 这样,在500毫秒之后,如果我没有从端口接收数据,我需要打印一些文本。我不知道 如何做到这一点有人可以帮我解决这个问题。我也上传了我的代码。
class PortDataReceived
{
private static SerialPort mySerialPort;
public static void Main()
{
mySerialPort = new SerialPort("COM5");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
//mySerialPort.ReadTimeout = 500;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
Console.WriteLine();
Console.ReadKey();
mySerialPort.Close();
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
////////////////////////////////////
//System.Threading.Thread.Sleep(1000);
//Console.WriteLine("NAN");
/* Timer tmr = new System.Timers.Timer();
tmr.Interval = 500;
tmr.Elapsed += OnTimedEvent;
tmr.AutoReset = true;
// Start the timer
tmr.Enabled = true
private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
if(indata == null)
* {
* Console.WriteLine("NAN");
* }
}*/
////////////////////////////////////
{
string pattern = @"^\$GNGGA,[^,]+,(\d{2})(\d{2}\.\d+),([NS]),(\d{3})(\d{2}\.\d+),([EW]),.+$";
System.Text.RegularExpressions.MatchCollection matches = System.Text.RegularExpressions.Regex.Matches(indata, pattern);
if (matches.Count > 0)
{
foreach (System.Text.RegularExpressions.Match match in matches)
{
double Lat = Double.Parse(match.Groups[1].Value, System.Globalization.CultureInfo.InvariantCulture);
Lat += Double.Parse(match.Groups[2].Value, System.Globalization.CultureInfo.InvariantCulture) / 60;
Lat *= match.Groups[3].Value == "N" ? 1 : -1;
double Lng = Double.Parse(match.Groups[4].Value, System.Globalization.CultureInfo.InvariantCulture);
Lng += Double.Parse(match.Groups[5].Value, System.Globalization.CultureInfo.InvariantCulture) / 60;
Lng *= match.Groups[6].Value == "E" ? 1 : -1;
string output = "{Lat: " + Lat.ToString(System.Globalization.CultureInfo.InvariantCulture);
output += ", Lng: " + Lng.ToString(System.Globalization.CultureInfo.InvariantCulture) + "}";
Console.WriteLine(output);
}
}
//mySerialPort.DataReceived -= new SerialDataReceivedEventHandler(DataReceivedHandler);
}
}
}
答案 0 :(得分:0)
You can use a synchronization object, for example ManualResetEvent
to check whether data has been received within 500 milliseconds.
Declare:
class PortDataReceived
{
// Create an event which is not signaled
ManualResetEvent DataReceivedEvent = new ManualResetEvent(false);
...
}
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
// Set the event object to signaled state as soon as data is received
DataReceivedEvent.Set();
...
}
Then in your Main
function you can do:
public static void Main()
{
...
mySerialPort.Open();
TimeSpan waitTime = TimeSpan.FromMilliseconds(500);
if(DataReceivedEvent.WaitOne(waitTime) == false)
{
// Failure: Data has not been received within waitTime
// Print text
}
else
{
// Success: Data has been received within waitTime
// Do work
}
...
}
答案 1 :(得分:0)
Make another class to handle incoming data
In that class start a timer, stop the timer when the incoming data is a complete gps message.
you can make a public method to start the timer depending what the trigger is for the start so
_gps.Start()
then in your serial just call
_gps.Interpret(indata)
as an asside, make a class for lat long. make a class for translating your gps strings to cooridinates
so interpret will be something like
public void Interpret(string s)
{
var extra = _packet.Consume(s); // extra is if s has more than the data you are expecting
if(_packet.Complete)
{
var location = packet.ToLocation()
}
}