C#上位机与三菱PLC的通信04--MC协议之A-1E报文测试

到目前为止,还没有网上有哪个文章有我如此的报文分析,操作实例,一大批都是抄来抄去,没有截图,没有说明,没有实例,有卵用呀,仅以此文章献给最爱的粉丝,希望对各位大师有些启示。

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。 

1、A-1E协议回顾

 

上节文章完成了下面几项操作:

1、读取D100地址开始的2个int类型数据

2、 通过A1E进行D102的双字 DWord(Float) 读取,即读取float类型--4Byte 

3、通过A1E进行位的读取M16,M区的地址要转换成16进制,即读取bool类型数据

4、通过A1E进行字的写入,即向 D20,D21写入34,45

5、通过A1E向 D30 写入一个Float数据24.5,一个float占4个字节 

通过5个操作实例掌握了报文的结构,发送和接收都有报文的结构,但那是通过工具软件“网络调试助手”实现的,这节来通过C#代码组成报文结构并测试效果,需要用到vs2022开发工具,字节数组,socket通信等知识。

2、启动mc服务器

3、创建项目方案

打开VS2022,创建控制台项目

 

4、报文组装与测试

1、读取D100地址开始的2个int类型数据

发送:01 FF 0A 00 64 00 00 00 20 44 02 00 

响应:81 00 19 00 26 00 

 

2、 通过A1E进行D102的双字 DWord(Float) 读取,即读取float类型--4Byte 

发送:01 FF 0A 00 66 00 00 00 20 44 04 00  

接收:81 00 33 33 35 42 00 00 00 00  

3、通过A1E进行位的读取M16,M区的地址要转换成16进制,即读取bool类型数据

发送:00 FF 0A 00 10 00 00 00 20 4D 01 00 

接收:80 00 10  

 

4、通过A1E进行字的写入,即向 D20,D21写入34,45

发送:03 FF 0A 00 14 00 00 00 20 44 02 00 22 00 2D 00  

接收:83 00 

 

5、通过A1E向 D30 写入一个Float数据24.5,一个float占4个字节 

发送:03 FF 0A 00 1E 00 00 00 20 44 02 00 00 00 C4 41 

接收:83 00 

