IFIX与S7-300 PLC 的连接方法

心灵微语

世界上的一队小小的漂泊者呀,请留下你们的足印在我的文字里。

Troupe of little vagrants of the world, leave your footprints in my words.

使用情况:PLC一次需要传递大量数据给HMI;反之亦然!

当然了,这也是WinCC的一个小漏洞,就是在Tags点数有限的情况下,可以使用这种方法来扩展点数。

提醒:此方式下。PLC与HMI只能使用“字节”进行交互。

以下重点阐述“浮点数”交互的问题!关于“DINT”或“INT”,大家可以参照“浮点数”的交互方式。其实“浮点数”交互时,依据的也就是“DINT”型数据。

举例:REAL:A(保留小数点后两位)

DINT:B

推导:B=REAL_To_DINT(A*100.0)

A= DINT_To_REAL(B)/100.0

通过上述,我们很容易得出一个结论:可以操作的“浮点数”范围应限制在“-21474836.48~21474836.47”内,也就是其扩大100倍后,在一个“DINT”范围内。

这里建议大家将“浮点数”范围限制在“-20000000.00~20000000.00”,当超出范围时,HMI和PLC中应有相应的防护、报警措施。(以下文中并没有具体给出防护、报警措施)

数据交互时,为了保证数据的有效性,①这里还简单的做了一下“和校验”,当然亦可以扩展其他的校验方式。(校验必须要有)②还需要增加检验 “PLC与HMI”是否断线从而保证交互数据的有效性!

“PLC与HMI”之间断线判断方法:

PLC发送递增数据至HMI,判断“当前周期数据”与“上一周期数据”是否不一样: ①“不相等”,即通讯正常; ②“相等”,且持续“一段时间”(5~10秒),即通讯异常!

反之:HMI发送递增数据至PLC,判断方法和上面一样!


一、数据方向:

---PLC To HMI(HMI From PLC)

1、PLC工作:

PLC创建“DB1”数据块,注意创建的数据类型是“DINT”;

IFIX与S7-300 PLC 的连接方法

将浮点数转换为双整数,并存入DB1中。(这里将要传递的数据,逐一转换后,存入DB1中)

定义:REAL:A(保留小数点后两位) DINT:B

推导:B= REAL_To_DINT(A*100.0)

IFIX与S7-300 PLC 的连接方法

PLC中计算和校验,注意这里的数据类型是”DINT”和“DWORD”。

提供给HMI做判断!

IFIX与S7-300 PLC 的连接方法

2、HMI工作:

创建“原始数据类型”变量

,这里建议:一个“原始数据类型”变量最多可以有400个字节,即100个“REAL”数据或“DINT” 数据

若想交互更多数据,可以新建多个“原始数据类型”变量。

但一定要注意传输量限制(小于16K)

IFIX与S7-300 PLC 的连接方法

创建显示用的“内部变量”

IFIX与S7-300 PLC 的连接方法

创建脚本程序

//***************************************************************************************

// Define Variable定义变量

// Define Read Variable

BYTE Read_A [400] ; // HMI From PLC ReallyVariable

DWORD Read_B [100] ; // Change Type Variable

LONG Read_C [100] ; // Change Type Variable

FLOAT Read_D [100] ; // HMI Variable

DWORD Read_E , Read_F ;

// Public Variable

INT i , j ;

// Read Program

// HMI Read PLC读取数据

GetTagRaw ( "Read_Raw0" , Read_A , 400 ) ;

// HMI From PLC Really Variable拼装数据

for(i=0;i<100;i++)

{

j = i * 4 ;

Read_B [ i ] = ( DWORD ) ( ( Read_A [ j ] * 16777216 ) +( Read_A [ j + 1 ] * 65536 ) + ( Read_A [ j + 2 ] * 256 ) + Read_A [ j + 3 ] );

}

// Change Variable Type数据类型转换和数据校验计算

// Value Check

Read_E =0 ;

for ( i = 0 ; i < 100 ; i++ )

{

Read_E = Read_E + Read_B [ i ] ; // Value Check

Read_C [ i ] = ( LONG ) Read_B [ i ] ; // Change Variable Type

Read_D [ i ] = ( ( FLOAT ) Read_C [ i ] ) / 100.0; // ChangeVariable Type

}

Read_F = Read_E ^ 0xFFFFFFFF ; // Value Check

// Gain PLC Variable数据写入“内部变量”中

SetTagFloat ( "Read0" ,Read_D [ 0 ] ) ;

SetTagFloat ( "Read1" ,Read_D [ 1 ] ) ;

SetTagFloat ( "Read2" ,Read_D [ 2 ] ) ;

SetTagFloat ( "Read3" ,Read_D [ 3 ] ) ;

SetTagFloat ( "Read4" ,Read_D [ 4 ] ) ;

// ......此处省略

SetTagFloat ( "Read95" ,Read_D [ 95 ] ) ;

SetTagFloat ( "Read96" ,Read_D [ 96 ] ) ;

SetTagFloat ( "Read97" ,Read_D [ 97 ] ) ;

SetTagFloat ( "Read98" ,Read_D [ 98 ] ) ;

SetTagFloat ( "Read99" ,Read_D [ 99 ] ) ;

以下是数据校验判断(判断来至PLC的校验数据)

if ( ( Read_E == GetTagDWord( "Read_Check1" ) )& ( Read_F == GetTagDWord( "Read _Check2" ) ) )

{

SetTagBit ( "Read_Good" , 1 ) ;

SetTagBit ( "Read_Bad" , 0 ) ;

}

else

{

SetTagBit ( "Read_Good" , 0 ) ;

SetTagBit ( "Read_Bad" , 1 ) ;

}

//***************************************************************************************

扩展:

当需要交互更多数据时,若想交互500个“浮点数”。只需要增加以下部分:(以下为举例)

(以下程序为了可读性,定义的变量较多,当然也可以适当的减少!)

