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

数据内容


本文标签: 数据 代码 寄存器 功能 使用