Rexroth(力士乐)PLC与Labwindows CVI OPC通讯的实现

本文详细介绍了Rexroth PLC与CVI通过OPC进行通讯的全过程,包括OPC Server的安装与配置、OPC Configurator的使用、OPC Test Client的测试方法以及PLC端的配置与编程技巧。特别关注了变量表的配置和Labwindows CVI 2013下的编程实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OPC Server 安装

力士乐开发软件中已经集成了OPC Server的相关组件,只需要安装Indraworks里的communication 组件即可,当前我使用的版本是Indraworks 12v08,这里就不详细介绍安装方法了。
只是要注意一点:最好将电脑非Unicode设置成非中文,再安装,我碰到许多次出现Indraworks安装失败,或者在配置后测试 noconfig的状态。

OPC Server配置

OPC Configurator 配置

  1. 打开Rexroth>IndraLogic>OPC Configurator
    在这里插入图片描述
  2. 添加PLC, 如果是一个客户端选择 Single PLC,如果位多个可以右击append PLC在这里插入图片描述.在这里插入图片描述
  3. Edit创建通讯参数,如果已有Gateway可以直接点添加New…,如有没有先添加Gateway 选择TCP/IP
  4. 在这里插入图片描述在这里插入图片描述
  5. 添加PLC配置时,请选择TCP/IP(Level 2 Route)在这里插入图片描述

OPC Test Client 测试

如果想要确认新建的OPC Server运行状态如何,可以使用 OPC Test Client 程序。
Rexroth>Communication>OPC Test Client
在这里插入图片描述
选择IndraLogic.OPC在这里插入图片描述状态信息栏里显示运行状态
在这里插入图片描述
如果出现状态noconfig的状态,你的PLC是连接到你的服务器的,只是读不到你的配置文件,或者读不到 你的变量表。
遇到这个问题
1.首先确认你的电脑是否设置成了Unicode简体中文,可先将他设置成英文。
2.变量表是你的PLC编译后生成的.SDB文件。可以将他手动配置到你的Gateway Files里。

连接好PLC后可以通过添加Item 来确认变量是否可以遍历到
在这里插入图片描述

PLC端配置

新建变量
在这里插入图片描述Project>Option>Symbol Configuration>Configure symbol file 选中所有变量
在这里插入图片描述

CVI OPC通讯编程

当前使用的是Labwindows CVI 2013版本
从文件读取配置信号ini配置文件如下
[PLC_TO_IPC]
Num=16
;
[IPC_TO_PLC]
Num=25
;
[PO_0]
EN=“HeartBeat”
CN=“心跳信号”
GM=“HeartBeat”
URL=“opc://localhost/IndraLogic.OPC.02/PLC1:.stPLC.bPuls”
TYPE=111
SIZE=2
;
[PO_1]
EN=“DMC”
CN=“ID码”
GM=“DMC”
URL=“opc://localhost/IndraLogic.OPC.02/PLC1:.stPLC.chDMC”
TYPE=115
SIZE=50
;
[PO_2]
EN=“Mode”
CN=“模式”
GM=“Mode”
URL=“opc://localhost/IndraLogic.OPC.02/PLC1:.stPLC.iMode”
TYPE=102
SIZE=4
;

封装部分直接上源代码
当前只读取PLC 的四种类型。CodeSys下的 REAL,BOOL,INT,STRING

// Include files

#include "dataskt.h"
#include <ansi_c.h>
#include "inifile.h"
#include "PLCCom.h"

//==============================================================================
// Constants

#define GETURL(section,chvalue)   if(0>=Ini_GetPointerToRawString (handle,section,"URL",&chvalue)) return -1001;else      //get the url if wrong return -1;
#define GETTYPE(section,value)   if(0>=Ini_GetInt(handle,section,"TYPE",&value)) return -1002;else 				//get the valible type if wrong return -1;
#define GETSIZE(section,value)   if(0>=Ini_GetInt(handle,section,"SIZE",&value)) return -1005;else 				//get the valible type if wrong return -1; 
#define GETHANDLE(url,section,i)  if(0>DS_OpenEx(url,DSConst_ReadWriteAutoUpdate,NULL,NULL,DSConst_EventModel,1,&section)) return -1003000-i;else  //get the handle of the valible

#define CHECK_HANDLE(handle,i)	if(handle== 0)  return -1000000-10000*i;else
#define OPC_GETTYPE(handle,type,i)  if(0>DS_GetDataType(handle,&type,&uiSize,NULL)) return -2000000-10000*i;else
#define CHECK_TYPE(type,type2,i)   if(type2!=type) return -3000000-10000*i-type2;else 
#define ErrCheck(function,i)    if(function<0) return -4000000-10000*i;else
//==============================================================================
// Types

//==============================================================================
// Static global variables
static struct  SignalInfo stPLC[56];
static struct  SignalInfo stIPC[56]; 
int PLCNO=0;
int IPCNO=0;

//==============================================================================
// Static functions
enum Type
{
	T_BOOL=111,
	T_INT=102,
	T_REAL=104,
	T_STRING=115,

};

unsigned char *pPlcData;
unsigned char *pIpcData;


//==============================================================================
// Global variables

//==============================================================================
// Global functions
/*****************  initial  the url********************/
//RootPath  the root path of the program
//pPlcInfo plc 信息的结构体指针
//pIpcInfo ipc信息结构体指针
//success 返回0   失败返回负数
//               -1 FAIL TO GET URL
//               -2 FAIL TO GET THE HANDLE
//               -3 FAIL TO GET THE TYPE
//               -4 FAIL TO fIND THE FILE 
extern "C" __declspec(dllexport)int PLC_COM_Initial(char *RootPath,unsigned char *pPlcInfo , unsigned char *pIpcInfo)
{
	char path[225]="";
	char *chval;
	char temp[20]="";
	char *opcURLs;
	pPlcData=pPlcInfo;
	pIpcData=pIpcInfo;
	strcpy(path,RootPath);
	strcat(path,"\\Configuration\\PLCInterface.ini"); //文件路径获取
	IniText handle=Ini_New (0);
	if(0!=Ini_ReadFromFile(handle,path)) {Ini_Dispose(handle);return -1004;}
	
	if(0>=Ini_GetInt (handle,"PLC_TO_IPC","Num",&PLCNO)) return -1005;
	
	if(0>=Ini_GetInt (handle,"IPC_TO_PLC","Num",&IPCNO)) return -1006;
	
		
	unsigned int  uiType=0, uiSize=0; 
	//read the url for the config file
	for(int i=0; i<PLCNO; i++)
	{
		sprintf(temp,"PO_%d",i);
		GETURL(temp,chval);
		opcURLs=StrDup(chval);
		GETHANDLE(opcURLs,stPLC[i].iHandle,i);
		free(opcURLs); 
		GETTYPE(temp,stPLC[i].iType); 
		GETSIZE(temp,stPLC[i].iSize);
		OPC_GETTYPE(stPLC[i].iHandle,uiType,i);
		CHECK_TYPE(stPLC[i].iType,uiType,i) ;
	}
	
	for(int i=0; i<IPCNO; i++)
	{
		sprintf(temp,"IO_%d",i);
		GETURL(temp,chval);
		opcURLs=StrDup(chval);
		GETHANDLE(opcURLs,stIPC[i].iHandle,i);
		free(opcURLs); 
		GETTYPE(temp,stIPC[i].iType);
		GETSIZE(temp,stIPC[i].iSize);
		OPC_GETTYPE(stIPC[i].iHandle,uiType,i);
		CHECK_TYPE(stIPC[i].iType,uiType,i) ;
	}
	
	Ini_Dispose(handle);
	return 0;
}
/*****************  read the signal from plc********************/
//success 返回0   失败返回负数 
//               -1 FAIL CHECK THE HANDLE
//               -2 FAIL TO GET THE TYPE  
//               -3 FAIL TO CHECK THE TYPE
//               -4 FAIL TO GET THE VALUE
extern "C" __declspec(dllexport)int PLC_COM_Read()
{
	int index=0;
	unsigned int uiType=0;
	unsigned int uiSize=0;
		
	//plc to ipc signal receive
	for(int i=0; i<PLCNO; i++)
	{
		int *piVal=(int *)(pPlcData+index);
		short *psVal=(short *)(pPlcData+index);
		char *pcVal=(char *)(pPlcData+index);
		float *pfVal =(float *)(pPlcData+index);
		
		int iVal=0;
		short sVal=0;
		float fVal=0;
		CHECK_HANDLE(stPLC[i].iHandle,i);
		OPC_GETTYPE(stPLC[i].iHandle,uiType,i);
		switch(stPLC[i].iType)
		{
			case T_BOOL:
				ErrCheck(DS_GetDataValue(stPLC[i].iHandle,CAVT_SHORT, &sVal, uiSize+1, NULL,NULL),i);
				sVal=abs(sVal);
				*psVal=sVal;
				break;
			case T_INT:
				ErrCheck(DS_GetDataValue(stPLC[i].iHandle,CAVT_INT, &iVal, uiSize+1, NULL,NULL),i);
				*piVal=iVal;
				break;
			case T_STRING:
				ErrCheck(DS_GetDataValue(stPLC[i].iHandle,CAVT_CSTRING,pcVal, uiSize+1, NULL,NULL),i);
				break;
			case T_REAL:
				ErrCheck(DS_GetDataValue(stPLC[i].iHandle,CAVT_FLOAT, &fVal, uiSize+1, NULL,NULL),i);
				*pfVal=fVal;
				break; 
			default:
				return -600000-i*1000-stPLC[i].iType;
		}
		index+=stPLC[i].iSize; 
	}
	return 0;
}
/*****************  write the signal to plc ********************/
//success 返回0   失败返回负数 
//               -1 FAIL CHECK THE HANDLE
//               -2 FAIL TO GET THE TYPE  
//               -3 FAIL TO CHECK THE TYPE
//               -4 FAIL TO set THE VALUE
extern "C" __declspec(dllexport)int PLC_COM_Set()
{
	int index=0; 
	//ipc to plc signal receive
	for(int i=0; i<IPCNO; i++)
	{
		int *piVal=(int *)(pIpcData+index);
		short *psVal=(short *)(pIpcData+index);
		char *pcVal=(char *)(pIpcData+index);
		float *pfVal =(float *)(pIpcData+index);
		
		int iVal=0;
		short sVal=0;
		float fVal=0;
		CHECK_HANDLE(stIPC[i].iHandle,i);
		switch(stIPC[i].iType)
		{

			case T_BOOL:
				sVal=*psVal;
				ErrCheck(DS_SetDataValue (stIPC[i].iHandle,CAVT_SHORT, &sVal,0,0),i);
				break;
			case T_INT:
				iVal=*piVal;
				ErrCheck(DS_SetDataValue(stIPC[i].iHandle,CAVT_INT, &iVal, 0,0),i);
				break;
			case T_STRING:
				ErrCheck(DS_SetDataValue (stIPC[i].iHandle,CAVT_CSTRING, pcVal,0,0),i);
				break;
			case T_REAL:
				fVal=*pfVal;
				ErrCheck(DS_SetDataValue(stIPC[i].iHandle,CAVT_FLOAT, &fVal, 0,0),i);
				break;
			default:
				return -700000-i*1000-stIPC[i].iType;
		}
		index+=stIPC[i].iSize; 
	}
	return 0;
}

调用以上函数的方法

//此部分位初始化调用
int PLCInterface_Initial()
{
	int iRetVal=0;
	
	if(Initialed==0)
		iRetVal=PLC_COM_Initial(gPara.SWPath,(unsigned char*)&stPLC,(unsigned char*)&stIPC);
	if(iRetVal==0)
	{
		Initialed=1;
		stIPC.bIsReady=TRUE;
	}else
	{
		char temp[20]="";
		sprintf(temp,"Code:%d",iRetVal);
		MessageAlarm("1081",temp,gPara.ActLanguage); 
	}
	return iRetVal;
}
//此部分贴入定时器循环扫描
int PLC_IPC_Ctrol()
{
	static int bPulseEx=0;
	static double dTimerA=0,dTimerB=0;//timer count
	static char Trigger=0;
	static int ModeEx=-1;
	

	if(!Initialed) return 0; // 
	//READ AND WRITE
	int ret=PLC_COM_Read();
	if(0!=ret)
	{
		char temp[20]="";
		sprintf(temp,"RCode:%d",ret);
		MessageAlarm("1070",temp,gPara.ActLanguage);
		return 0;
	}
	ret=PLC_COM_Set();
	if(0!=ret)
	{
		char temp[20]="";
		sprintf(temp,"WCode:%d",ret);
		MessageAlarm("1070",temp,gPara.ActLanguage);
		return 0;
	}
}

至此,整个OPC通讯的实现就已完成。
划重点
DS_GetDataValue(stPLC[i].iHandle,CAVT_SHORT, &sVal, uiSize+1, NULL,NULL),i);
CAVT_SHORT 是指 在上位机程序变量的定义类型 而非PLC端变量的定义类型。
运行效果
在这里插入图片描述

