Unity轨道ModBus使用步骤

Unity对接轨道屏ModBus步骤:

​ 将NModbus4.dll导入到Unity的Plugin下

NModbus4.dll百度网盘下载地址
链接:https://pan.baidu.com/s/1wAFljFuGdpCUGgb8-7gRSA?pwd=y38v 
提取码:y38v 
  1. 连接串口!
    • 调用OpenSerial方法进行连接。
  2. 在开启Unity项目时,如果轨道是断电重启的,就需要重新给轨道设置初始位置。
    • 首先要请求回参,向左复位或者向右复位,复位到限位器位置
    • 需要一直读取寄存器状态,直到SQ1电平(右)或SQ2电平(左)的值为0时,是到达限位器位置 (0=>到限位 1=>未到限位)
    • 到达限位器后需要向左或者向右移动30个脉冲,也就是差不多10毫米左右
    • 移动完成后将轨道现在的位置设置为0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO.Ports;
using Modbus.Device;
using System.Threading;

namespace Modbus485
{
    class MotorCtrl
    {

        enum MDRESULT
        {
            MDERR_SUCCESS,      // 成功
                                /*以下为MODBUS错误*/
            MDERR_FUNC = 0x01,  // 无效功能码
            MDERR_ADDR,         // 无效寄存器地址
            MDERR_VALUE,        // 无效寄存器数据
            MDERR_FAIL,         // 操作失败
            MDERR_ENSURE,       // 请求已被确认
            MDERR_BUSY,         // 设备忙
            MDERR_PARITY = 0x08,    // 奇偶检验错误
            MDERR_BADGATEWAY = 0x0a, // 不可用的网关路径
            MDERR_GATEWAYERR,       // 网关目标设备响应失败
                                    /*以下为扩展错误*/
            MDERR_FORBIDDEN = 0x40,  // 禁止操作
            MDERR_NOTSTUDY = 0x60,   // 尚未学习
            MDERR_NOTOPEN = 0x80, // 串口未打开
            MDERR_COMM,         // 通讯错误	(从机返回的地址或响应命令不一致)
            MDERR_TIMEOUT,      // 操作超时
            MDERR_BUFFER,       // 数据长度超出缓冲区的容量
            MDERR_UNDEF = 0xff	// 未定义错误
        }

        public struct RTSTATUS
        {
            public short nPWM;         // PWM
            public ushort nAmp;          // 电机电流 电流值的1/10 单位mA
            public short nPhaseFreq;           // 换向频率
            public ushort nFinishSta;            // 完成状态
            public ushort nPhasePosHi;           // 脉冲数高半字
            public ushort nPhasePosLo;           // 脉冲数低半字
            public ushort nLeftTimeHi;   // 完成时间高半字
            public ushort nLeftTimeLo;   // 完成时间低半字

            public short nIN1Voltage;  // AI1电压  电压值的1/10 单位mV
            public short nIN2Voltage;  // AI2电压	电压值的1/10 单位mV
            public short nIN3Voltage;  // AI2电压	电压值的1/10 单位mV
            public short nDiffVoltage; // 差分电压

            public ushort bSQ1Level;     // SQ1电平  右  0(到限位)/ 1(未到限位)
            public ushort bSQ2Level;     // SQ2电平  左  0(到限位)/ 1(未到限位)
            public ushort nInPWM;            // 输入PWM
            public short nInFreq;      // 输入频率
            public ushort nInPulseHi;        // 输入脉冲高半字
            public ushort nInPulseLo;        // 输入脉冲低半字
            public ushort nLockSta;      // 堵转状态
            public ushort nErrorSta;     // 错误状态
            public ushort nMotorSpd;     // 电机转速
            public ushort bSpdDiv10;     // 转速是除以10的
            public ushort bSpdMulti;         // 转速量程乘以10
            public short nTemperature;     // 温度
            public ushort nPowerVoltage;		// 电源电压
        }

        RTSTATUS rtstatus = new RTSTATUS();
        /// <summary>
        /// 私有串口实例
        /// </summary>
        public SerialPort serialPort = new SerialPort();