6、完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace MitSUBISHI.MCProtocol.Test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            MCTestA1E();  
            Console.WriteLine("执行完成!");
            Console.ReadKey();
        }

        private static void MCTestA1E()
        {
            // 连接
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect("192.168.1.3", 6000);

            #region 1、通过A1E进行D100地址按字进行读取2个,即读取int类型  

            //int len = 2;
            //byte[] bytes = new byte[] {
            //        0x01,
            //        0xFF,0x0A,0x00,
            //        0x64,0x00,0x00,0x00, // 起始地址
            //        0x20,0x44, // 存储区 
            //        (byte)(len%256),
            //        (byte)(len/256%256) // 读取长度
            //    };
            //socket.Send(bytes);
            //byte[] respBytes = new byte[len * 2 + 2];
            //socket.Receive(respBytes);

            //for (int i = 2; i < respBytes.Length; i++)
            //{
            //    //每2个字节一组
            //    byte[] temp = new byte[2];
            //    temp[0] = respBytes[i];
            //    temp[1] = respBytes[++i];
            //    Console.WriteLine(BitConverter.ToInt16(temp, 0));//字节数组转换成int16数据
            //}

            #endregion

            #region 2、通过A1E进行D102的双字 DWord(Float) 读取,即读取float类型--4Byte 

            //int len = 2;
            //byte[] bytes = new byte[] {
            //    0x01,//0x01代表按批量字
            //    0xFF,0x0A,0x00,
            //    0x66,0x00,0x00,0x00, // 起始地址
            //    0x20,0x44, // 存储区 
            //    (byte)(len*2%256),
            //    (byte)(len*2/256%256) // 读取长度
            //};
            //socket.Send(bytes);
            //byte[] respBytes = new byte[len * 2 * 2 + 2];
            //socket.Receive(respBytes);

            //for (int i = 2; i < respBytes.Length; i++)
            //{
            //    //每4个字节一组
            //    byte[] temp = new byte[4];
            //    temp[0] = respBytes[i];
            //    temp[1] = respBytes[++i];
            //    temp[2] = respBytes[++i];
            //    temp[3] = respBytes[++i];
            //    Console.WriteLine(BitConverter.ToSingle(temp, 0));//字节数组转换成float数据
            //}
            #endregion

            #region 3、通过A1E进行位的读取M16,M区的地址要转换成16进制,即读取bool类型数据

            //int len = 1;
            //byte[] bytes = new byte[] {
            //    0x00,  // 代表批量位
            //    0xFF,0x0A,0x00,
            //    0x10,0x00,0x00,0x00, // 起始地址
            //    0x20,0x4D, // 存储区 
            //    (byte)(len%256),
            //    (byte)(len/256%256) // 读取长度
            //};

            //socket.Send(bytes);
             最终的数据长度是多少个字节  
            //int readLen = (int)Math.Ceiling(len * 1.0 / 2);
            //byte[] respBytes = new byte[readLen + 2];
            //socket.Receive(respBytes);
            //string binaryStr = "";
            //List<string> tempList = new List<string>();
            //for (int i = 2; i < respBytes.Length; i++)
            //{
            //    binaryStr = Convert.ToString(respBytes[i], 2).PadLeft(8, '0');
            //    // 每转换一次可以拿两个位信息
            //    tempList.Add(binaryStr.Substring(0, 4));
            //    tempList.Add(binaryStr.Substring(4));
            //}
            //for (int i = 0; i < len; i++)
            //{
            //    Console.WriteLine(tempList[i] == "0001");
            //}

            #endregion

            #region 4、通过A1E进行字的写入,即向 D20,D21写入34,45
            //int len = 2;
            //short v1 = 34, v2 = 45;
            //byte[] bytes = new byte[] {
            //    0x03,  // 代表批量位字
            //    0xFF,0x0A,0x00,
            //    0x14,0x00,0x00,0x00, // 起始地址
            //    0x20,0x44, // 存储区 
            //    // 写入长度
            //    (byte)(len%256),//低位
            //    (byte)(len/256%256), //高位
            //    //第一个数据
            //    (byte)(v1%256),//低位
            //    (byte)(v1/256%256),//高位
            //    //第二个数据
            //    (byte)(v2%256),
            //    (byte)(v2/256%256)
            //};

            //socket.Send(bytes);
            //int readLen = (int)Math.Ceiling(len * 1.0 / 2);
            //byte[] respBytes = new byte[2];
            //socket.Receive(respBytes);
            //var obj = respBytes;
            //if (Convert.ToInt16(respBytes[1]) == 0)
            //{
            //    Console.WriteLine("写入成功");
            //}
            #endregion

            #region 5、通过A1E向 D30 写入一个Float数据24.5,一个float占4个字节

            int len = 1;   // 一个值是4个字节    2个寄存器
            float value = 24.5f;

            byte[] bytes = new byte[] {
                0x03,  // 代表批量字
                0xFF,0x0A,0x00,
                0x1E,0x00,0x00,0x00, // 起始地址
                0x20,0x44, // 存储区 
                (byte)(len*2%256),
                (byte)(len*2/256%256), // 写入长度
                BitConverter.GetBytes(value)[0],
                BitConverter.GetBytes(value)[1],
                BitConverter.GetBytes(value)[2],
                BitConverter.GetBytes(value)[3]
            };

            socket.Send(bytes);

            int readLen = (int)Math.Ceiling(len * 1.0 / 2);
            byte[] respBytes = new byte[2];
            socket.Receive(respBytes);
            var obj = respBytes;
            if (Convert.ToInt16(respBytes[1]) == 0)
            {
                Console.WriteLine("写入成功");
            }

            #endregion
        }
    }
}

5、小结

 

到目前为止,还没有网上有哪个文章有我如此的报文分析,操作实例,一大批都是抄来抄去,仅以此文章献给最爱的粉丝,希望对各位大师有些启示。

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。

原创真的不容易,走过路过不要错过,点赞关注收藏又圈粉,共同致富。 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/390206.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3 之 商城项目—结算模块

路由配置 chekout/index.vue <script setup> const checkInfo {} // 订单对象 const curAddress {} // 地址对象 </script> <template><div class"xtx-pay-checkout-page"><div class"container"><div class"w…

lenovo联想小新 Pro14 2022 Intel版IAH5R,AMD版ARH5R(82UT),(82UU)原装出厂Win11系统带恢复重置功能

联想小新Pro14笔记本电脑恢复原厂OEM预装Windows11系统镜像包&#xff0c;开箱状态时一模一样 Intel版(82UT)链接&#xff1a;https://pan.baidu.com/s/1jexQXkC6TerUnDQffwLooA?pwdcc09 提取码&#xff1a;cc09 AMD锐龙版(82UU)链接&#xff1a;https://pan.baidu.com/s/…

【FPGA开发】HDMI通信协议解析及FPGA实现

本篇文章包含的内容 一、HDMI简介1.1 HDMI引脚解析1.2 HDMI工作原理1.3 DVI编码1.4 TMDS编码 二、并串转换、单端差分转换原语2.1 原语简介2.2 IO端口组件 笔者在这里使用的开发板是正点原子的达芬奇开发板&#xff0c;FPGA型号为XC7A35TFGG484-2。参考的课程是正点原子的课程手…

Calendar的使用(Java)

直接从需求来理解&#xff1a;将2024年2月16日增加一个月 如果不使用Calendar的话&#xff0c;我们需要定义字符串记住这个日期&#xff0c;然后把字符串解析成Date日期对象&#xff0c;通过Date日期对象获取其毫秒值&#xff0c;然后增加一个月的毫秒值&#xff0c;再格式化时…

蓝桥杯第十四届电子类单片机组程序设计

目录 前言 蓝桥杯大赛历届真题&#xff08;点击查看&#xff09; 一、第十四届比赛题目 1.比赛原题 2.题目解读 1&#xff09;任务要求 2&#xff09;注意事项 二、任务实现 1.NE555读取时机的问题 1&#xff09;缩短计数时间 2&#xff09;实时读取 2.温度传感器读…

社区养老|社区养老服务系统|基于springboot社区养老服务系统设计与实现(源码+数据库+文档)

社区养老服务系统目录 目录 基于springboot社区养老服务系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员部分功能 &#xff08;1&#xff09; 用户管理 &#xff08;2&#xff09;服务种类管理 &#xff08;3&#xff09;社区服务管理 &#xff08…

MySQL 基础知识(八)之用户权限管理

目录 1 MySQL 权限管理概念 2 用户管理 2.1 创建用户 2.2 查看当前登录用户 2.3 修改用户名 2.4 删除用户 3 授予权限 3.1 授予用户管理员权限 3.2 授予用户数据库权限 3.3 授予用户表权限 3.4 授予用户列权限 4 查询权限 5 回收权限 1 MySQL 权限管理概念 关于 M…

NodeJS背后的人:Express

NodeJS背后的人&#xff1a;Express 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 文章简单学习总结&#xff1a;如有错误 大佬 &#x1f449;点. 前置知识&#xff1a;需要掌握了解&#xff1a; JavaScript基础语法 、Node.JS环境API 、前端工程\模块化 …

ESP32学习(3)——连接WIFI

1.简介 Wi-Fi是基于IEEE 802.11标准的无线网络技术 让联网设备以无线电波的形式&#xff0c;加入采用TCP/IP通信协议的网络. Wi-Fi设备有两种模式&#xff1a; 1.Access Point(AP) 模式&#xff0c;此为无线接入点&#xff0c;家里的光猫就是结合WiFi和internet路由功能的AP。…

Javaweb之SpringBootWeb案例之AOP通知类型的详细解析

3.1 通知类型 在入门程序当中&#xff0c;我们已经使用了一种功能最为强大的通知类型&#xff1a;Around环绕通知。 Around("execution(* com.itheima.service.*.*(..))") public Object recordTime(ProceedingJoinPoint pjp) throws Throwable {//记录方法执行开始…

I/O并行口直接驱动LED显示

1&#xff0e;  实验任务 如图所示&#xff0c;利用AT89S51单片机的P0端口的P0.0&#xff0d;P0.7连接到一个共阴数码管的a&#xff0d;h的笔段上&#xff0c;数码管的公共端接地。在数码管上循环显示0&#xff0d;9数字&#xff0c;时间间隔0.2秒。 2&#xff0e;  电路原…

第7章 Page449~451 7.8.9智能指针 std::shared_ptr

“shared_ptr”是“共享式智能指针”。 即多个“shared_ptr”之间可以管理同一个裸指针。于是 O* o new O; //一个裸指针 std::shared_ptr <O> p1(o); //交给p1管 std::shared_ptr <O> p2(o); //又交给p2管 出乎意料&#xff0c;以上代码仍然是可以通过编译但运…

IO流---缓冲流,转换流,打印流,序列化流

缓冲流 缓冲流&#xff08;Buffered Stream&#xff09;也被称为高效流&#xff0c;它是对基本的字节字符流进行增强的一种流。通过缓冲流&#xff0c;可以提高数据的读写能力。 在创建缓冲流对象时&#xff0c;会创建一个内置的默认大小的缓冲区数组。通过对缓冲区的读写&…

JDBC教程+数据库连接池

JDBC 1.JDBC概述 ​ JDBC&#xff0c;全称Java数据库连接&#xff08;Java DataBase Connectivity&#xff09;&#xff0c;它是使用Java语言操作关系型数据库的一套API。 ​ JDBC本质是官方&#xff08;原SUN公司&#xff0c;现ORACLE&#xff09;定义的一套操作所有关系型数…

35岁转行,是我人生中最正确的选择

前言 经常听到有人说&#xff0c;35岁是职场的分水岭&#xff0c;但我觉得我的35岁&#xff0c;人生才刚刚开始。 35岁前后&#xff0c;我生二胎&#xff0c;考研&#xff0c;跳槽&#xff0c;转行&#xff0c;从传统行业到服务业&#xff0c;从服务业到新能源行业&#xff0…

静态时序分析:SDC约束命令set_clock_transition详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在静态时序分析&#xff1a;SDC约束命令create_clock详解一文的最后&#xff0c;我们谈到了针对理想(ideal)时钟&#xff0c;可以使用set_clock_transition命令直…

函数、极限、连续——刷题(3

目录 1.题目&#xff1a;2.解题思路和步骤&#xff1a;3.总结&#xff1a;小结&#xff1a; 1.题目&#xff1a; 2.解题思路和步骤&#xff1a; 3.总结&#xff1a; 首先还是考虑好所有情况&#xff08;所有情况见&#xff1a;函数、极限、连续——刷题&#xff08;1&#xff…

JVM-垃圾回收(标记算法,收集器)

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 垃圾回收的基本原理 1 什么是垃圾&#xff1f; 在…

并发编程(1)基础篇

1 概览 1.1 这门课讲什么 这门课中的【并发】一词涵盖了在 Java 平台上的 进程线程并发并行 以及 Java 并发工具、并发问题以及解决方案&#xff0c;同时也会讲解一些其它领域的并发 1.2 为什么学这么课 我工作中用不到并发啊&#xff1f; 那你还是没有接触到复杂项目. …

JS如何判断普通函数与异步(async)函数

这里可以先打印一下普通函数和异步&#xff08;async&#xff09;函数的结构&#xff0c;如下图 可以看出两者原型链&#xff0c;普通函数的原型链指向的是一个函数&#xff0c;异步&#xff08;async&#xff09;函数原型链指向的是一个AsyncFunction&#xff0c;这时就会想到…