论文摘要 近年来,随着虚拟仪器技术、网络通讯技术的显著进步以及Intemet的迅速 普及,将网络技术应用到虚拟仪器,使信号采集、传输和处理分析一体化,已 成为一种趋势。这一方面可以使许多昂贵的硬件资源得以共享,另一方面还便 于系统的扩展和效率的提高。它通过应用程序各功能化模块的有机结合,用 户利用友好的图形界面来控制计算机,完成对仪器控制、数据采集、分析、存 储及显示等功能。 本文针对数据采集监控系统的开发需求,设计并实现了一种基于虚拟仪 器平台的数据采集监控系统。系统采用的是一个虚拟仪器的构造形式,由数 据采集卡、工业控制计算机和信号调理电路构成硬件系统。系统软件开发平台 为LabWindow托VI,应用软件完成数据采集、处理、存储和显示等功能。 论文的主要研究工作如下: (1)根据数据采集监控系统的功能需求,提出了系统软件的总体设计方 案,并对虚拟仪器的体系结构和软件开发两方面进行了深入的研究; (2)设计并实现了数据采集和处理模块。利用基于线程池的多线程技术和 基于线程安全队列的数据保护机制,改善数据吞吐量,提高程序响应速度和更 有效的后台数据处理; (3)设计并实现了通信模块。制定串口通信协议,确保数据传输的可靠性 和高速率,有效解决了数据传输远程监控的问题; (4)设计并实现了数据库模块。实现了详细数据查询、报警信息查询、数 据报表管理、交接班管理、用户登录权限管理等功能。
### 回答1: Rexroth PLC PPC-R02.2N 手册是一本关于该型号PLC的详细说明书。该手册提供了关于设备的技术参数、功能描述、硬件配置、编程指南以及故障排除方法等信息。 手册首先介绍了PPC-R02.2N PLC的特点和应用领域。它具有高性能、高可靠性和灵活性,适用于各种工业自动化应用。该PLC可用于控制和监控各种设备和系统,如生产线、机器人、输送系统等。 手册接着介绍了PLC的硬件组成和配置。它包括CPU、存储器、输入/输出模块、通信接口等。手册详细描述了每个组件的技术参数和连接方式,以帮助用户正确配置和连接PLC。 手册还提供了PLC的编程指南。它介绍了PLC的编程语言、编程环境和开发工具。用户可以通过编写程序来实现各种控制逻辑和功能,如数据处理、逻辑运算、变量控制等。手册提供了大量的代码示例和实例,以帮助用户理解和应用编程技巧。 此外,手册还包括了PLC的诊断和故障排除方法。它列出了常见故障的可能原因和解决方案,以及故障码和报警信息的解释。用户可以根据手册提供的指导,快速诊断和修复PLC故障,保证设备的正常运行。 总之,Rexroth PLC PPC-R02.2N 手册详细介绍了该型号PLC的技术参数、功能、硬件配置、编程指南和故障排除方法。它是用户了解和使用该PLC的重要参考手册。 ### 回答2: rexroth plc ppc-r02.2n 手册是专门用于rexroth ppc-r02.2n型号的可编程逻辑控制器的操作指南。该手册详细介绍了该型号PLC的功能和特点,以及如何正确使用和调试该设备。 该手册包含以下方面的内容: 1. 产品概述:介绍了rexroth ppc-r02.2n PLC的外观和基本参数,包括输入输出模块、通信接口等。 2. 硬件安装:说明了如何正确安装rexroth ppc-r02.2n PLC,包括连接电源、模块、传感器和执行器等。 3. 软件配置:介绍了PLC的软件配置过程,包括参数设置、编程语言选择和编程环境搭建等。 4. PLC编程:详细介绍了rexroth ppc-r02.2n PLC的编程方法和编程语言,包括 ladder diagram(梯形图)、function block diagram(功能块图)等,以及常用的指令和功能模块的应用。 5. 调试故障排除:提供了在使用过程中常见问题的解决方案,包括如何进行调试和故障排除,以确保PLC的正常运行。 通过仔细阅读和理解rexroth plc ppc-r02.2n手册,用户能够了解该PLC的基本原理和操作流程,掌握PLC的编程和调试技巧,从而能够灵活应用该设备来实现自动化控制任务。此外,手册中也提供了一些实例和应用场景,供用户参考和借鉴。 总之,rexroth plc ppc-r02.2n手册对于用户正确、高效地使用该型号的PLC具有重要的指导作用,对于学习和掌握PLC相关知识也具有一定的参考价值。 ### 回答3: rexroth plc ppc-r02.2n 是一款由德国力士乐公司制造的可编程逻辑控制器(PLC)。它是一种高性能的控制设备,可用于自动化控制系统中的各种应用。该设备具有多种输入和输出接口,可以连接各种传感器和执行器,实现对机械和电气设备的控制。 《rexroth plc ppc-r02.2n 手册》是对该设备的说明和操作指南。手册的目的是向用户提供设备的技术参数、接口定义、安装和调试方法、编程指导以及各种故障排除的解决方法等详细信息。通过阅读手册,用户可以了解设备的功能和特性,并能够独立进行设备的操作和维护。 手册的内容主要包括以下几个方面: 1. 设备介绍:包括设备的外观和结构、产品编号、型号规格等基本信息。 2. 硬件配置:介绍设备的各种输入和输出接口,以及它们的功能和参数。 3. 系统安装:包括设备的安装位置、连接方法以及相应的电气和机械要求。 4. 编程指南:介绍了PLC编程的基本概念、编程环境和语言,以及各种常用指令和函数的使用方法。 5. 故障排除:列举了可能出现的故障和解决方法,帮助用户快速排除设备故障并进行维修。 总之,rexroth plc ppc-r02.2n 手册是一本对该PLC设备进行详细介绍和操作指导的手册,它可以帮助用户充分了解设备的性能和使用方法,确保设备的正常运行和维护。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值