基于C# 读写PLC数据

一、PLC部分

将电脑与PLC连接的网口IP设置到同一网段,192.168.1.X,已台达为例。

将关心的数据进行监视

AS系列装置通讯地址

二、C#上位机部分

在NuGet安装包中添加Nmodbus4库,并引用命名空间。

代码如下 :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Modbus;

namespace ReadAndwriteDelta
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Modbus.Device.ModbusIpMaster ipMaster;
        TcpClient tcpClient;


        bool isConnect;//连接状态
        /// <summary>
        /// 建立连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_Connect_Click(object sender, EventArgs e)
        {
            if (!isConnect)
            {
                try
                {
                    tcpClient = new TcpClient();
                    tcpClient.Connect(IPAddress.Parse("192.168.1.5"), 502);
                    ipMaster = Modbus.Device.ModbusIpMaster.CreateIp(tcpClient);
                    isConnect = true;
                    this.btn_Connect.BackColor = Color.Green;
                }
                catch (Exception ex)
                {
                    isConnect = false;
                    MessageBox.Show("连接失败:" + ex.ToString());
                    return;
                }
            }
            else
            {
                MessageBox.Show("已建立连接");
            }
        }

        /// <summary>
        /// 断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_DisConnect_Click(object sender, EventArgs e)
        {
            if (isConnect)
            {
                try
                {
                    tcpClient.Close();
                    ipMaster.Dispose();
                    isConnect = false;
                    this.btn_Connect.BackColor = DefaultBackColor;
                }
                catch (Exception ex)
                {
                    isConnect = true;
                    MessageBox.Show("断开失败:" + ex.ToString());
                    return;
                }
            }
            else
            {
                MessageBox.Show("已断开连接");
            }
        }

        

        /// <summary>
        ///读数据 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_Read_Click(object sender, EventArgs e)
        {
            if (isConnect)//判断tcp连接
            {
                switch (cbbox_ReadDevicetype.Text)
                {
                    case "M":
                        try
                        {
                            //此位置固定读一个长度
                            bool[] res = ipMaster.ReadCoils(ushort.Parse(txtb_ReadAddress.Text), 1);
                            txtb_ReadPara.Text = res[0].ToString();
                        }
                        catch (Exception)
                        {
                            MessageBox.Show("M区数据读取失败");
                            return;
                        }
                        break;
                    case "D":
                        //数据初始化
                        try
                        {
                            //默认读2个长度,共32位
                            var res = ipMaster.ReadHoldingRegisters(ushort.Parse(txtb_ReadAddress.Text), 2);
                            //  读取数据个数个数不能太大,大于100个会报错
                            if (res.Length == 2)
                            {
                                float res1 = GetFloatFromUshortArray(new ushort[] { res[1], res[0] });     
                                txtb_ReadPara.Text = Math.Round(res1, 2).ToString("0.0");                                     
                            }
                        }
                        catch (Exception)
                        {
                            MessageBox.Show("D区数据读取失败");
                        }
                        break;
                    default:
                        break;
                }
            }
        }

        private float GetFloatFromUshortArray(ushort[] p)
        {
            List<byte> result = new List<byte>();
            result.AddRange(BitConverter.GetBytes(p[0]));
            result.AddRange(BitConverter.GetBytes(p[1]));
            byte[] b = new byte[4];
            b[0] = result[2];
            b[1] = result[3];
            b[2] = result[0];
            b[3] = result[1];
            //高位在后,低位在前
            return BitConverter.ToSingle(b, 0);            
        }

        /// <summary>
        /// 写数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_Write_Click(object sender, EventArgs e)
        {
            if(isConnect)//判断tcp连接
            {
                switch (cbbox_WriteDeviceType.Text)
                {
                    case "M":
                        try
                        {
                            ipMaster.WriteSingleCoil(ushort.Parse(txtb_WriteAddress.Text), bool.Parse(txtb_WritePara.Text));
                        }
                        catch (Exception)
                        {
                            MessageBox.Show("M区写入失败");
                            return;
                        }
                        break;
                    case "D":
                        try
                        {
                            ipMaster.WriteMultipleRegisters(ushort.Parse(txtb_WriteAddress.Text), GetUshortArrayFromFloat(float.Parse(txtb_WritePara.Text)));
                        }
                        catch (Exception)
                        {
                            MessageBox.Show("D区写入失败");
                            return;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        private ushort[] GetUshortArrayFromFloat(float val)
        {
            var bytearray = BitConverter.GetBytes(val);
            ushort[] res = new ushort[2];
            res[1] = BitConverter.ToUInt16(new byte[] { bytearray[2], bytearray[3] }, 0);
            res[0] = BitConverter.ToUInt16(new byte[] { bytearray[0], bytearray[1] }, 0);
            return res;
        }
    }
}

读写M区 

由于使用的Nmodbus4库中的方法,每一个方法对应一个modbus通讯功能码,填写地址时直接填写M区或D区地址即可。

读写D区

 该实例为简单的读写plc数据实例,其余功能,可尽情发挥。

  • 13
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
C#中,可以使用Socket类来实现基于TCP/IP协议的PLC通信。下面是一个简单的示例代码,演示如何通过TCP/IP协议读写PLC: ```csharp using System; using System.Net.Sockets; class Program { static void Main(string[] args) { // PLC的IP地址和端口号 string plcIp = "192.168.0.1"; int plcPort = 502; try { // 创建TCP客户端套接字 using (TcpClient client = new TcpClient()) { // 连接到PLC client.Connect(plcIp, plcPort); // 获取网络流 using (NetworkStream stream = client.GetStream()) { // 发送读取请求 byte[] readRequest = new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x01 }; stream.Write(readRequest, 0, readRequest.Length); // 接收响应数据 byte[] response = new byte[1024]; int bytesRead = stream.Read(response, 0, response.Length); // 解析响应数据 // 这里根据PLC的协议进行解析,具体的解析方式需要参考PLC的文档 // 关闭连接 client.Close(); } } } catch (Exception ex) { Console.WriteLine("PLC通信发生错误:" + ex.Message); } } } ``` 在上述示例中,我们使用TcpClient类来创建一个TCP客户端套接字,然后使用Connect方法连接到PLC的IP地址和端口号。接着,通过GetStream方法获取网络流,并通过Write方法发送读取请求。然后,通过Read方法接收响应数据,并根据PLC的协议进行解析。最后,关闭连接。 请注意,上述代码仅为示例,实际的PLC通信协议和数据解析方式可能因PLC型号和厂商而异。您需要参考PLC的文档以了解具体的通信协议和数据解析方式。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值