/***************************************************************************************

// Define Variable定义变量

// Define Read Variable

BYTE Read_A0 [400] ;

BYTE Read_A1 [400] ;

BYTE Read_A2 [400] ;

BYTE Read_A3 [400] ;

BYTE Read_A4 [400] ;

DWORD Read_B0 [100] ;

DWORD Read_B1 [100] ;

DWORD Read_B2 [100] ;

DWORD Read_B3 [100] ;

DWORD Read_B4 [100] ;

LONG Read_C0 [100] ;

LONG Read_C1 [100] ;

LONG Read_C2 [100] ;

LONG Read_C3 [100] ;

LONG Read_C4 [100] ;

FLOAT Read_D0 [100] ;

FLOAT Read_D1 [100] ;

FLOAT Read_D2 [100] ;

FLOAT Read_D3 [100] ;

FLOAT Read_D4 [100] ;

DWORD Read_E , Read_F ;

// Public Variable

INT i , j ;

// Read Program

// HMI Read PLC读取数据

GetTagRaw ( "Read_Raw0" , Read_A0 , 400 ) ;

GetTagRaw ( "Read_Raw1" , Read_A1 , 400 ) ;

GetTagRaw ( "Read_Raw2" , Read_A2 , 400 ) ;

GetTagRaw ( "Read_Raw3" , Read_A3 , 400 ) ;

GetTagRaw ( "Read_Raw4" , Read_A4 , 400 ) ;

// HMI From PLC Really Variable拼装数据

for(i=0;i<100;i++)

{

j = i * 4 ;

Read_B0 [ i ] = ( DWORD ) ( ( Read_A0 [ j ] * 16777216 )+ ( Read_A0 [ j + 1 ] * 65536 ) + ( Read_A0 [ j + 2 ] * 256 ) + Read_A0 [ j + 3] ) ;

Read_B1 [ i ] = ( DWORD ) ( ( Read_A1 [ j ] * 16777216 )+ ( Read_A1 [ j + 1 ] * 65536 ) + ( Read_A1 [ j + 2 ] * 256 ) + Read_A1 [ j + 3] ) ;

Read_B2 [ i ] = ( DWORD ) ( ( Read_A2 [ j ] * 16777216 )+ ( Read_A2 [ j + 1 ] * 65536 ) + ( Read_A2 [ j + 2 ] * 256 ) + Read_A2 [ j + 3] ) ;

Read_B3 [ i ] = ( DWORD ) ( ( Read_A3 [ j ] * 16777216 )+ ( Read_A3 [ j + 1 ] * 65536 ) + ( Read_A3 [ j + 2 ] * 256 ) + Read_A3 [ j + 3] ) ;

Read_B4 [ i ] = ( DWORD ) ( ( Read_A4 [ j ] * 16777216 )+ ( Read_A4 [ j + 1 ] * 65536 ) + ( Read_A4 [ j + 2 ] * 256 ) + Read_A4 [ j + 3] ) ;

}

// Change Variable Type数据类型转换和数据校验计算

// Value Check

Read_E =0 ;

for ( i = 0 ; i < 100 ; i++ )

{

Read_E = Read_E + Read_B0 [ i ] + Read_B1 [ i ] + Read_B2[ i ] + Read_B3 [ i ] + Read_B4 [ i ] ;

Read_C0 [ i ] = ( LONG ) Read_B0 [ i ] ;

Read_C1 [ i ] = ( LONG ) Read_B1 [ i ] ;

Read_C2 [ i ] = ( LONG ) Read_B2 [ i ] ;

Read_C3 [ i ] = ( LONG ) Read_B3 [ i ] ;

Read_C4 [ i ] = ( LONG ) Read_B4 [ i ] ;

Read_D0 [ i ] = ( ( FLOAT ) Read_C0 [ i ] ) / 100.0;

Read_D1 [ i ] = ( ( FLOAT ) Read_C1 [ i ] ) / 100.0;

Read_D2 [ i ] = ( ( FLOAT ) Read_C2 [ i ] ) / 100.0;

Read_D3 [ i ] = ( ( FLOAT ) Read_C3 [ i ] ) / 100.0;

Read_D4 [ i ] = ( ( FLOAT ) Read_C4 [ i ] ) / 100.0;

}

Read_F = Read_E ^ 0xFFFFFFFF ;

/***************************************************************************************

本文内容提供下载:

回复“数据”,直接下载

IFIX与S7-300 PLC 的连接方法


二、数据方向:

----PLC From HMI(HMI To PLC)

1、PLC工作:

PLC创建“DB3”数据块,注意创建的数据类型是“DINT”;

IFIX与S7-300 PLC 的连接方法

取出DB3中数据,将双整数转换为浮点数。(这里将要转换的数据,逐一从DB3中取出,进行转换)

定义:REAL:A(保留小数点后两位) DINT:B

推导:A= DINT_To_REAL(B)/100.0

IFIX与S7-300 PLC 的连接方法

PLC中计算“和校验”注意这里的数据类型是”DINT”和“DWORD”。

判断来至HMI的“校验数据”!

IFIX与S7-300 PLC 的连接方法

2、HMI工作:

创建“原始数据类型”变量,这里建议:一个“原始数据类型”变量最多可以有400个字节,即100个“REAL”数据或“DINT” 数据。

若想交互更多数据,可以新建多个“原始数据类型”变量。

但一定要注意传输量限制(小于16K)。

IFIX与S7-300 PLC 的连接方法

创建设置用的“内部变量”

IFIX与S7-300 PLC 的连接方法

创建脚本程序

//***************************************************************************************

// Define Variable定义变量

// Define Write Variable

BYTE Write_A [400] ; // HMI To PLC Really Variable

DWORD Write_B [100] ; // Change Type Variable

LONG Write_C [100] ; // Change Type Variable

FLOAT Write_D [100] ; // HMI Variable

DWORD Write_E , Write_F ;

// Public Variable

INT i , j ;

// Write Program

// Gain HMI Variable获取HMI设置的数据,即“内部变量”的数据

Write_D [ 0 ] = GetTagFloat ( "Write0" ) ;

Write_D [ 1 ] = GetTagFloat ( "Write1" ) ;

Write_D [ 2 ] = GetTagFloat ( "Write2" ) ;

Write_D [ 3 ] = GetTagFloat ( "Write3" ) ;

Write_D [ 4 ] = GetTagFloat ( "Write4" ) ;

// ......此处省略

Write_D [ 95 ] = GetTagFloat ( "Write95" );

Write_D [ 96 ] = GetTagFloat ( "Write96" ) ;

Write_D [ 97 ] = GetTagFloat ( "Write97" ) ;

Write_D [ 98 ] = GetTagFloat ( "Write98" ) ;

Write_D [ 99 ] = GetTagFloat ( "Write99" ) ;

// Change Variable Type 数据类型转换和数据校验计算

// Value Check

Write_E =0 ;

for ( i = 0 ; i < 100 ; i++ )

{

Write_C [ i ] = ( LONG ) ( Write_D [ i ] * 100.0 ) ; // ChangeVariable Type

Write_B [ i ] = ( DWORD ) Write_C [ i ] ; // ChangeVariable Type

Write_E = Write_E + Write_B [ i ] ; // ValueCheck

}

Write_F = Write_E ^ 0xFFFFFFFF ; // Value Check

// HMI To PLC Really Variable拆分数据

for ( i = 0 ; i < 100 ; i++ )

{

j = i * 4 ;

Write_A [ j ] = ( BYTE ) ( Write_B [ i ] / 16777216 ) ;

Write_A [ j + 1 ] = ( BYTE ) ( ( Write_B [ i ] %16777216) / 65536 ) ;

Write_A [ j + 2 ] = ( BYTE ) ( ( ( Write_B [ i ]%16777216 ) % 65536 ) / 256 ) ;

Write_A [ j + 3 ] = ( BYTE ) ( ( ( Write_B [ i ]%16777216 ) % 65536 ) % 256 ) ;

}

// HMI Write PLC 写入数据

SetTagRaw ( "Write_Raw0" , Write_A , 400 ) ;

SetTagDWord ( "Write_Check1" , Write_E) ;

SetTagDWord ( "Write_Check2" ,Write_F ) ;

//***************************************************************************************

扩展:

当需要交互更多数据时,若想交互500个“浮点数”。只需要增加以下部分:(以下为举例)

(以下程序为了可读性,定义的变量较多,当然也可以适当的减少!)

可以参照上文“PLC To HMI(HMI From PLC)”内容!

“REAL”数据交互时,PLC端使用的子程序:

//***************************************************************************************

定义:REAL:A(保留小数点后两位)

DINT:B

推导:B= REAL_To_DINT(A*100.0)

FUNCTION FC1:VOID

TITLE = 'Block Title'

VERSION: '1.0'

AUTHOR: BXL

// Block Parameters

VAR_INPUT

InV:REAL;

END_VAR

VAR_OUTPUT

OutV:DINT;

END_VAR

BEGIN

OutV:=TRUNC(InV*100.0);

END_FUNCTION

//***************************************************************************************

//***************************************************************************************

定义:REAL:A(保留小数点后两位)

DINT:B

推导:A= DINT_To_REAL(B)/100.0

FUNCTION FC3:VOID

TITLE = 'Block Title'

VERSION: '1.0'

AUTHOR: BXL

// Block Parameters

VAR_INPUT

InV:DINT;

END_VAR

VAR_OUTPUT

OutV:REAL;

END_VAR

VAR_TEMP

TempV:REAL;

END_VAR

BEGIN

TempV:=DINT_TO_REAL(InV);

OutV:=TempV/100.0;

END_FUNCTION

//***************************************************************************************

//***************************************************************************************

PLC端产生校验数据,提供个HMI端判断使用

FUNCTION FC11:VOID

TITLE = 'Block Title'

VERSION: '1.0'

AUTHOR: BXL

// Block Parameters

VAR_INPUT

DBx:WORD;

Address:INT;

Number:INT;

END_VAR

VAR_OUTPUT

CheckADD_V:DINT;

CheckXOR_V:DWORD;

END_VAR

VAR_TEMP

TempAddress:INT;

TempNumber:INT;

END_VAR

BEGIN

TempAddress:=Address;

CheckADD_V:=0;

FOR TempNumber:=1 TO Number BY 1 DO

CheckADD_V:=CheckADD_V+DWORD_TO_DINT(WORD_TO_BLOCK_DB(DBx).DD[TempAddress]);

TempAddress:=TempAddress+4;

END_FOR;

CheckXOR_V:=DINT_TO_DWORD(CheckADD_V) XOR 16#FFFFFFFF;

END_FUNCTION

//***************************************************************************************

//***************************************************************************************

PLC判断HMI端提供的校验数据

FUNCTION FC33:VOID

TITLE = 'Block Title'

VERSION: '1.0'

AUTHOR: BXL

// Block Parameters

VAR_INPUT

DBx:WORD;

Address:INT;

Number:INT;

HMIADD_V:DINT;

HMIXOR_V:DINT;

END_VAR

VAR_OUTPUT

CheckADD_V:DINT;

CheckXOR_V:DWORD;

Check_Good:BOOL;

Check_Bad:BOOL;

END_VAR

VAR_TEMP

TempAddress:INT;

TempNumber:INT;

END_VAR

BEGIN

TempAddress:=Address;

CheckADD_V:=0;

FOR TempNumber:=1 TO Number BY 1 DO CheckADD_V:=CheckADD_V+DWORD_TO_DINT(WORD_TO_BLOCK_DB(DBx).DD[TempAddress]);

TempAddress:=TempAddress+4;

END_FOR;

CheckXOR_V:=DINT_TO_DWORD(CheckADD_V) XOR 16#FFFFFFFF;

IF (CheckADD_V=HMIADD_V) AND (CheckXOR_V=(DINT_TO_DWORD(HMIXOR_V)))THEN

Check_Good:=TRUE;

Check_Bad:=FALSE;

ELSE

Check_Good:=FALSE;

Check_Bad:=TRUE;

END_IF;

END_FUNCTION

//***************************************************************************************

“DINT”数据交互时,PLC的操作:

和“REAL”数据交互时一样,就是少了“数据类型”转换的操作过程。

“DINT”数据交互时,HMI的操作:

脚本事例如下,其他内容都一样,只要注意“内部变量”的数据类型为“DINT”就行了。


分享到:


相關文章: