从串口c#接收数据时检查设备状态

时间:2013-08-06 16:16:18

标签: c# serial-port status

通过串口连接的设备的生命状态。

大家好。

我如何检查设备是否响应请求?我正在谷歌上搜索这几天,并尝试了很多解决方案,但没有给我带来我期望的结果。经过多次尝试,我将在下面描述。我觉得我非常接近,但现在我需要一些帮助,所以请提前感谢每一个答案。

目前情况

我现在在做什么很简单。首先,我在应用程序开始时打开串口serialPort.Open()(数据几乎接收所有应用程序运行时间)。

由于这只是我表单中的一个示例,因此只有一个名为labelStatuslabelStatus.Text = "Not connected"

的标签

接下来我要添加一个计时器和它的tick方法,其中包含serialPort.Write()的执行。如果重要,Timer Interval设置为100.

private void timer_Tick(object sender, EventArgs e)
{
    if (serialPort.IsOpen)
    {
        serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
    }
}

下一步是创建DataReceived事件,如下所示(非常简化的版本,在我的应用程序中,收到的数据正在解析为浮点数并存储在数组中,但它只是为了显示问题)

private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    string someVariable = serialPort.ReadLine();
    labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
    //If i received something that means the device is plugged in and connection is correct (still very simplified)
}

最后一件事是创建ErrorReceived方法。

private void serialPort_ErrorReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Not connected"));
}

直到现在一切顺利。发送数据有效。发送数据时,每100毫秒执行一次DataReceived事件。我的数据收到正确,没有任何问题。当我启动应用程序labelStatus时,文本为“未连接”(设备电缆未插入)。当我插入设备labelStatus文本更改为“已连接”时。 但现在当我插入电缆ErrorReceived时,事件未执行且labelStatus文字仍处于“已连接”状态。所以我之前已经问过:我如何检查设备是否仍然连接到计算机? (或者可能:当数据没有收到时,如何执行ErrorReceived事件?)

注意:串行端口ReadTimeout设置为300毫秒。

我尝试了什么

我已经尝试了很多东西,但是我脑子里的这个似乎应该可以工作但不会。

我修改了DataReceived事件,并将serialPort.ReadLine()放入try/catch阻止TimeoutException阻止{I}尝试手动执行ErrorReceived方法如下所示

private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    try
    {
        string someVariable = serialPort.ReadLine();
        labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
        //If i received something that means the device is plugged in and connection is correct (still very simplified)
    }
    catch (TimeoutException)
    {
        serialPort_ErrorReceived(null, null);
    }
}

我希望能像我想的那样工作。

顺便说一句。对不起我的英语不好。这不完美,但我会尽力而为。干杯!

2 个答案:

答案 0 :(得分:0)

侦听在删除或插入设备时将触发的WM_DEVICECHANGE事件。

以下是一个实现示例和更多信息:

答案 1 :(得分:0)

这是我案例中的解决方案

关于Martjin的回答,我需要进一步解释我的情况。首先,我想说我没有在我的计算机上安装任何硬件,所以我认为WM_DEVICECHANGE事件不是我需要的(但当然感谢您提供的信息,我已经学到了一些东西新)。应用程序正在从规模读取数据。插入COM端口后扩展不发送任何数据,实际上它与计算机之间根本没有通信。读取数据的唯一方法是发送扩展请求,因此我必须依赖它。

首先尝试

计划:

  • 添加两个静态int字段(标志)checkOldcheckNew
  • checkNew中增加DataReceived,检入计时器Tick方法
  • checkOld等于checkNew。如果为true则表示checkNew 没有增加,这意味着DataReceived没有被执行。

`     private void serialPort_DataReceived(object sender,System.IO.Ports.SerialDataReceivedEventArgs e)     {

    checkNew++;

    string someVariable = serialPort.ReadLine();
    labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
    //If i received something that means the device is plugged in and connection is correct (still very simplified)
}

private void timer_Tick(object sender, EventArgs e)
{
    if (serialPort.IsOpen)
    {
        serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
    }
    if (checkOld == checkNew)
    {
        labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Not connected"));
    }
}

`

计划很好,但是当我测试时,结果甚至都不好。发生了什么?实际上设备状态是闪烁连接 - 没有连接 - 没有连接等。我已经写了一些数据输出并得到答案。计时器循环速度非常快,DataReceived事件无法始终增加checkNew值。

最终解决方案

根据我目前的情况,我决定添加一些小改动。而不是比较两个整数值,尝试收集几个最后的值,检查是否所有都是sem。

计划:

  • 添加三个静态字段:前六个元素的整数数组 statusArray,第二个整数index,其值等于6(最后一个 数组的元素+ 1),第三个整数checkNew
  • 增加checkNew in DataReceived事件,
  • 计时器Tick事件填充数组中的
  • index, 递减index值,直到整个数组被填充,如果index == 0重置index值为 6,
  • 并最后检查是否存储了checkNew的最后六个值 statusArray是一样的。如果为真,那意味着DataReceived没有 连续六次执行,现在我可以确定连接是 丢失。

`     static int index = 6;     static int checkNew = 0;

static int[] statusArray = {0,0,0,0,0,0};

private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{

    checkNew++;

    string someVariable = serialPort.ReadLine();
    labelStatus.Invoke((MethodInvoker)(() => labelStatus.Text = "Connected"));
    //If i received something that means the device is plugged in and connection is correct (still very simplified)
}

private void timer_Tick(object sender, EventArgs e)
{
    if (serialPort.IsOpen)
    {
        serialPort.WriteLine("r"); //I'm sending "r" message and device send data back
    }

    if (index == 0)
        index = 6;
    index--;

    int value = statusArray[index] = checkNew;
}

`