# Werte an Struct zuweisen (TwinCat)



## chriszero (26 November 2010)

Hallo,
Ich bin ein C/C++/C# Programmierer der sich gerade mit ST rumschlagen muss. Und da hab ich ein paar Probleme, denke das ich da ein paar Grundlegende Dinge falsch mache.

Ich hab ein Funktionsbaustein in dem ich einmalig übergebene werte an eine selbst definierte Struktur übergebe. Diese ist als VAR_IN_OUT deklariert.
Hier der Code:


```
TYPE TypRomutec :
STRUCT
	bSlaveAddress : BYTE;
	bActiveModule : BYTE;
	bTotalModules : BYTE;
	aModuleAddresses : ARRAY [0..9] OF BYTE := 16#FF,16#FF,16#FF,16#FF,16#FF,16#FF,16#FF,16#FF,16#FF,16#FF;
	tTimeout : TIME;
	xInit : BOOL;
	MB: ModbusRtuMaster_PcCOM;
END_STRUCT
END_TYPE
```


```
FUNCTION_BLOCK RomutecMaster
VAR_INPUT
	bSlaveAddress : BYTE := 160;
	tTimeOut : TIME := t#1s;
	ModbusComPort: ModbusRtuMaster_PcCOM;
END_VAR
VAR_IN_OUT
	sRomutec :TypRomutec;
END_VAR
VAR
	xInit : BOOL;
END_VAR
```


```
IF NOT xInit THEN
	sRomutec.bSlaveAddress := bSlaveAddress;
	sRomutec.MB := ModbusComPort;
	sRomutec.tTimeout := tTimeOut;
	xInit := TRUE;
END_IF
```

Hier noch ein Baustein der dieses Struct verwendet (Haupt Arbeitscode wegen Größe entfernt).

```
FUNCTION_BLOCK BDH1401
VAR_INPUT
	xEnable : BOOL := TRUE;
	bModuleAddress : BYTE;
	bModuleGroup : BYTE := 0;
END_VAR
VAR_OUTPUT
END_VAR
VAR
	bOutput : BYTE;
	aInput : ARRAY[0..2] OF BYTE;
	iState: BYTE;
END_VAR
VAR_IN_OUT
	sRomutec :TypRomutec;
END_VAR
```


```
IF InitRomutec(bModuleAddress, sRomutec) THEN
	CASE iState OF
	0:	sRomutec.MB.ReadInputStatus(
			UnitID:=sRomutec.bSlaveAddress ,					(* Slave address *)
			Quantity:=24 ,
			MBAddr:=bModuleAddress *32 ,
			cbLength:=3 ,
			pMemoryAddr:=ADR(aInput) ,	(*Copy in the input array *)
			Execute:=TRUE ,
			Timeout:=t#1s );
		IF NOT sRomutec.MB.BUSY THEN
			sRomutec.MB.ReadInputStatus(Execute:=FALSE);
			iState:=1;
		END_IF
	1:	sRomutec.MB.WriteMultipleCoils(
			UnitID:=sRomutec.bSlaveAddress ,					(* Slave address *)
			Quantity:=8 ,					(* Write 1 Byte *)
			MBAddr:=bModuleAddress *32 ,
			cbLength:=1 ,
			pMemoryAddr:=ADR(bOutput) ,(*Copy to the output *)
			Execute:=TRUE ,
			Timeout:=t#1s );
		IF NOT sRomutec.MB.BUSY THEN
			sRomutec.MB.WriteMultipleCoils(Execute:=FALSE);
			iState:=0;
			NextModule(sRomutec); (* Gehe zum nächsten Modul *)
		END_IF
	END_CASE
END_IF
```

Das ganze rufe ich dann über ein Programm auf (in CFC), siehe Bild.

```
PROGRAM Test
VAR

	Mod1: BDH1401;
	Master: RomutecMaster;
	Mod2: BDH1401;
	sRomutec: TypRomutec;
	x1: BOOL;
END_VAR
```







Das CFC Programm rufe ich über mein MAIN programm auf, in der auch de Modbusschnittstelle deklariert wurde:


```
PROGRAM MAIN
VAR
	MB: ModbusRtuMaster_PcCOM;
	fbBX_COM_64	: FB_BX_COM_64;
	ComConfig		: ST_COMConfig;
	xInit : BOOL := TRUE;
END_VAR
```


```
(* BX COM 2 Interface *)
	fbBX_COM_64.ComConfig.eCommPort			:=	COM2;
	fbBX_COM_64.ComConfig.BaudRate				:=	9600;
	fbBX_COM_64.ComConfig.eDataBits				:=	EIGHT_DATABITS;
	fbBX_COM_64.ComConfig.eStoppBits			:=	ONE_STOPPBIT;
	fbBX_COM_64.ComConfig.eParity				:=	NONE;
	fbBX_COM_64.ComConfig.dwMode 				:=	1;						(*0-RS232 / 1-RS485*)
	
	(* convert Modbus lib to the seriell BX interface *)
	fbBX_COM_64();
	(* see globale variables VAR_CONFIG *)
	fbBX_COM_64.pstrEmo_IN  := ADR(MB.InData );
	fbBX_COM_64.pstrEmo_Out  := ADR(MB.OutData );

Test;
```

