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”就行了。


分享到:


相關文章: