首页 > 其他分享 >Modbus ASCII 获取数据

Modbus ASCII 获取数据

时间:2024-08-27 16:53:55浏览次数:11  
标签:字节 16 浮点数 serialPort Modbus 获取数据 串口 ASCII

根据银河高低温试验箱协议读取数据

1.协议内容

8.1:通讯协议介绍
8.1.5 通讯设置
本通讯协议使用异步串行通讯方式,1 个起始位、8 个数据位、2 个停止
位、无奇偶校验数据通讯格式,其中数据位8 位,第1 位为最高位(MSB),第8
位为最低位(LSB)。
8.1.6 数据格式
通讯采用直接存取S7-200 V 存储器数据的方式,所有的参数均放置于S7-200 V存储器中,S7-200 中的数据类型为BYTE(字节)、INT(有符号整数)、WORD(无符号整数)、DWORD(无符号长整)、LONG(有符号长整)、FLOAT
(浮点数)等格式,位操作按字节方式操作,一个字节8 个位。其中BYTE 长度
为1字节;INT 和WORD为2字节,先高后低;DWORD和LONG 为4字节,
先高后低;浮点数为4字节。详细资料可参考西门子SIMATIC S7-200 可编程控
制器系统手册。
8.1.7 读参数命令
命令格式:>MMVDUUUUr
>:起始字符
MM:机号(在编程时因该转换为16进制数据)
VD:读命令
UUUU:S7200 内部V 存储器地址(在编程时因该转换为16 进制数
据)
r:回车字符

响应数据格式:<MMVDUUUUaabbccddee…r
<MMVDUUUU:响应命令头
aabbccddee:从指定的V单元开始的128字节,每2个字符代表一个字节。
r:回车字符

8.1.8 PLC地址说明

参数名称 V地址单元 数据格式 数据说明
运行状态 904 int 0 停止 1 运行 2 暂停
温度测量值 804 float 单位:℃
湿度测量值 860 float 单位:RH%

2.使用串口助手调试

  1. 串口助手设置
串口参数 参数值
波特率 9600
数据位 8
停止位 2
校验位
流控
  1. 调试截图
    img
    命令说明 要在命令后面添加回车,否则PLC无法识别命令。
>00VD0388 :获取设备运行状态  返回结果: <00VD0388000000010000000200040000000000000000000000000000000000000000000000000000000000000000000000000000000000FA03B6000000FA0000FDDA0000
>00VD0324 :获取温度测量值    返回结果:<00VD032441EA980041EABDD541F6580041FBE0000000000044864400447EBA00000000000000000000000000000000000000000041C80000000000000000000000000000
>00VD035C :获取湿度测量值    返回结果:<00VD035C00000000000000000000000001000400000000000000000000000000000000000000000000000000000000000000000100000002000400000000000000000000

根据命令返回结果,解析数据,获取温度测量值和湿度测量值。

1.由于返回结果为16进制,需要将16进制进行状态。

2.温度测量值和湿度测量值在返回结果中的位置分别为:41EA9800和00000000,需要将这两个值转换为float类型。
3.运行状态在返回结果中的位置为:0000(截取命令后4位),转换为整数值为0。

4.温度测量值为41EA9800(截取命令后8位),转换为浮点数为:29.324219。

5.湿度测量值为00000000(截取命令后8位),转换为浮点数为:0。

3.C# 使用 SerialPort 发送命令接收数据

  1. 初始化串口信息并打开串口
        private void OpenCom()
        {

            // 创建SerialPort对象
            serialPort = new SerialPort(txtPort.Text.Trim(), 9600, Parity.None, 8, StopBits.Two);

            serialPort.ReadTimeout = 1000;   //串口读取超时时间
            serialPort.WriteTimeout = 1000;   //串口写入超时时间 
            // 打开串口
            serialPort.Open();
        }
  1. 发送命令并接收数据
重点:将字符串转换为ASCII码字节数组 byte[] asciiBytes = Encoding.ASCII.GetBytes(request); 如果不通过ASCII码字节数组发送,则无法正确接收数据。

img

public string SendOrderToPLC(string request)
        {
            string txt = string.Empty;
            try
            {
                OpenCom();
                 
                // 将字符串转换为ASCII码字节数组
                byte[] asciiBytes = Encoding.ASCII.GetBytes(request);

                // 发送字节数组
                serialPort.Write(asciiBytes, 0, asciiBytes.Length);
                //等待数据接收完成 数据量小等待时间可小,数据量大等待时间长
                Thread.Sleep(1000);

                ASCIIEncoding ascii = new ASCIIEncoding();
                byte[] readBuffer = new byte[serialPort.BytesToRead];
                serialPort.Read(readBuffer, 0, readBuffer.Length);

                if (readBuffer.Length > 14)
                {
                    txt = ascii.GetString(readBuffer);

                    // 关闭串口
                    serialPort.Close();
                    return txt;
                }
                else
                {
                    this.Invoke(new Action(() =>
                    {
                        this.labMes.Text = "No response received";
                    }));
                    serialPort.Close();
                    return txt;
                }
            }
            catch (Exception ex)
            {
                txt = null;
                this.Invoke(new Action(() =>
                {
                    this.labMes.Text = ex.Message;
                }));
                return txt;
            }
        }
  1. 处理数据
     处理设备运行状态数据
    //获取设备运行状态  ,取的是整数  所以16进制取4位;排除前面的<00VD0388命令  
    /*0 停止 1 运行 2 暂停 
     */
    var stringSub = result.Substring(9, 4); 
    var st = HexToDecimal(stringSub);

    处理温度数据
    /*温度取的是浮点数 所以16进制取8位;排除前面的 < 00VD0324命令  单位:℃
      */
    var stringSub = result.Substring(9, 8);
    var st = HexToDecimal(stringSub);


    /*湿度取的是浮点数 所以16进制取8位;排除前面的 < 00VD035C命令  单位:RH%
      */
    var stringSub = result.Substring(9, 8);
    var st = HexToDecimal(stringSub);

4.数据转换方法

        /// <summary>
        /// 将16进制字符串转换为浮点数
        /// </summary>
        /// <param name="hex"></param>
        /// <returns></returns>
        static double HexToDecimal(string hex)
        {
            uint intValue = Convert.ToUInt32(hex, 16);

            // 将整数值转换为单精度浮点数
            float floatValue = BitConverter.ToSingle(BitConverter.GetBytes(intValue), 0);

            // 输出结果
            Console.WriteLine("Hex: " + hex);
            Console.WriteLine("Float: " + floatValue);
            return floatValue;
        }

标签:字节,16,浮点数,serialPort,Modbus,获取数据,串口,ASCII
From: https://www.cnblogs.com/wofeiliangren/p/18383057

相关文章

  • Springboot获取数据库内容
    @ControllerpublicclassCon{@GetMapping("/sumView")publicStringsumView(Modelmodel,Stringdata){Liststudents=newArrayList<>();Stringsql="SELECT*FROMstuwhere学号=?;";//请替换为实际的SQL语句......
  • java在项目中实现个性化定制的数据可视化图表———静态,动态获取数据
    一、Echarts介绍ECharts是一款基于JavaScript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。ECharts最初由百度团队开源,并于2018年初捐赠给Apache基金会,成为ASF孵化级项目。2021年1月26日晚,Apache基金会官方宣布ECharts项目正式毕业。1月28日,EChar......
  • 帮助我们从曲线图中获取数据的软件分享——GetData Graph Digitizer
    在科技论文写作和数据分析过程中,我们常常需要将自己的数据与前人的研究成果进行对比。然而,有时我们只能从别人的论文中获得一张包含坐标轴的曲线图,而无法直接获取原始数据。在这种情况下,GetDataGraphDigitizer软件就显得尤为重要。今天,我将详细介绍这款软件,帮助大家轻松......
  • C#实现数据采集系统-数据反写(3)ModbusTcp写入数据模块开发
    写入报文分析//000100000006FF050001FF00写单个线圈//000100000006FF0600050023写单个寄存器//写多个寄存器//00060000000BFF1000020002040021002A//前7位相同,第八位功能码不同,九、十位写入地址,这是格式一样部分线圈......
  • Modbus-RTU详解及报文解析
    文章目录报文结构物理层数据链路层寻址主站状态机从站状态机介质管理应用层Client/Server模型CRC16校验及代码实现ModbusRTU报文分析案例01读取输出线圈02读取输入线圈03读取保持寄存器04读取输入寄存器05写入单个线圈(预置单线圈)06写入单个寄存器(预置单寄存器)0F写入多......
  • Modbus协议
    一、Modbus协议Modbus协议是一种软件协议,支持RS232(硬件层协议)、RS485(硬件层协议)、TCP/IP等多种电气接口。Modbus协议标准开放、无版权要求,消息帧格式简单,便于厂商开发和集成。Modbus可以在各种介质上传输,报文类型支持ASCII、RTU、TCP三种,使用串口传输时选择ASCII(字符)和RTU模......
  • ASCII和Unicode区别
    ASCII和Unicode的主要区别在于它们的编码范围、长度、兼容性、支持的语言种类以及编码方式。‌编码范围和长度‌:ASCII编码只能表示128个字符,包括英文字母、数字和一些标点符号,每个字符占用一个字节。而Unicode编码可以表示几乎所有语言的字符,包括拉丁文、中文、日文等,每个......
  • Axios请求使用params参数导致后端获取数据嵌套
    问题重述:首先看前端的axios请求这里我使用params参数将data数据传给后端letdata=JSON.stringify(this.posts);axios.post("/blog_war_exploded/insertPost",{params:{data:data......
  • linq快速动态获取数据库表字段名称、类型、数据
     varbj="Bj";             varpbj=typeof(Xs_xx).GetProperty(bj);//获得班级属性      /*      varcxbj=fromaainsjklj.Xs_xx            lety=(string)pbj.GetValue(aa,null)//linq......
  • EtherNet/IP从站转Modbus-RTU协议转换网关(推荐收藏吖)
    作者的许多朋友均对如何实现EtherNet/IP网络和Modbus-RTU网络的连接互通感到十分困扰,现在为大家统一作出解释。事实上,捷米特YC-DPM-EIP此款设备能够完美地解决这一问题。接下来,作者将会给各位全面且详尽地阐述该设备的功能、参数以及配置的方法。1.产品功能捷米特JM-EIP-RTU......