        /// <summary>
        /// 私有ModbusRTU主站字段
        /// </summary>
        public static IModbusMaster master;
        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="_COM">端口</param>
        /// <param name="_BaudRate">波特率</param>
        /// <param name="_Parity">奇偶校验</param>
        /// <param name="_DataBits">数据位</param>
        /// <param name="_StopBits">停止位</param>
        public bool OpenSerial(string _COM, int _BaudRate = 115200, Parity _Parity = Parity.Even, int _DataBits = 8, StopBits _StopBits = StopBits.One)
        {
            try
            {
                //设定串口参数
                serialPort.PortName = _COM;
                serialPort.BaudRate = _BaudRate;
                serialPort.Parity = _Parity;
                serialPort.DataBits = _DataBits;
                serialPort.StopBits = _StopBits;

                //创建ModbusRTU主站实例
                master = ModbusSerialMaster.CreateRtu(serialPort);

                //打开串口
                if (!serialPort.IsOpen) serialPort.Open();
                master.Transport.Retries = 0;
                master.Transport.ReadTimeout = 200;
                master.Transport.WriteTimeout = 200;

                return true;
            }
            catch (Exception)
            {
                return false;
            }

            //关闭串口
            //serialPort.Close();
        }
        public void CloseSerial()
        {
            //if (serialPort.IsOpen) 
            serialPort.Close();
        }
        /// <summary>
        /// 判断是否打开
        /// </summary>
        /// <returns></returns>
        public bool isOpen()
        {
            return serialPort.IsOpen;
        }

        /// <summary>
        /// 复位!   
        /// </summary>
        /// <param name="addr"></param>
        /// <param name="mode">3 向左</param>
        public void Ref(byte addr, ushort mode = 3)
        {
            master.WriteSingleRegister(addr, 0xaa, mode);
        }
        /// <summary>
        /// 设置位置为0
        /// </summary>
        /// <param name="addr"></param>
        public void Set0(byte addr)
        {
            master.WriteSingleRegister(addr, 0x700a, 1);
        }
        /// <summary>
        /// 向右移动
        /// </summary>
        public void MoveRight(byte addr, ushort speed)
        {
            master.WriteSingleRegister(addr, 0x43, speed);
        }

