Unity连接ModbusTcp发送读取寄存器

unity连接modbus需要有NModbus4.dll文件

文件地址: (下载地址)

1.配置一个modbus主站(MThings测试软件挺好用的)

2.unity用来连接

下面直接上代码

 

using Modbus.Device;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;


public class Concent_ : MonoBehaviour
{
    public ModbusMaster  modbusIpMaster;
    public TcpClient tcpClient;
    IPAddress address = new IPAddress(new byte[] { 127,0,0,1 });
    public int port = 502;
    
    public bool conen = false;
    public bool Reda_White = false;
    private ushort[] udata = new ushort[]{0x03};
    private ushort star=1;
    Thread mythread;
    //Thread youthread;
    public bool isconect = false;
    // Start is called before the first frame update
    void Start()
    {
        if (Connect (address.ToString (), port))
        {
            Debug.Log("连接成功");
        }
        else
        {
            Debug.Log("连接失败");
        }
    }
    public bool Connect(string ip, int port)
    {
        try
        {
            tcpClient = new TcpClient(ip, port);

            tcpClient.SendTimeout = 1;
            modbusIpMaster = ModbusIpMaster.CreateIp(tcpClient);
            //开启另一个线程(可用可不用)
            mythread = new Thread(WriteMessageFromClient);
            //线程开启
            mythread.Start();
            conen = true;          
            return true;         
        }
        catch (Exception ex)
        {

            tcpClient.Close();

            Debug.LogError(ex.Message);
            return false;
        }
    }

    public void WriteMessageFromClient()
    {
        while (conen)
        {
            try
            {
                if (Reda_White)
                {                  
                    Write_jiChunQi(star, udata);
                    Debug.Log("发送成功");                                      
                }
                if (kuse)
                {
                 ushort [] msg=  modbusIpMaster.ReadHoldingRegisters(0x01,1, 0x01);                  
                }               
            }
            catch
            {
                break;
            }
        }
        tcpClient.Close();
    }
    public void Write_jiChunQi(ushort star,ushort[]data)
    {
        modbusIpMaster.WriteMultipleRegisters(1,star, data);
        
    }   
    /// 10进制转16进制 
    private byte GetHex(string msg)
    {
        byte hex = Convert.ToByte(msg);
        return hex;
    }
    ///16进制转10进制 
    public int GetDex(string msg)
    {
        int res = Convert.ToInt32(msg,16);
        return res;
    }
    //退出的时候关闭连接
    private void OnApplicationQuit()
    {
        tcpClient.Close();
    }
    public bool kuse = false;
    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            //WriteMultipleRegisters(设备地址,寄存器起始地址, 要写入的值)  
            modbusIpMaster.WriteMultipleRegisters(0x01,star,udata);
            Debug.Log("发送成功");
        }
        if (Input.GetKeyDown (KeyCode.Space))
        {
            //ReadHoldingRegisters(设备地址, 寄存器起始地址, 读取数量);  读取多个寄存器
            ushort[] msg = modbusIpMaster.ReadHoldingRegisters(0x01, 1, 0x06);
            foreach (var item in msg)
            {
                Debug.Log(item);
            }                                 
        }
    }
   
}
Modbus连接

 读取AI模块

 public void Button_4()
    {
        //读取AI模块的值  功能码04    ReadInputRegisters(设备地址,起始地址,读取值的地址)        
        ushort[] msg = modbusIpMaster.ReadInputRegisters(0x01, 0x01, 0x01);
        foreach (var item in msg)                      
        {
            //转换二进制  item是十进制的
            string ooo = Convert.ToString(item, 2);
            string s= ooo;
             //因为数据采集模块是16位的 所以得往前面补0  变成一个16位数 
            for (int i = 0; i < 16 - ooo.Length; i++)
                s = s.Insert(0, "0");

             //遍历字符串长度
            for (int i =0;i<s.Length;i++)
            {                
                //看看字符串中哪一位是1 代表数据采集模块那个对应的孔 是开的状态 
                if (s[i].ToString() == "1")
                {
                    Debug.Log(16-i+ "");                   
                }                
            }

        }
    }

 

连接PLC1200

using S7.Net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
using Modbus.Device;


public class PLC_Controller : MonoBehaviour
{
    public enum PLCTYPE
    {
        S71200, S7200smart
    }

    Plc PLC1;//= new Plc(CpuType.S71200 ,"192.168.1.1",0,1);
    //在这里对Plc这类进行新建,public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot),这个函数是对连接的Plc进行一个访问初始化
    //需要的参数有PLC类型、IP地址、插槽号、机架号。其中后两项在博途CPU属性中可以查到。
    private TcpClient tcpClient;
    private  ModbusMaster modbusIpMaster;

    public PLCTYPE pLCTYPE = PLCTYPE.S71200;
    Thread PLCLink,NDATLink;
    public byte HighSet;

    public byte result;
    public double RealSet;
    public byte ReadValve;

    public ushort intValve;
    [Header ("模型cube")]
    public Cube_Ration Cube_Ration;
    float UnityHigh;
    // Start is called before the first frame update
    void Start()
    {
        BtnOpen();
       
    }

    public void BtnOpen()
    {

        try
        {
            if (pLCTYPE == PLCTYPE.S71200)
            {
                PLC1 = new Plc(CpuType.S71200, "192.168.1.88", 0, 1);  //这里的是做了一个外部设置IP地址的操作
                PLC1.Open();
            }
            else if (pLCTYPE == PLCTYPE.S7200smart)
            {
                PLC1 = new Plc(CpuType.S7200, "192.168.1.88", 0, 1);  //这里的是做了一个外部设置IP地址的操作
                PLC1.Open();
            }
           
           
            //打开与PLC的连接是有两种方式,一个是Open();另一个是OpenAsync(),两者之间的功能是一样的,前者可以返回错误信息,比较适合初学者。

            if (PLC1.IsConnected)   //判断是否连接
            {

                Debug.Log("Plc is Connected+连接成功");


                PLCLink = new Thread(LinkThread);
                PLCLink.Start();                    //这里我是想做一个阶段性的中断,所以选用另起线程,将查询和写入PLC的功能放入新的线程,数据处理在主线程。用来防止线程卡死。
            }
            else
            {
                Debug.Log("PLC 连接不成功,请检查IP地址、机架、插槽等是否正确");
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex);

        }
       
    }

    public void BtnClose()
    {
        try
        {
            PLC1.Close();     //关闭与PLC的连接
           
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
          
            throw;
        }
    }

    public void BtnRead()
    {
        //复位按键
        try
        {
            PLC1.Write("DB1.DBX0.0", true);  //我做的是Unity上的仿真PID所以需要一个复位按键。
            //PLC1.Write("M0.0", false);
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
           
            throw;
        }
    }
    bool db1;
    public void LinkThread()
    {
        while (true)
        {
            if (PLC1.IsConnected)
            {
                //RealSet = Convert.ToDouble(PLC1.Read("DB1.DBW2"));
                //读取PLC的值,这边我还没有做的很满意,大家可以根据S7.Net的说明书和自己的意图来写合适的代码
                //result = (byte)PLC1.Read("MB103");
                //intValve = (ushort)PLC1.Read("DB3.DBW12");
                //Debug.Log("DB1.DBW2:"+RealSet);
                Thread.Sleep(100);
                //Debug.Log ( PLC1.Read("DB1.DBX0.1"));
                RealSet = Convert.ToDouble(PLC1.Read("Q0.0"));
                Debug.Log(PLC1.Read("M0.0")+"   "+ RealSet+"  "+ Convert.ToInt16(PLC1.Read("VW0")));
                if (Convert.ToBoolean(PLC1.Read("M0.0"))==true|| sderr)
                {
                    Cube_Ration.ration = true;
                    Debug.Log("触发不触发:"+Cube_Ration.ration);
                }
                else
                {
                    Cube_Ration.ration = false;
                }
                if (sder )
                {
                    //PLC1.Write("DB1.DBW4", 110); //写入成功
                    
                    //BtnRead();
                    //Debug.Log(PLC1.Read("DB1.DBX0.1"));
                    PLC1.Write("Q0.1", 1 );
                    PLC1.Write("M0.1", 1);
                    Debug.Log("写入成功");
                }
                //else if (sderr)
                //{
                //    PLC1.Write("M0.1", false);
                //}

            }
                   
        }
    }
    
 

    private void OnApplicationQuit()
    {
        BtnClose();
    }
    bool sder = false;
    bool sderr = false;
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyUp (KeyCode.Space ))
        {
            sder = false;
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            sder = true;
        }
        if (Input.GetKeyUp(KeyCode.A))
        {
            sderr = false;
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            sderr = true;
        }
    }

}

 

plc_脚本随便挂在一个物体上面

下面是Cube 测试脚本,接受到PLC信号,cube旋转测试

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum 旋转轴
{
    X,Y,Z,NONE
}
public class Cube_Ration : MonoBehaviour
{
    [Header ("旋转速度")]
    public float rotionspeed = 250;
    public 旋转轴 rotationAxis = 旋转轴.NONE;
    public bool ration;
    public Vector3 axisv;
    public 旋转轴 rotationAxis_;
    public GameObject gam;
    private void Start()
    {
        Rotation_();

      
    }
    public void Rotation_()
    {
        switch (rotationAxis)
        {
            case 旋转轴.X:
                axisv = new Vector3 (1,0,0);
                break;
            case 旋转轴.Y:
                axisv = new Vector3(0, 1, 0);
                break;
            case 旋转轴.Z:
                axisv = new Vector3(0, 0, 1);
                break;
            case 旋转轴.NONE:
                axisv = Vector3.zero;
                break;
            default:
                break;
        }
        rotationAxis_ = rotationAxis;
    }
    void Update()
    {
        if (rotationAxis_!=rotationAxis)
        {
            Rotation_();
            Debug.Log("不一样了");
        }
        if (ration)
        {
            this.transform.RotateAround(this.transform.localPosition, axisv, Time.deltaTime* rotionspeed);
        }
    }
}

 

posted @ 2021-10-27 15:33  剑起苍穹  阅读(1631)  评论(0编辑  收藏  举报
/*鼠标点击特效*/