Modbus是PLC常用的通讯协议,经常用于与HMI通信。通过对此协议的分析,可以如同三菱MC协议一样,利用来与PC结合,发挥更大的作用。
Modbus 是一个应用层的通讯协议,位于 OSI 的第七层,在总线或者网络上的不同设备之间的,通过 客户端/服务端 的方式通讯,默认使用502端口进行通讯。
通讯示例:
// Remember: Big-endian values!
var responseADU = []byte{
// MBAP HEADER:
0x00, 0xFF, // Tx ID #255, typically an incremental value
0x00, 0x00, // Protocol ID, always 0
0x00, 0x0B, // Length of the following data (8+3=11)
0x00, // Unit identifier, 0 unless a Gateway is used
// PROTOCOL DATA UNIT:
0x03, // Function Code 03: Read Holding Registers
0x08, // Byte count of the following data (4*2=8)
0x00, 0x0A, // First register; value 10
0x0A, 0x00, // Second register; value 2560
0xFF, 0xFF, // Third register; value 65535 or -1 when signed.
0x00, 0x01, // Fourth register; value 1
}
| 代码 | 中文名称 | 位操作/字操作 | 操作数量 |
|---|---|---|---|
| 01h | 读线圈状态 | 位操作 | 单个或多个 |
| 02h | 读离散输入状态(只能读到0或1) | 位操作 | 单个或多个 |
| 03h | 读保持寄存器(保持寄存器可以通过06h功能写入) | 字操作 | 单个或多个 |
| 04h | 读输入寄存器(输入寄存器只能读取,不能通过06h功能写入) | 字操作 | 单个或多个 |
| 05h | 写单个线圈(线圈表示用来控制输出IO控制) | 位操作 | 单个 |
| 06h | 写单个保持寄存器 | 字操作 | 单个 |
| 0Fh | 写多个线圈 | 位操作 | 多个 |
| 10h | 写多个保持寄存器 | 字操作 | 多个 |
官方工具,不太好用,检测地址长度不能超过125,无法正确显示高低位转换的数据
链接: https://pan.baidu.com/s/19tEx6KzM0bjbCv342cA3zg
提取码: z44q
优点:可以同时显示多种类型的数据比较方便
缺点:检测地址长度不能超过125;无法正确显示高低位转换的数据;无法自动刷新

应该是最好用的工具了,长度没有限制,可以自动刷新,可以自定义数据的类型,并且可以处理高低位转换的场景
选择 connection -> connect

录入 modbus tcp server 的地址和端口号

setup -> Display Options -> floating point -> 选择高位优先,还是低位优先