        /// <summary>
        /// 向左移动
        /// </summary>
        public void MoveLeft(byte addr, ushort speed)
        {
            master.WriteSingleRegister(addr, 0x43, (ushort)-speed);
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void MoveStop(byte addr)
        {
            master.WriteSingleRegister(addr, 0x40, 0);
        }

        /// <summary>
        /// 移动到指定位置
        /// </summary>
        public void MoveGo(byte addr, ushort speed, int targetPos)
        {
            int setPos = targetPos * 240 / 95;
            SetPosition(addr, speed, (ushort)setPos);
        }

        private void SetPosition(byte addr, ushort speed, ushort value, int bRelative = 0)
        {
            ushort[] wSpd = new ushort[4];
            wSpd[0] = speed;    // 速度
            wSpd[1] = (ushort)bRelative;// 是否为相对位置, 0: 相对, 1: 绝对
            wSpd[2] = (ushort)(value >> 16);
            wSpd[3] = value;

            master.WriteMultipleRegisters(addr, 0x44, wSpd);
        }

        /// <summary>
        /// 读取寄存器 位置
        /// </summary>
        public double ReadStatus(byte addr)
        {
            ushort[] pos = master.ReadHoldingRegisters(addr, 0x24, 2);
            long Pos_Pus = (long)(pos[0] << 16) | pos[1];
            double Pos_mm = Pos_Pus * 95.0 / 240;

            return Pos_mm;
        }
        /// <summary>
        /// 读取寄存器状态 位置
        /// </summary>
        public RTSTATUS ReadState(byte addr)
        {
            ushort[] statusU = master.ReadHoldingRegisters(addr, 0x20, 25);
            RTSTATUS status = new RTSTATUS()
            {
                nPWM = (short)statusU[0],     // PWM
                nAmp = statusU[1],       // 电机电流 电流值的1/10 单位mA
                nPhaseFreq = (short)statusU[2],           // 换向频率
                nFinishSta = statusU[3],            // 完成状态
                nPhasePosHi = statusU[4],           // 脉冲数高半字
                nPhasePosLo = statusU[5],           // 脉冲数低半字
                nLeftTimeHi = statusU[6],   // 完成时间高半字
                nLeftTimeLo = statusU[7],   // 完成时间低半字

                nIN1Voltage = (short)statusU[8],  // AI1电压  电压值的1/10 单位mV
                nIN2Voltage = (short)statusU[9],  // AI2电压	电压值的1/10 单位mV
                nIN3Voltage = (short)statusU[10],  // AI2电压	电压值的1/10 单位mV
                nDiffVoltage = (short)statusU[11], // 差分电压

                bSQ1Level =statusU[12],     // SQ1电平  右  0(到限位)/ 1(未到限位)
                bSQ2Level = statusU[13],     // SQ2电平  左  0(到限位)/ 1(未到限位)
                nInPWM = statusU[14],            // 输入PWM
                nInFreq = (short)statusU[15],      // 输入频率
                nInPulseHi = statusU[16],        // 输入脉冲高半字
                nInPulseLo = statusU[17],        // 输入脉冲低半字
                nLockSta = statusU[18],    // 堵转状态
                nErrorSta = statusU[19],    // 错误状态
                nMotorSpd = statusU[20],     // 电机转速
                bSpdDiv10 = statusU[21],     // 转速是除以10的
                bSpdMulti = statusU[22],         // 转速量程乘以10
                nTemperature = (short)statusU[23],     // 温度
                nPowerVoltage = statusU[24],     // 电源电压
            };
            return status;
        }

    }
}

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity Modbus RTU是一个在Unity游戏开发引擎中实现Modbus RTU通信协议的工具。Modbus RTU是一种串行通信协议,用于在工业自动化领域中,将不同设备之间的数据传输和控制。 Unity Modbus RTU可以让开发者在Unity中轻松地与支持Modbus RTU协议的设备进行通信。它提供了一系列的API,使得开发者能够方便地读取和写入设备寄存器中的数据。开发者只需通过简单的代码,即可实现与设备之间的连接和数据交换。 Unity Modbus RTU还提供了灵活的配置选项,开发者可以设置通信的串口参数(如波特率、数据位、校验位等)和从设备地址。这使得Unity Modbus RTU能够与不同类型的Modbus RTU设备兼容,并且可以适应不同的通信环境需求。 通过使用Unity Modbus RTU,开发者可以轻松地实现在Unity中与工业自动化设备进行通信的功能。无论是读取传感器数据、控制执行器,还是进行设备状态监控,Unity Modbus RTU都能够提供便捷的解决方案。 总而言之,Unity Modbus RTU是一个强大的Unity插件,可以让开发者在游戏开发中与Modbus RTU设备进行通信,并实现数据交换和控制。它为Unity中的工业自动化应用提供了便捷的解决方案,为开发者节省了大量的时间和精力。 ### 回答2: Unity Modbus RTU是一个现代化的基于Unity引擎的Modbus RTU通信协议库。Modbus是一个通信协议,用于在工业自动化系统中连接不同设备,例如传感器、执行器等。Unity Modbus RTU实现了Modbus RTU协议的功能,使得用户可以在Unity引擎中轻松地集成和控制多种设备。 Unity Modbus RTU具有以下特点和优势: 1. 简便易用:Unity Modbus RTU提供了简洁、易懂的接口和文档,使得用户可以轻松地集成Modbus RTU通信功能。 2. 高效稳定:Unity Modbus RTU经过优化,具有良好的性能和稳定性,能够保证数据的准确传输和实时响应。 3. 多设备支持:Unity Modbus RTU支持连接和控制多种设备,包括传感器、执行器、PLC等。用户可以通过该协议库实现设备之间的通信和数据交换。 4. 可扩展性:Unity Modbus RTU提供了灵活的接口和功能,可以根据用户的需求进行扩展和定制化。 总而言之,Unity Modbus RTU是一个方便、高效、稳定的Modbus RTU通信协议库,适用于Unity引擎,并且支持多种设备的集成和控制。 ### 回答3: Unity Modbus RTU是一种通信协议,用于实现Modbus RTU通信。Modbus RTU是一种串行通信协议,它常用于连接PLC(可编程逻辑控制器)和其他设备,以实现数据的读取和控制。 Unity Modbus RTU具有以下特点: 1. 高效的通信速度:通过串行通信,Unity Modbus RTU能够以快速且稳定的速度传输数据,实现实时的数据交互。 2. 灵活的连接方式:Unity Modbus RTU可以通过串口、网络或者无线连接,以满足不同场景下的通信需求。 3. 易于操作:Unity Modbus RTU具有简单而直观的操作界面,用户可以方便地进行配置和管理。 4. 可靠的传输机制:Unity Modbus RTU采用CRC(循环冗余校验)机制,确保数据的可靠传输和完整性。 Unity Modbus RTU适用于各种工业控制系统,如自动化生产线、过程控制系统等。通过使用Unity Modbus RTU,用户可以轻松实现对设备的数据读取和控制,提高生产效率并优化系统运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值