【问题标题】:Checking device status, while receiving data from serial port c#检查设备状态,同时从串口c#接收数据
【发布时间】:2013-08-07 18:22:54
【问题描述】:

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

大家好。

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

现状

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

由于这只是我表单中的一个示例,因此只有一个名为 labelStatuslabelStatus.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() 放入带有 TimeoutExceptiontry/catch 块中,我尝试手动执行 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);
    }
}

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

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

【问题讨论】:

标签: c# serial-port status


【解决方案1】:

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

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

【讨论】:

  • 嗯。我试图发现这个想法,但我不确定 WM_DEVICECHANGE 事件是否适合我的情况。我正在连接的设备是规模和(我认为)系统不知道该设备是否已连接。我实际上没有向我的计算机(com 端口或任何其他)添加任何类型的硬件,我不知道是否插入了比例尺,直到我只是向它发送数据并得到响应。但也许我错了。如果我不请求数据,Scale 不会发送任何内容。如果我只是插入秤,它似乎只是插入,没有别的。比较之间没有通信。和设备。
【解决方案2】:

这是我的解决方案

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

第一次尝试

计划:

  • 添加两个静态 int 字段(标志)checkOldcheckNew
  • DataReceived 中增加checkNew,签入计时器Tick 方法
  • checkOld 等于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
  • 增加checkNew in DataReceived 事件,
  • 在定时器Tick事件填充数组到index, 递减index 值直到整个数组被填满,如果index == 0index 值重置为 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-07-09
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多