1

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

大家好。

如何检查设备是否响应请求?我在谷歌上搜索了几天,并尝试了很多 SO 的解决方案,但没有给我预期的结果。经过多次尝试,我的观点如下所述。我想我已经很接近了,但现在我需要的帮助很少,所以提前感谢您的每一个回答。

目前的情况

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

因为这只是我表格中的一个例子,所以只有一个标签叫做labelStatusandlabelStatus.Text = "Not connected"

接下来我要添加一个计时器,它是 tick 方法,其中包含serialPort.Write(). 如果这很重要,计时器间隔设置为 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"));
}

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

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

我试过什么

我已经尝试了很多东西,但我脑海中的这个似乎应该有效,但没有。

我已经修改了DataReceived事件,并且我已经尝试手动执行如下方法serialPort.ReadLine()try/catchTimeoutExceptionErrorReceived

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);
    }
}

我希望这会像我想要的那样工作。

顺便提一句。对不起我的英语不好。它并不完美,但我尽我所能。干杯!

4

2 回答 2

0

这是我的解决方案

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

第一次尝试

计划:

  • 添加两个静态 int 字段(标志)checkOldcheckNew,
  • 增量checkNewDataReceived签入计时器Tick方法
  • ischeckOld等于checkNew。如果为真,则表示checkNew 不递增,并且表示DataReceived未执行。

`私人无效serialPort_DataReceived(对象发送者,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
  • 事件增加checkNewDataReceived
  • 在定时器Tick事件填充数组中index,递减index值直到整个数组被填充,如果 将值index == 0重置index为 6,
  • 最后检查checkNew, 中存储的 最后六个值statusArray是否相同。如果为真,则意味着DataReceived没有连续执行六次,现在我可以确定连接丢失了。

`静态int索引= 6;静态 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;
}

`

于 2013-08-07T01:09:00.510 回答
0

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

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

于 2013-08-06T16:55:08.850 回答