在c#

时间:2017-06-09 12:26:03

标签: c# serial-port

我从连接到我的电脑的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);
    }
 }
}

2 个答案:

答案 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()
    }
}