zoukankan      html  css  js  c++  java
  • C#--Modbus-一主多从-委托跨线程更新UI界面

    以下是学习笔记

    一,接线图

      3台仪表设备接在一起

     二,界面设计:

    三,代码实现:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using DAL;
    
    namespace ModbusDemo
    {
        //委托跨线程更新UI步骤【1】:声明一个delegate委托类型:UpdateDelegate。
        delegate void UpdateDelegate();
        public partial class FrmMain : Form
        {
            public FrmMain()
            {
                InitializeComponent();
                this.Load += FrmMain_Load;
            }
            //委托跨线程更新UI步骤【2】:创建一个UpdateDelegate类型的对象。
            UpdateDelegate updateGUI;
    
            Modbus objMod = new Modbus();
            bool CommOK = false;
            bool ReadEnable = true;
            Dictionary<int, byte[]> CommValue = new Dictionary<int, byte[]>();
            Dictionary<int, List<string>> CurrentValue = new Dictionary<int, List<string>>();
    
            private void FrmMain_Load(object sender, EventArgs e)
            {
                //委托跨线程更新UI步骤【3】:给updateGUI(委托)对象绑定一个方法。
                updateGUI = UpdateUI;
    
                for (int i = 0; i < 5; i++)
                {
                    this.cmb_1stNum.Items.Add(i.ToString());
                    this.cmb_2ndNum.Items.Add(i.ToString());
                    this.cmb_3rdNum.Items.Add(i.ToString());
                }
    
    
                if (objMod.OpenMyComm(9600, "COM3", 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One))
                {
                    CommOK = true;
                }
                else
                {
                    MessageBox.Show("串口打开失败,请检查串口!", "串口打开 ");
                    return;
                }
    
                Thread t = new Thread(new ThreadStart(Comm));
                t.IsBackground = true;
                t.Start();
            }
    
            /// <summary>
            /// 线程执行的方法
            /// </summary>
            private void Comm()
            {
                while (CommOK)
                {
                    //第一步:数据读取
                    //对于从站1,读取0-4共5个寄存器
                    CommValue[1] = objMod.ReadKeepReg(1, 0, 5);
                    //对于从站2和从站3,读取0-3共4个寄存器
                    CommValue[2] = objMod.ReadKeepReg(2, 0, 4);
                    CommValue[3] = objMod.ReadKeepReg(3, 0, 4);
    
                    //第二步:数据解析
                    AnalyseData();
    
                    //第三步:更新到界面
                    //委托跨线程更新UI步骤【6】:在线程中调用委托。
                    updateGUI();
                }
            }
    
            /// <summary>
            /// 数据解析
            /// </summary>
            private void AnalyseData()
            {
                byte[] res;
                List<string> list;
                foreach (int item in CommValue.Keys)
                {
                    switch (item)
                    {
                        //从站1
                        case 1:
                            res = CommValue[1];
                            list = new List<string>();
                            if (res != null && res.Length == 10)
                            {
                                //计数值
                                Int32 res1 = ByteArrayToInt32(new byte[4] { res[0], res[1], res[2], res[3] });
                                list.Add(res1.ToString());
                                Int16 res2 = ByteArrayToInt16(new byte[2] { res[6], res[7] });
                                list.Add(res2.ToString());
                            }
                            CurrentValue[1] = list;
                            break;
                        case 2:
                            res = CommValue[2];
                            list = new List<string>();
                            if (res != null && res.Length == 8)
                            {
                                //计时值
                                Int32 res1 = ByteArrayToInt32(new byte[4] { res[0], res[1], res[2], res[3] });
                                list.Add(res1.ToString());
                                Int16 res2 = ByteArrayToInt16(new byte[2] { res[6], res[7] });
                                list.Add(res2.ToString());
                            }
                            CurrentValue[2] = list;
                            break;
                        case 3:
                            res = CommValue[3];
                            list = new List<string>();
                            if (res != null && res.Length == 8)
                            {
                                //计时值
                                Int32 res1 = ByteArrayToInt32(new byte[4] { res[0], res[1], res[2], res[3] });
                                list.Add(res1.ToString());
                                Int16 res2 = ByteArrayToInt16(new byte[2] { res[6], res[7] });
                                list.Add(res2.ToString());
                            }
                            CurrentValue[3] = list;
                            break;
                    }
                }
    
            }
    
            /// <summary>
            /// 委托跨线程更新UI步骤【4】:更新UI的方法。
            /// </summary>
            private void UpdateUI()
            {
                if (CurrentValue.Count == 3)
                {
                    //判断该方法是否被主线程调用,也就是创建窗体控件的线程,当控件的InvokeRequired属性为ture时,说明是被主线程以外的线程调用。如果不加判断,会造成异常
                    if (this.InvokeRequired)//判断
                    {
                        //委托跨线程更新UI步骤【5】:激活委托。
                        this.Invoke(updateGUI);
                    }
                    else
                    {
                        if (CurrentValue[1].Count>0)
                        {
                            this.txt_1stNum.Text = CurrentValue[1][0];
                            this.cmb_1stNum.Text = CurrentValue[1][1];
                        }
                        if (CurrentValue[2].Count > 0)
                        {
                            this.txt_2ndNum.Text = CurrentValue[2][0];
                            this.cmb_2ndNum.Text = CurrentValue[2][1];
                        }
                        if (CurrentValue[3].Count > 0)
                        {
                            this.txt_3rdNum.Text = CurrentValue[3][0];
                            this.cmb_3rdNum.Text = CurrentValue[3][1];
                        }
                    }
                }
            }
    
    
    
            /// <summary>
            /// 4个字节转换成一个长整形
            /// </summary>
            /// <param name="byteArray"></param>
            /// <returns></returns>
            private Int32 ByteArrayToInt32(byte[] byteArray)
            {
                if (byteArray.Length == 4)
                {
                    return (Int32)(byteArray[3] + byteArray[2] * Math.Pow(2, 8) + byteArray[1] * Math.Pow(2, 16) + byteArray[0] * Math.Pow(2, 24));
                }
                else
                {
                    return 0;
                }
    
            }
    
            private Int16 ByteArrayToInt16(byte[] byteArray)
            {
                if (byteArray.Length == 2)
                {
                    return (Int16)(byteArray[1] + byteArray[0] * Math.Pow(2, 8));
                }
                else
                {
                    return 0;
                }
    
            }
    
            private void btn_Set1_Click(object sender, EventArgs e)
            {
                objMod.PreSetKeepReg(1, 3, int.Parse(this.txt_Set1.Text.Trim()));
            }
    
            private void btn_Set2_Click(object sender, EventArgs e)
            {
                objMod.PreSetKeepReg(2, 3, int.Parse(this.txt_Set2.Text.Trim()));
            }
    
            private void btn_Set3_Click(object sender, EventArgs e)
            {
                objMod.PreSetKeepReg(3, 3, int.Parse(this.txt_Set3.Text.Trim()));
            }
        }
    }
    

      

  • 相关阅读:
    Unity热更新06-XLua热补丁-05
    Unity热更新06-XLua热补丁-04
    Unity热更新06-XLua热补丁-03
    Unity热更新06-XLua热补丁-02
    Unity热更新06-XLua热补丁-01
    [SQLite][database disk image is malformed]数据库恢复
    VMware 安装MAC
    c#编写的服务中访问网络位置的共享文件夹
    Android Socket发送信息时闪退
    一个简单的Log类
  • 原文地址:https://www.cnblogs.com/baozi789654/p/14671897.html
Copyright © 2011-2022 走看看