一、基础知识
1. 字节
字节来自英文byte,习惯上用大写的“B”表示。字节是计算机中数据处理的基本单位。计算机中以字节为单位存储和解释信息,规定一个字节由八个二进制位构成,即1个字节等于8个比特(1Byte=8bit),八位二进制数最小为00000000,最大为11111111;通常1个字节可以存入一个ASCII码(1个英文字母=1个字节),2个字节可以存放一个汉字国标码(1个汉字=2个字节)
2. 字
来自英文word,计算机进行数据处理时,一次存取、加工和传送的数据长度称为字(word)。
一个字通常由一个或多个(一般是字节的整数位)字节构成,例如286微机的字由2个字节组成,它的字长为16;486微机的字由4个字节组成,它的字长为32位机。计算机的字长决定了其CPU一次操作处理实际位数的多少,由此可见计算机的字长越大,其性能越优越。
32位计算机:1字=32位=4字节
64位计算机:1字=64位=8字节
3. 位
来自英文bit,表示二进制位。位是计算机内部数据储存的最小单位,一个二进制位只可以表示0和1两种状态;两个二进制位可以表示00、01、10、11四种状态;三位二进制数可表示八种状态,以此类推。
1字节=8位(1byte = 8bit) ,字长是8,即:0000(高位) 0000(低位)。
1字=2字节(1word = 2byte),字长为16
二、帧格式
1. FINS命令格式
发送的命令格式:Text区域最大2000个字节。其余每一小格一个字节。
80 00 02 00 D2 00 00 39 00 00 0101 B2 000A00 0004
ICF RSV GCT DNA DA1 DA2 SNA SA1 SA2 SID CMDCODE TEXT
响应的命令格式:Text区域最大1998个字节。其余每一小格一个字节。
C0 00 02 00 39 00 00 D2 00 00 0101 0000 0001 0001 0001 0001
ICF RSV GCT DNA DA1 DA2 SNA SA1 SA2 SID CMDCODE ENDCODE TEXT
2. 命令格式拆解说明
2.1. ICF
ICF,Information Control Field(信息控制领域)
大小为2个字节,第7位始终为1,第六位根据命令或响应,命令帧为0,响应帧为1。第1~5位总是0,这里命令帧需要设置成0,响应帧则不需要。
2.2. RSV
RSV,Reserved(预留)总是00.
2.3. GCT
GCT,Gateway Count(网关数)根据PLC版本,这里设置成02。
2.4. DNA
Destination network address目标网络号
00:本地网络
01~7F: 远程网络(1~127)
2.5. DA1
Destination node address目标节点地址(目标IP的尾号)
00:本地PLC内部连接
01~20:Controller Link 网络(1~32)
01~FE:Ethernet(1~254)
FF:广播
2.6. DA2
Destination unit address目标单元号
00:CPU单元
FE:Controller Link单元或Ethernet 单元连接到网络
10~1F:CPU总线单元
E1:内插板
2.7. SNA
Source network address源网络号
00:本地网络
01~7F:远程网络(1~127)
2.8. SA1
Source node address源节点地址(本机IP的尾号)
00:PLC内部连接
01~20:Controller Link网节点号(1~32)
01~FE:Ethernet(1~254)
2.9. SA2
Source unit address源单元号
00:CPU单元或PC主机
10~1F:CPU总线单元
2.10. SID
Service ID可以理解为时序号, 00~FF之间任意设置。
2.11. COMMOND CODE 、TEXT
请求帧命令和内容部分:
2.11.1. Command code
命令码,十六进制,常用的有0101读取内存区,0102写入内存区
2.11.2. Memoryarea code
内存区代码,常用的 DM区(D区)的字控制的代码为82,HR区(H区)字控制为B2
2.11.3. Beginning read address
读数据区的起始地址,由3个字节表示。
例如:要读取从第10个字开始的数据,则为000A00,从第100个字开始则为006400。
2.11.4. Number of read elements
需要读取的字(WORD)的数量。由2个字节表示。
例如:要读取10个字,则为000A;要读取100个字,则为0064。
响应帧命令和内容部分:
命令码同上,End code为0000时正常,其他为异常(异常码自行网上搜索),读取数据则按命令要求读取字数。
三、调试工具
网络调试工具:NetAssist
四、实战
业务场景
- 业主现场使用的是 CS/CJ系列PLC
- 某大道ACU02的分区3对应的IP和端口:192.168.100.210:9600
- 本地调试机IP和端口:192.168.100.57:9000
- ACU02分区3舱室设备分布图
- 状态:1 开 0 关
1.TCP方式
待补充
2.UDP方式
2.1 照明设备
【照明】读请求
请求内容:查看H10.00,H11.00,H12.00,H13.00的照明状态
请求命令:80000200D200003900000101B2000A000004
示例:800002 00 D2 00 00 39 00 00 0101 B2 000A00 0004
参数解释:
D2:目标IP尾号,192.168.100.210的尾号是十进制210,换算成16进制为:D2
39:本机IP尾号,192.168.100.57的尾号是十进制57,换算成16进制为:39
0101:读请求,使用0101读命令,命令查看见Command code命令码
B2: 反馈区H10.00可知为 H区,H区对应的word码为:B2,命令查看见Memoryarea code内存区代码
000A00:读数据区的起始地址,3个字节表示,前两个字节标识word,后一个字节标识浮点(不用管),H10.00
为第10个位置,将十进制的10转换为二进制为A,即000A,带上后一个字节的浮点,即000A00
0004: 表示向后读4个字,一个字16位
【照明】读请求的返回
示例:
C00002 003900 00D200 00 0101 0000 0001 0001 0001 0001
C00002 003900 00D200 00 0101 0000 0000 0000 0000 0000
39: 本机IP尾号
D2:目标IP尾号
0101:读请求
0000 :正常反馈
0001 0001 0001 0001:查询返回数据,4个字,4台全开
0000 0000 0000 0000:查询返回数据,4个字,4台全关
【照明】写请求
请求内容:将H10.00的照明进行开关配置
请求命令:80000200D200003900000102B2000A00000200010001
示例:80000200D200003900000102B2006E00000200010001
80000200D20000390000: 和读请求一样
0102:写请求,使用0102写命令,命令查看见Command code命令码
B2:反馈区H110.00可知为 H区,H区对应的word码为:B2,命令查看见Memoryarea code内存区代码
006E00:读数据区的起始地址,3个字节表示,前两个字节标识word,后一个字节标识浮点(不用管),注意这里的照明施工现场设置的开或关是控制的一组灯,而不是1个
0002:写两个字,即控制 H110和H111这两个连续点的灯(两组灯)
0001:第一个字的状态 0000 0000 0000 0001(0001)
0001:第二个字的状态 0000 0000 0000 0001(0001)
【照明】写请求的返回
示例:C00002 003900 00D200 00 0102 0000
39: 本机IP尾号
D2:目标IP尾号
0102:读请求
0000 :正常反馈
草稿纸(仅供参考)
***【照明】***
【照明】读请求:
800002 00D200 003900 00 0101 B2 000A00 0004
【照明】写请求:
80000200D200003900000101B2000A000004(读)(读四个灯,注意是反馈区地址)
80000200D200003900000102B2006E00000200010001(写0002 0001 0001,开两灯,注意是控制区地址)
返回示例:
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
【照明】读返回:
C00002 003900 00D200 00 0101 0000 0001 0001 0001 0001 (4台全开)
C00002 003900 00D200 00 0101 0000 0000 0000 0000 0000 (4台全关)
【照明】写返回:
C00002 003900 00D200 00 0102 0000
2.2 智能井盖
注意事项:施工现场的井盖只能控制 锁扣,不能控制井盖的抬起和下压,所以只能远程控制锁扣的开关,真实井盖的关闭,需要操作人员在实地进行打开或者闭合,但是可以查询到井盖的打开和关闭状态
命令读写原理同照明,不做赘述
草稿纸(仅供参考)
*****【智能井盖】*****
800002 00D200 003900 00 0101(读) 82(D区) 019000 0001
800002 00D200 003900 00 0102(写) 82(D区) 01F400 0001 0001(锁扣打开)注意:开关状态都是1
800002 00D200 003900 00 0102(写) 82(D区) 01F600 0001 0001(锁扣关闭)注意:开关状态都是1
【智能井盖】读请求:
80000200D200003900000101820190000005(这里连读了5个字,可单独指定地址读1个字)
返回示例:
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
C00002 003900 00D200 00 0102 0000
【智能井盖】读返回:
C00002 003900 00D200 00 0101 0000 0000 0000 0001 0000 0001 (关X开x开)
C00002 003900 00D200 00 0101 0000 0001 0000 0000 0000 0001 (开X关x开)
C00002 003900 00D200 00 0101 0000 0000 0000 0001 0000 0001 (关X开x开)
【智能井盖】写请求:
锁扣打开:80000200D2000039000001028201F40000010001
锁扣关闭:80000200D2000039000001028201F60000010001
【智能井盖】写返回
C00002 003900 00D200 00 0102 0000
2.3 排风机
注意事项:注意,这里是存在浮点数float,点位有小数点,计算读取一个字,字长为16,足够装下排风机的3个状态
【排风机】读请求
请求内容:查看H30.00,H30.01,H30.02的三种状态
请求命令:80000200D200003900000101B2000A000004
示例:800002 00D200 003900 00 0101 B2 001E00 0001
0101:读
B2: H区
001E00:十进制30
0001:读1个字
【排风机】读请求的返回
C00002 003900 00D200 00 0101 0000 0005
【排风机】写请求
请求内容:H30.00风机进行开关
开:80000200D20000390000 0102 B2 001E00 0001 0001
关:80000200D20000390000 0102 B2 001E00 0001 0000
【排风机】写返回
C0000200390000D20000 0102 0000
草稿纸(仅供参考)
*****【排风机】*****
800002 00D200 003900 00 0101(读) B2(H区) 001E00 0001
【排风机】读请求
80000200D200003900000101B2001E000001(查3个,小数点为一组)
【排风机】返回
C00002 003900 00D200 00 0101 0000 0001
C00002 003900 00D200 00 0101 0000 0005(注意,这是16进制,要看二进制,转成二进制为:0101,从右向左:开关开x)
【排风机】写请求
800002 00D200 003900 00 0102(写) B2(H区) 008200 0001 0001(开)
800002 00D200 003900 00 0102(写) B2(H区) 008200 0001 0000(关)
【排风机】写请求
开:80000200D200003900000102B200820000010001
关:80000200D200003900000102B200820000010000
【排风机】写返回
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
开:C00002 003900 00D200 00 0102 0000
关:C00002 003900 00D200 00 0102 0000
2.4 温度、湿度
注意事项:附录代码计算温度/湿度值,其中温度值缩小10倍,湿度值不变
命令读写原理同照明,不做赘述,注意查询的结果:4个字节表示1个(温度或者湿度)值,高位和地位互换,再带入代码中计算,得到的温度值再缩小10倍(湿度值不变)才是最终答案
示例:C0000200390000D2000001010000 0000 4325
0000 4325:为数据值,高低位互换,带入代码得到计算结果:
得到结果:165.0为温度值,除10,得到最终温度为 16.5℃
草稿纸(仅供参考)
*****【温度、湿度】*****
【温度、湿度】读请求,没有写 (温湿度是浮点型,读一个字节即 8位)
800002 00D200 003900 00 0101(读) 82(D区) 00C800 0004(连读4位)
读请求:80000200D2000039000001018200C8000004
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
读返回(4连读):
C00002 003900 00D200 00 0101 0000 00004325 0000423C (用代码跑计算温湿度,165.0,47.0)
温度/氧气缩小10倍,湿度不缩减
2.5 氧气
注意事项:附录代码计算氧气值,再将氧气值缩小10倍
命令读写原理同照明,计算原理同温度,不做赘述
草稿纸(仅供参考)
*****【氧气】*****
读请求:800002 00D200 003900 00 0101(读) 82(D区) 012C00 0006(连读6位,三组)
读请求:80000200D20000390000010182012C000006
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
读返回:
C00002 003900 00D200 00 0101 0000 0000434D 00004351 00004351(氧气值3个:205.0,209.0,209.0)
温度/氧气缩小10倍,湿度不缩减
2.6 空调
注意事项:空调无法观测状态,仅根据发送后收到 0000的正常返回确认是否成功过执行了命令,和当前空调处于什么状态
命令读原理同照明,不做赘述
草稿纸(仅供参考)
*****【空调】*****
写请求:
800002 00D200 003900 00 0102(写) 82(D区) 02BC00 0001 0001
写请求,开制冷24度:
80000200D2000039000001028202BC0000010001
写请求,空调关:
80000200D2000039000001028202C00000010001
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
写返回:
C00002 003900 00D200 00 0102 0000
2.7 防火门
注意事项:开到位就是门最大角度打开,状态为1。关闭、半开、未开到位都算做关闭,状态为0
命令读原理同照明,不做赘述
草稿纸(仅供参考)
*****【防火门】***** 无法写
800002 00D200 003900 00 0101(读) B2(H区) 003200 0004(连读4个)
读请求:
80000200D200003900000101B20032000004
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
读返回:
C00002 003900 00D200 00 0101 0000 0000 0001 0001 0001(x,√,√,√),x是关或者未开到位,√开到位
2.8 水泵
注意事项:水泵打开后,发起关闭后,需要进行状态置零,否则会出现,如果不置零,会出现水泵信号混乱,导致水泵关闭不掉,水泵长时间空转会导致电机烧毁
解决方案:
水泵开启:80000200D200003900000102B2008C0000010001(开)
水泵关闭:80000200D200003900000102B2008C0000010002 (关)
关闭后,时间间隔1~2s后,复位
水泵启动信号复位为0:80000200D200003900000102B2008C0000010000
命令读原理同排风机,不做赘述
【水泵】写请求
80000200D20000390000 0102 B20 08C00 0001 0001(开)
80000200D20000390000 0102 B20 08C00 0001 0002(关)
80000200D20000390000 0102 B20 08C00 0001 0000(复位)
写请求计算示意图:
草稿纸(仅供参考)
*****【水泵】*****
【读请求】
水汛仓2#集水坑潜污泵(3分区)自动状态:H40.00
800002 00D200 003900 00 0101(读) B2(H区) 002800 0001
80000200D200003900000101B20028000001
水汛仓1#集水坑潜污泵(3分区)主从激活状态:H41.00
800002 00D200 003900 00 0101(读) B2(H区) 002900 0001
80000200D200003900000101B20029000001
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
读返回
【H40】
C00002 003900 00D200 00 0101 0000 0001 (转成2进制:0000 0000 0000 0001)
C00002 003900 00D200 00 0101 0000 0005 (0000 0000 0000 0101)
【H41】
C00002 003900 00D200 00 0101 0000 0001 (转成2进制:0000 0000 0000 0001)
1#水泵过负荷故障:H40.01
1#/2#水泵运行信号:H40.02
2#水泵过负荷故障:H40.03
高液位报警信号:H40.04
低液位信号:H40.05
【写请求】
1#/2#水泵启动 H140.00
800002 00D200 003900 00 0102(写) B2(H区) 008C00 0001
水泵启动:【2#水泵 H140】
80000200D200003900000102B2008C0000010001(开)
80000200D200003900000102B2008C0000010002(关)
C00002 00C000(计算机节点) 000300(PLC 节点) 00 0101(读数据) 0000(正常反馈) 0123(数据)
C00002 003900 00D200 00 0102 1003
C00002 003900 00D200 00 0102 1003
1#/2#水泵停止 H140.01
水泵信号复位注意:
80000200D200003900000102B2008C0000010001(开)
80000200D200003900000102B2008C0000010002 (关)
80000200D200003900000102B2008C000000 (启动信号归0)
五、附录
public static void main(String[] args) {
// 十六进制表示的浮点数
String hexString = "42400000";
// 将十六进制字符串转换为整数
int intValue = Integer.parseInt(hexString, 16);
// 使用intBitsToFloat方法将整数转换为浮点数
float floatValue = Float.intBitsToFloat(intValue);
System.out.println("Hexadecimal: " + hexString);
System.out.println("Float value: " + floatValue);
}