在车间连接外网的机器上,把502端口映射到外网,方便远程调试。
官网 (https://dashboard.ngrok.com/get-started/setup) 注册账号,下载客户端
# 进入 rgrok 命令行工具所在目录
# 配置token
ngrok config add-authtoken {ngrok token}
# 映射modbus tcp server 到外网
ngrok tcp {modbus tcp server ip}:502
在plc中,有的是低位优先,也有的是高位优先,比如:
如果一个Int类型数组,占用4个字节,4个字节顺序为ABCD,那么采用big-endian大端字节顺序,那么在内存中即为ABCD,如果采用small-endian小端字节顺序,那么在内存中存储即为DCBA,但是在实际应用中,还有可能出现BADC或者CDAB的情况,因此我们在大小端的基础上做了一下扩展,定义了4种不同字节顺序,采用枚举类型表示,代码如下所示:
ABCD = 0, // 大端形式
BADC = 1, // 单字反转
CDAB = 2, // 双字反转
DCBA = 3, // 小端形式
import (
"bytes"
"encoding/binary"
"fmt"
"testing"
"time"
"github.com/simonvetter/modbus"
)
func Test_Modbus(t *testing.T) {
var client *modbus.ModbusClient
var err error
// for a TCP endpoint
// (see examples/tls_client.go for TLS usage and options)
client, err = modbus.NewClient(&modbus.ClientConfiguration{
URL: "tcp://ip:port", // 可以直接使用ngrok映射到外网的地址
Timeout: 1 * time.Second,
})
// note: use udp:// for modbus TCP over UDP
if err != nil {
fmt.Println(err.Error())
}
err = client.Open()
if err != nil {
fmt.Println(err.Error())
}
// uint
fmt.Println("uint read and write")
for i := 0; i <= 7; i++ {
address := uint16(i)
value := uint16(1)
v, err := client.ReadRegister(address, modbus.HOLDING_REGISTER)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println("address:", address, ",old value:", v)
err = client.WriteRegister(address, value)
if err != nil {
fmt.Println(err.Error())
}
v, err = client.ReadRegister(address, modbus.HOLDING_REGISTER)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println("address:", address, ",new value:", v)
}
// float
fmt.Println("float read and write")
bytes, err := client.ReadBytes(6, 4, modbus.HOLDING_REGISTER)
if err != nil {
fmt.Println(err.Error())
}
f, _ := bytesToFloat32(bytes)
fmt.Println("old value:", f)
err = client.WriteBytes(6, float32ToBytes(123.456))
if err != nil {
fmt.Println(err.Error())
}
bytes, err = client.ReadBytes(6, 4, modbus.HOLDING_REGISTER)
if err != nil {
fmt.Println(err.Error())
}
f, _ = bytesToFloat32(bytes)
fmt.Println("new value:", f)
}
modbus tcp: https://www.ad.siemens.com.cn/productportal/Prods/published/Comm/Comm_9.1/Comm_9.1.html
golang modbus: https://github.com/goburrow/modbus
modbus server:https://blog.csdn.net/weixin_42330983/article/details/124860023
Modscan32 https://www.sohu.com/a/443539826_651846
https://github.com/ffffffff0x/1earn/blob/master/1earn/Security/ICS/实验/Modbus仿真环境搭建.md
读写:https://github.com/simonvetter/modbus
华为Od必看系列华为OD机试全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理已参加机试人员的实战技巧华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典文章目录华为Od必看系列使用说明本期题目:任务总执行时长题目输入输出示例一输入输出说明go代码实现华为OD其它语言版本
目录Golang获取HTTP请求的IP地址HTTP的发展历史3,HTTP所在的网络层次4,HTTP请求与响应
关闭。这个问题需要debuggingdetails.它目前不接受答案。编辑问题以包含desiredbehavior,aspecificproblemorerror,andtheshortestcodenecessarytoreproducetheproblem.这将有助于其他人回答问题。关闭4年前。Improvethisquestion在golang代码中使用sql查询获取语法错误。golang中此SQL查询所需的正确语法:rows,errQuery:=dbCon.Query("SELECTB.LatestDate,A.SVRNameASServerName,A.DRIVE,A.Tot
给定表达式字符串exp,编写程序检查exp中“{”、“}”、“(”、“)”、“[”、“]的对和顺序是否正确。packagemainimport("fmt"stack"github.com/golang-collections/collections/stack")funcmain(){s:="(a[0]+b[2c[6]])){24+53}"stackO:=stack.New()stackmap:=map[string]string{"[":"]","(":")","{":"}"}varstr=""for_,num:=ranges{str=string(num)if(str=="{"||
关闭。这个问题是notreproducibleorwascausedbytypos.它目前不接受答案。这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topic在这里,这个问题的解决方式不太可能帮助future的读者。关闭3年前。Improvethisquestion如何通过使用此库在golang中传递数字来获取国家代码:https://godoc.org/github.com/nyaruka/phonenumbers?
为什么下面的代码会抛出意外的函数错误?我看到错误./func_correct.go:4:syntaxerror:unexpectedfunc,expectingnamepackagemainfunc(st*Stack)Pop()int{v:=0forix:=len(st)-1;ix>=0;ix--{ifv=st[ix];v!=0{st[ix]=0returnv}}return0}funcmain(){Pop()} 最佳答案 定义堆栈类型在main中为其创建一个变量对其调用Pop代码:packagemainimport"fmt"typ
Thisquestionalreadyhasanswershere:ForloopoftwovariablesinGo(3个答案)2年前关闭。我正在通过Gotour在Go中使用for循环我跑的时候packagemainimport"fmt"funcmain(){sum:=1forsum程序运行正常,输出为1024但是当我更改sum:=0时packagemainimport"fmt"funcmain(){sum:=0forsum它给出了错误的说法processtooktoolongProgramexited.编辑:我沉迷于Go巡回赛,以至于我无法意识到,我犯了一个逻辑错误:P。
关闭。这个问题需要debuggingdetails.它目前不接受答案。编辑问题以包含desiredbehavior,aspecificproblemorerror,andtheshortestcodenecessarytoreproducetheproblem.这将有助于其他人回答问题。关闭4年前。Improvethisquestion我有一个Json:{"id":"me","name":"myname","planets":{"EARTH":3,"MARS":4}}我不知道如何将planets字段解码为map[string]int,所以我将访问元素而无需解码它们,就像在这个例子中一样
我是Go(Golang)的新手。我写了一个简单的基准程序来测试MySQL的并发处理。当我增加并发channel数时,不断收到“dialtcp52.55.254.165:3306:getsockopt:connectionrefused”、“unexpectedEOF”错误。每个go例程都将1到n行批量插入到一个简单的客户表中。该程序允许设置可变插入大小(单个语句中的行数)和并行go例程的数量(每个go例程执行上面的一个插入)。程序在小数字row寻找线索。基于它们,我设置了数据库最大连接数以及“max_allowed_packet”和“max_connections”。我还设置了go
这个问题在这里已经有了答案:Functiondeclarationsyntax:thingsinparenthesisbeforefunctionname(3个答案)WhatsthedifferenceoffunctionsandmethodsinGo?(5个答案)ParameterbeforethefunctionnameinGo?[duplicate](1个回答)WhatdothebracketsafterfuncmeaninGo?[duplicate](1个回答)关闭8个月前。我正在学习Golang-在教程中我经常看到这样的语法:typeSomeTypestruct{//stru