You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

西门子PLC编码器数据读取异常:两个文本框数值一致

解决西门子PLC编码器数据时间节点读取重复问题

问题背景

  • 硬件配置:编码器与西门子PLC相连,对应数据块为DB1.DBD56
  • 异常现象:两个文本框txtbefore和txtafterWeld显示的编码器数值完全相同
  • 需求目标:分别读取1秒前和1秒后的编码器数值

问题根源分析

现有代码中,Read_Before和Read_After方法直接复用同一个变量convertTomm——这个变量存储的是当前最新的编码器转换值,没有单独保存1秒前的历史数据,导致两个文本框始终显示相同数值。同时缺少明确的时间节点触发逻辑,无法实现“1秒间隔读取”的要求。

解决方案

1. 添加历史值存储变量

在类的成员区域定义变量,专门保存1秒前的编码器数值:

private double _previousEncoderValue = 0;

2. 实现1秒间隔的时间触发逻辑

假设timer_OneCycleProcess是用于控制时间间隔的计时器(需将其Interval属性设置为1000即1秒),修改其Tick事件处理方法:

private void timer_OneCycleProcess_Tick(object sender, EventArgs e)
{
    try
    {
        if (plc_s7_1200.IsConnected)
        {
            // 读取PLC中编码器的原始值并转换为毫米(复用原有转换逻辑)
            double rawEncoderValue = Convert.ToDouble(plc_s7_1200.Read("DB1.DBD56"));
            convertTomm = rawEncoderValue; // 假设convertTomm是已实现的毫米转换变量

            // 首次触发:记录1秒前的初始值
            if (_previousEncoderValue == 0)
            {
                _previousEncoderValue = convertTomm;
                txtbefore.Text = string.Format("{0:0.0}", _previousEncoderValue);
            }
            else
            {
                // 1秒后:读取当前值并更新文本框
                txtafterWeld.Text = string.Format("{0:0.0}", convertTomm);
                // 重置变量,准备下一次周期读取
                _previousEncoderValue = 0;
                timer_OneCycleProcess.Stop();
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("读取编码器数据出错: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

3. 调整状态触发计时器逻辑

修改timer_anvilState_Tick方法,确保在触发读取周期前重置历史值:

private void timer_anvilState_Tick(object sender, EventArgs e)
{
    try
    {
        bool anvilState = (bool)plc_s7_1200.Read("DB1.DBX68.4");

        if (plc_s7_1200.IsConnected)
        {
            if (anvilState == true)
            {
                // 启动读取周期前重置历史值,避免旧数据干扰
                _previousEncoderValue = 0;
                timer_OneCycleProcess.Start();
            }
            else
            {
                timer_OneCycleProcess.Stop();
                command = "IDLE";
            }
        }

        // 保留原有业务逻辑调用
        Edata_convertion();
        read_lastweld_result();
    }
    catch (Exception ex)
    {
        MessageBox.Show("请检查PC与PLC连接: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

4. 简化原读取方法(可选)

如果仍需保留Read_Before和Read_After方法,可修改为基于存储的历史值更新:

#region READ BEFORE
public void Read_Before()
{
    txtbefore.Text = string.Format("{0:0.0}", _previousEncoderValue);
}
#endregion

#region READ AFTER
public void Read_After()
{
    txtafterWeld.Text = string.Format("{0:0.0}", convertTomm);
}
#endregion

关键注意事项

  • 必须使用独立变量存储历史值,禁止直接复用当前读取的实时值
  • 确保timer_OneCycleProcess的Interval属性设置为1000毫秒,保证两次读取的时间差为1秒
  • 每次启动读取周期前重置历史值,避免上次周期的残留数据影响结果

内容的提问来源于stack exchange,提问作者GMK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:35:24