admin 管理员组文章数量: 1184232
2024年2月18日发(作者:perl语言怎么下载)
FAE-华北
资料分类 应用技术
标题
用NJ控制器对V680S进行通讯测试
制作者 丛龙辉 审核者
编号
应用技术-用NJ控制器对V680S进行通讯测
试
目录
1. 目的 ............................................................................................................... 2
2. 相关手册 ........................................................................................................ 2
3. 对象产品和对象工具 ...................................................................................... 2
3.1. 对象产品............................................................................................... 2
3.2. 设备构成............................................................................................... 2
4. 技术内容 ........................................................................................................ 3
4.1. Modbus-TCP协议简介 ........................................................................... 3
4.2. V680S使用的MODBUS/TCP协议 ............................................................. 4
4.3. 实现方法: ........................................................................................... 9
5. 附件数据 ........................................................................................................ 17
FAE-华北
1. 目的
V680S系列是Omron RFID家族的最新主打产品,目前已大量应用于京东方B5/B6线。为便于使用,该产品使用以太网接口,通讯协议采用MODBUS-TCP,内置了Web界面。
2. 相关手册
和本资料相关的手册如下。
.
SBCA-CN5-360F
型号
Z235-E1-01
手册名称
机器自动化控制器NJ系列指令基准手册基本篇
V680S SeriesUser’s Manual
相关页码
2-913~2-935
Section 5
3. 对象产品和对象工具
3.1. 对象产品
本操作使用的对象产品如下。
厂家
Omron
Omron
Omron
Omron
Omron
Omron
Omron
名称
NJ5系列控制器
Sysmac Studio
Reader/Writer
RF tag
24VDC Power supply
Cable
Switching Hub
型号
NJ501-1500+NJ-PA3001
V680S-HMD64-ETN
V680-D1KP66T
S8VS-03024
V680S-A41 (5m)
W4S1
版本
V1.03
V1.07
3.2. 设备构成
本次操作的设备构成如下所示。
FAE-华北
4. 技术内容
4.1. Modbus-TCP协议简介
MODBUS/TCP是简单的、中立厂商的用于管理和控制自动化设备的MODBUS系列通讯协议的派生产品。显而易见,它覆盖了使用TCP/IP协议的 “Intranet”和“Internet”环境中MODBUS报文的用途。协议的最通用用途是为诸如PLC,I/O模块,以及连接其它简单域总线或 I/O模块的网关服务的。所有的请求通过TCP从寄存器端口502发出。
Modbus TCP数据帧:
Modbus TCP数据帧包含报文头、功能代码和数据3部分。
MBAP报文头(MBAP、ModbusApplicationProtocol、Modbus应用协议)分4个域,共7个字节,如下表所示:
Modbus功能代码
共有3种类型分别为:
1) 公共功能代码(如表4所示):已定义好的功能码,保证其唯一性,由认可;
2) 用户自定义功能代码有两组,分别为65~72和100~110,无需认可,但不保证代码使用的唯一性。如变为公共代码,需交RFC认可;
3) 保留的功能代码,由某些公司使用在某些传统设备的代码,不可作为公共用途。
功能代码划分:按应用深浅,可分为3个类别。
FAE-华北
类别0,对于客户机/服务器最小的可用子集:
读多个保持寄存器(fc.3);写多个保持寄存器(fc.16);
类别1,可实现基本互易操作的常用代码:
读线圈(fc.1);读开关量输入(fc.2);读输入寄存器(fc.4);写线圈(fc.5);写单一寄存器(fc.6)。
类别2,用于人机界面、监控系统的例行操作和数据传送功能:
强制多个线圈(fc.15);读通用寄存器(fc.20);写通用寄存器(fc.21);屏蔽写寄存器(fc.22);读写寄存器(fc.23)。
4.2. V680S使用的MODBUS/TCP协议
电脑、PLC或其它主站设备是客户端,V680S读写器是服务器。通讯过程示例如下
图1 V680S的modbus/tcp通讯过程
FAE-华北
以下内容摘自V680S操作手册:
Message Formats
The host device communications protocol that is used by the V680S is based on
Modbus/TCP. The command message that the host device sends to the Reader Writer is
called a query. The response message that the Reader Writer returns is called the response.
The communications formats for queries and responses are given below.
Query format
Transaction Identifier
You can set any desired value. The transaction identifier in the response from the Reader
Writer will be a copy of the value that is specified here.
Protocol Identifier
This field is always 0000 hex.
Field Length
Specify the number of bytes inclusively from the unit identifier through the end of the data.
Byte 4 will always be 00 hex.
Unit Identifier
This field is always FF hex.
Function code
Specify the function code of the function for the Reader Writer to applicable
function codes are listed below.
Function code
03hex
10hex
Data
Function
Read Holding Register
Write Holding Register
Send the data for the function format of the data depends on the function
the data types that are supported by Modbus communications, the Reader Writer supports
the following data type.
Response Format
Normal End
Error End
FAE-华北
Function Code
A value of 80hex is added to the value that was specified in the query and set.
Exception Code
A code that provides information on the error is attached.
Exception Code Meaning
01 hex Illegal function
02 hex Illegal data address
03 hex Illegal data value
04 hex Failure in slave device
06 hex Slave device busy
Message Details
READ DATA
This query reads data from an RF Tag in the communications area.
Query Format
Response Format
Normal Response
Error Response
Execution Example
Reading Eight Words of Data Starting from Word Address 1234 Hex in the RF Tag
TX: FF
FAE-华北
RX: FF333344445555666677778888
WRITE DATA
This query writes data to an RF Tag in the communications area.
Query Format
Response Format
Normal Response
Error Response
Execution Example
Writing “34444” to Four Words Starting from Word Address 1234 Hex in the RF
Tag
TX: FFF34444
RX: FF1012340004
READ ID
This query reads the ID code from an RF Tag in the communications area.
Query Format
Response Format
Normal Response
FAE-华北
Error Response
以上为V680S会经常用到的消息格式,其它格式在此省略。
FAE-华北
4.3. 实现方法:
1. NJ的编程实现
NJ没有内置Modbus/TCP功能块,故需要自行编写FB实现,为此编写了3个功能块MTCP_Connect、MTCP_Fun03、MTCP_Fun10分别用于建立Modbus/TCP连接、功能码03、功能码10。以下为三个功能块的源代码:
功能块MTCP_Connect源代码:
输入/输出
名称
Enable
IPaddress
Port
Connect
Connected
Error
ErrorID
TCP_Socket
Socket_Status
输入/输出
输入
输入
输入
输入
输出
输出
输出
输出
输出
数据类型
BOOL
STRING[16]
UINT
BOOL
BOOL
BOOL
WORD
_sSOCKET
_eCONNECTION_STATE
边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
初始值
UINT#502
保持
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
常量
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
内部
名称
TCP_Port
TCP_Connect_Inst
TCP_ClearBuf_Inst
TCP_Status_Inst
Connecting
TCP_Step
TCP_Close_Inst
LocalPort
Cycle
counter
cpt
CyclicTimer
Rtime
Busy
数据类型
UINT
SktTCPConnect
SktClearBuf
SktGetTCPStatus
BOOL
INT
SktClose
UINT
BOOL
UINT
UINT
_sTimer
UINT
BOOL
初始值
UINT#502
分配到
保持 常量
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
FALSE FALSE
//-----------------------------------------------------------------------------------
// Modbus TCP Client Connect
// __________________________________________________________________________________
Cycle:=Timer(NOT Cycle,UINT#10,CyclicTimer,Cycle,Rtime); // 每1秒检查连接状态
cpt:=cpt +1;
IFNOT Busy AND Cycle AND (TCP_> 16#0) THEN
counter := counter +1;
TCP_Status_Inst(Execute:=TRUE,Socket:=TCP_Socket);
IF (TCP_Status_) OR (TCP_Status_) THEN
Socket_Status :=TCP_Status_tus;
Connected:= (Socket_Status = _ESTABLISHED);
TCP_Status_Inst(Execute:=FALSE);
END_IF;
END_IF;
CASETCP_StepOF
0: //初始化
FAE-华北
1:
2:
3:
4:
END_CASE;
TCP_Status_Inst(Execute:=FALSE);
TCP_Connect_Inst(Execute:=FALSE);
TCP_Close_Inst(Execute:=FALSE);
TCP_ClearBuf_Inst(Execute:=TRUE);
TCP_Step:=INT#1;
// 等待连接 ---------------------------------------------------------
IF Connect ANDNOT Connected THENTCP_Step:=INT#2;END_IF;
// 建立连接-------------------------------------------------------------
Error:=FALSE;
IF Port >0 THENTCP_Port:=Port;
TCP_Connect_Inst(Execute:=TRUE,
SrcTcpPort:=LocalPort,
DstAdr:=IPaddress,
DstTcpPort:=TCP_Port ,
Socket =>TCP_Socket);
IF (TCP_Connect_) THEN
TCP_Connect_Inst(Execute:=FALSE);
Connected:=TRUE;
TCP_Step:=INT#3;
Busy:=FALSE;
ELSIF (TCP_Connect_) THEN
Error:=TRUE;
ErrorID:=TCP_Connect_D;
TCP_Connect_Inst(Execute:=FALSE);
TCP_Step:=INT#0;
Busy:=FALSE;
END_IF;
END_IF;
//已连接 -------------------------------------------------------------------
IF (Connected ANDNOT Connect) OR (Connect ANDNOT Connected)
THENTCP_Step:=INT#4;
END_IF; // -->关闭连接
//关闭socket -----------------------------------------------------------------
TCP_Close_Inst(Execute:=TRUE,Socket:=Tcp_Socket);
Busy:=TRUE;
IF (TCP_Close_) OR (TCP_Close_) THEN
TCP_Step:=INT#0;
Busy:=FALSE;
IF (TCP_Close_) THEN
Error:=TRUE;
ErrorID:=TCP_Close_D;
END_IF;
END_IF;
功能块MTCP_Fun03源代码:
输入/输出
名称
Enable
TCP_Socket
Register_Address
Register_Qty
Send_Request
Cmd_Ok
Error
ErrorID
Register
输入/输出
输入
输入
输入
输入
输入
输出
输出
输出
输出
数据类型
BOOL
_sSOCKET
WORD
WORD
BOOL
BOOL
BOOL
WORD
ARRAY[0..127] OF WORD
边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
初始值
保持
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
常量
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FAE-华北
内部
名称
Expected_Length
TCP_Send_Inst
TCP_ClearBuf_Inst
TCP_Recv_Inst
TCP_Status_Inst
TCP_Step
i
Qty
Sending
Send_Data
Recv_Data
Swap_Address
数据类型
BYTE
SktTCPSend
SktClearBuf
SktTCPRcv
SktGetTCPStatus
INT
UINT
UINT
BOOL
ARRAY[0..255] OF BYTE
ARRAY[0..255] OF BYTE
WORD
初始值
分配到
保持
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
常量
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
//-----------------------------------------------------------------------------------
// Modbus TCP Fun03: Read Registers
// -----------------------------------------------------------------------------------
CASETCP_StepOF
0: // Waiting for Send Request INPUT
IFSend_RequestANDNOT Sending THEN
Sending:=TRUE;
TCP_Step:=INT#1;
TCP_Recv_Inst(Execute:=FALSE,RcvDat:=Recv_Data[0]);
TCP_Send_Inst(Execute:=FALSE, SendDat:=Send_Data[0]);
Error:=FALSE;
ErrorID:=16#0;
TCP_ClearBuf_Inst(Execute:=TRUE);
END_IF;
IFNOTSend_RequestTHENCmd_Ok:=FALSE;END_IF;
1: // 发送查询----------------------------------------------------------------
// Initialize MBAP header
Send_Data[0]:= 16#00; //Transaction identifier upper byte
Send_Data[1]:= 16#00; //Transaction identifier lower byte
Send_Data[2]:= 16#00; //Protocol identifier upper byte
Send_Data[3]:= 16#00; //Protocol identifier lower byte
Send_Data[4]:= 16#00; //Field length upper byte,固定为16#00
Send_Data[5]:= 16#06; // Field length lower byte,固定为16#06
Send_Data[6]:= 16#FF; // Unit identifier(always FF when no Modbus+)
Send_Data[7]:= 16#03; // Function code读寄存器
ToAryByte(Register_Address,_HIGH_LOW,Send_Data[8]); //Register address要读取的寄存器起始地址
ToAryByte(Register_Qty,_HIGH_LOW,Send_Data[10]); //Word count要读取的长度(字)
Expected_Length:= UINT_TO_BYTE(WORD_TO_UINT(Register_Qty)*2 + 3);
TCP_Send_Inst(Execute:=TRUE, // -->发送请求
Socket:=TCP_Socket,
SendDat:=Send_Data[0],
Size:=UINT#12);
IF (TCP_Send_) THEN
TCP_Step:=INT#2;
TCP_Send_Inst(Execute:=FALSE, SendDat:=Send_Data[0]);
ELSIF (TCP_Send_) THEN
Error :=TRUE;
ErrorID:=TCP_Send_D;
TCP_Step:=INT#3;
TCP_Send_Inst(Execute:=FALSE, SendDat:=Send_Data[0]);
END_IF;
2: // 接收响应--------------------------------------------------------------
TCP_Recv_Inst( Execute:=TRUE,
Socket:=TCP_Socket,
Timeout:=UINT#20, // Timeout fixed to 2s
Size:=UINT#255,
RcvDat:= Recv_Data[0]);
IF (TCP_Recv_) THEN
IFRecv_Data[7]=16#83 THEN //错误响应时Function code + 80 hex
Error :=TRUE;
FAE-华北
3:
END_CASE;
ErrorID:=Recv_Data[8]; // Modbus Exception Error
ELSIF (Recv_Data[5] = Expected_Length) THEN
Qty:= BYTE_TO_UINT(Recv_Data[8]);
AryByteTo(Recv_Data[9], Qty,_HIGH_LOW,Register);
Cmd_Ok:=TRUE;
END_IF;
TCP_Step:=INT#3;
ELSIF (TCP_Recv_) THEN
Error:=TRUE;
ErrorID:=TCP_Recv_D; // Receive Error (2006=Timeout)
TCP_Step:=INT#3;
END_IF;
//结束--------------------------------------
IFNOTSend_RequestTHEN
Sending:=FALSE;
TCP_Step:=INT#0;
END_IF;
功能块MTCP_Fun10源代码:
输入/输出
名称
Enable
TCP_Socket
Register_Address
Register_Qty
Registers
Send_Request
Cmd_Ok
Error
ErrorID
输入/输出
输入
输入
输入
输入
输入
输入
输出
输出
输出
数据类型
BOOL
_sSOCKET
WORD
WORD
ARRAY[0..127] OF WORD
BOOL
BOOL
BOOL
WORD
边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
无边沿
初始值
保持
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
常量
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
内部
名称
Byte_Qty
TCP_Send_Inst
TCP_ClearBuf_Inst
TCP_Recv_Inst
TCP_Status_Inst
TCP_Step
i
Swap_Reg
Sending
Send_Data
Recv_Data
IdxByte
数据类型
UINT
SktTCPSend
SktClearBuf
SktTCPRcv
SktGetTCPStatus
INT
UINT
WORD
BOOL
ARRAY[0..255] OF BYTE
ARRAY[0..255] OF BYTE
UINT
初始值
分配到
保持
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
常量
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
//-----------------------------------------------------------------------------------
// Modbus TCP Client Fn10 Write Registers
// -----------------------------------------------------------------------------------
CASETCP_StepOF
0: // Waiting for Send Request INPUT
IFSend_RequestANDNOT Sending THEN
Sending:=TRUE;
TCP_Step:=INT#1;
TCP_Recv_Inst(Execute:=FALSE,RcvDat:=Recv_Data[0]);
TCP_Send_Inst(Execute:=FALSE, SendDat:=Send_Data[0]);
Error:=FALSE;
ErrorID:= 16#0;
FAE-华北
TCP_ClearBuf_Inst(Execute:=TRUE);
END_IF;
IFNOTSend_RequestTHENCmd_Ok:=FALSE;END_IF;
1: // 发送请求 ----------------------------------------------------------------
// Initialize MBAP header
Send_Data[0]:=16#00; //Transaction identifier upper byte
Send_Data[1]:=16#00; //Transaction identifier lower byte
Send_Data[2]:=16#00; //Protocol identifier upper byte
Send_Data[3]:=16#00; //Protocol identifier lower byte
Send_Data[4]:=16#00; //Field length upper byte,固定为16#00
//Send_Data[5]:= //Field length lower byte (待计算)
Send_Data[6]:= 16#FF; // Unit identifier(always FF when no Modbus+)
Send_Data[7]:= 16#10; // Function code写多个寄存器
ToAryByte(Register_Address,_HIGH_LOW,Send_Data[8]); //Register address要写入的寄存器起始地址
ToAryByte(Register_Qty,_HIGH_LOW,Send_Data[10]); //Word count要写入的长度(字)
Byte_Qty:= WORD_TO_UINT(Register_Qty)* UINT#2;
Send_Data[12]:=UINT_TO_Byte(Byte_Qty); // Byte count
idxByte:=UINT#13;
// initialize index
FOR i:= 0 TO WORD_TO_UINT(Register_Qty) DO // add register in the send request
ToAryByte(Registers[i],_HIGH_LOW,Send_Data[idxByte]);
dxByte:=idxByte + UINT#2;
END_FOR;
Byte_Qty:= Byte_Qty + UINT#7;
Send_Data[5]:= UINT_TO_Byte(Byte_Qty); //Field length lower byte=Byte count+UINT#7
Byte_Qty := Byte_Qty+ UINT#6; //总发送字节数=Byte count+UINT#13
TCP_Send_Inst(Execute:=TRUE, // --> send request
Socket:=TCP_Socket,
SendDat:=Send_Data[0],
Size:=Byte_Qty);
IF (TCP_Send_) THEN
TCP_Step:=INT#2;
TCP_Send_Inst(Execute:=FALSE, SendDat:=Send_Data[0]);
ELSIF (TCP_Send_) THEN
Error:=TRUE;
ErrorID:=TCP_Send_D;
TCP_Step:=INT#3;
TCP_Send_Inst(Execute:=FALSE, SendDat:=Send_Data[0]);
END_IF;
2: // 接收响应 --------------------------------------------------------------
TCP_Recv_Inst( Execute:=TRUE,
Socket:=TCP_Socket,
Timeout:=UINT#20,
Size:=UINT#255,
RcvDat := Recv_Data[0]);
IF (TCP_Recv_) THEN
IFRecv_Data[7]=16#90 THEN //错误响应时Function code + 80 hex
Error:=TRUE;
ErrorID:=Recv_Data[8]; // Modbus Exception Error
ELSIFRecv_Data[7] = 16#10 ANDRecv_Data[8] = Send_Data[8] ANDRecv_Data[9]=Send_Data[9]
THEN
Cmd_Ok:=TRUE;
END_IF;
TCP_Step:=INT#3;
ELSIF (TCP_Recv_) THEN
Error:=TRUE;
ErrorID:=TCP_Recv_D; // Receive Error (2006=Timeout)
TCP_Step:=INT#3;
END_IF;
3: //Finished -----------------------------------------------------------------------
IFNOTSend_RequestTHEN
Sending:=FALSE;
TCP_Step:=INT#0;
END_IF;
END_CASE;
编写如下程序调用功能块进行读写测试:
FAE-华北
2. V680S设置
由于NJ默认IP地址为192.168.250.1,故修改读写器IP地址为192.168.250.200,网关地址为192.168.250.254,如下图所示
FAE-华北
3.
测试效果:
用读写器内置的Web Browser Interface读取:
1) Tag ID读取测试:
需要注意的是:在寄存器号码中填入
A000时,浏览器会报右图所示错误,但不影响使用,点击发送按钮后会得到Tag ID,如本次测试的Tag ID为:
8579D8020000005E0
用NJ测试:首先将Cmd_Connect置ON,建立与TCP_Server(V680S读写器)的连接:
触发ReadID,读取Tag ID
FAE-华北
查看寄存器,可知读到的Tag ID也是8579D8020000005E0
2) 读取测试:
事先在Tag的0x0010起始的地址区写入了34444的数据,用读写器内置的Web
Browser Interface读取:
将Address设置为0010,Qty设置为0004,手动将Cmd_ReadReg置ON,读取Tag数据,读取到的数据也为34444:
3) 写入测试
FAE-华北
Cmd_WriteReg置ON,向Tag中写入数据:
将Address设置为0020,Qty设置为0005,WriteReg[0-4]设置为00330004,手动将
用读写器内置的Web Browser Interface读取,确认0020开始的5个字中确实写入了00330004:
4.
注意事项:
5. 附件数据
请把相关数据,文件名,数据的内容整理在此。
文件名
V680读写测试.smc
数据内容
版权声明:本文标题:用NJ控制器对V680S进行通讯测试 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1708248794a517710.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论