Aber aus irgend einem Grund scheinen keine Werte in der Struktur zu sein, zumindest nicht wenn sie außerhalb von RomutecMaster verwendet wird. Der "Debugger" zeigt nur "???", Folglich kommt auch keine Modbuskommunikation zu Stande.


----------



## RobiHerb (26 November 2010)

*Fb_bx_com_64 ?*

Wo ist denn der Type FB_BX_COM_64 definiert!

Aufruf mit in/out ist in der Regel wie folgt zu machen:

fbAufruf (varInOutName := structParameter);

also NICHT fbAufruf ();


----------



## chriszero (26 November 2010)

FB_BX_COM_64 ist in einer Beckhoff Bibliothek definiert. Das funktioniert ja auch alles. Aber nur wenn ich alles im MAIN aufrufe. So zb, Orginal Beispiel:


```
(* BX COM 2 Interface *)
fbBX_COM_64.ComConfig.eCommPort			:=	COM2;
fbBX_COM_64.ComConfig.BaudRate				:=	9600;
fbBX_COM_64.ComConfig.eDataBits				:=	EIGHT_DATABITS;
fbBX_COM_64.ComConfig.eStoppBits			:=	ONE_STOPPBIT;
fbBX_COM_64.ComConfig.eParity				:=	NONE;
fbBX_COM_64.ComConfig.dwMode 				:=	1;						(*0-RS232 / 1-RS485*)

(* convert Modbus lib to the seriell BX interface *)
fbBX_COM_64();
(* see globale variables VAR_CONFIG *)
fbBX_COM_64.pstrEmo_IN  := ADR(MB.InData );
fbBX_COM_64.pstrEmo_Out  := ADR(MB.OutData );


CASE i OF
0:	MB.ReadInputStatus(
		UnitID:=160 ,					(* Slave address *)
		Quantity:=24 ,					
		MBAddr:=32 ,					
		cbLength:=24 ,
		pMemoryAddr:=ADR(Input) ,	(*Copy in the input array *)
		Execute:=TRUE ,
		Timeout:=t#1s );
	IF NOT MB.BUSY THEN
		MB.ReadInputStatus(Execute:=FALSE);
		i:=1;
	END_IF
1:	outp := 7;
	MB.WriteMultipleCoils(
		UnitID:=160 ,					
		Quantity:=8 ,				
		MBAddr:=32 ,			
		cbLength:=1 ,
		pMemoryAddr:=ADR(outp) ,(*Copy from the output array *)
		Execute:=TRUE ,
		Timeout:=t#1s );
	IF NOT MB.BUSY THEN
		MB.WriteMultipleCoils(Execute:=FALSE);
		Output[0]:=Output[0]+1;		(* Counter *)
		i:=0;
	END_IF
END_CASE
```

Aber es läuft einfach nicht wenn ich es in FUNCTION_BLOCK's verpacke.
Was mach ich da falsch? Es ist doch der selbe Code? Oder übersehe ich was?

Liegt das eventuell an Mehrfachinstanzen?

Edit: Also ich glaub immernoch das es irgend wie etwas mit dem Struct zu tun hat. Das orginal Beispiel geht ja?!


----------



## peelee (26 November 2010)

Hy,

kann es sein das du dir im Debugger den FB, also die implementation, und nicht die Instanz anschaust?
Das verhalten das im Onlinemodus nur ??? erscheinen kenne ich nur daher bei Beckhoff. Codesys ist da auch nicht anders. In der Instanz sollte er dir irgendwelche Werte anzeigen auch wenn es nicht korrekt ist aber bestimmt nicht ???. Die ??? kommen immer dann wenn der Debugger nicht weiss was er anzeigen soll. Das ist aber eigentlich nur bei der Implementation der Fall ansonsten hättest du einen Compilerfehler bekommen und hättest garnicht Online gehen können. Wenn er Online geht dann muß auch das Projekt korrekt sein(zumindest was die Syntax und die Typen betrifft) sonst geht er garnicht Online.


----------



## chriszero (26 November 2010)

Ich schau mir natürlich die Instanz an. Was mir aufgefallen ist: es werden zwar die Fragezeichen angezeigt, aber das struct hat die Daten, ist mir aufgefallen wenn ich die Typen aus dem struct in lokale variablen zuweise. also nur ein anzeige Problem. Ändert jedoch nichts an der tatsache das die serielle modbus Schnittstelle nicht arbeitet. obwohl es der selbe code wie im beckhoff beispiel ist, nur andert verpackt.


----------

