s7 300 FC's and temp variables

As with most things, the more you look, the more you find out. The restriction for output variables from FC's is that if a completely addressed data operand is assigned to an output, the output must be evaluated in the FC.

This means that outputs Q0.0 etc, DBX0.0 etc will work (as they are completely defined by the area pointer) if you use the set/reset logic in the FC.
It also means that an output assigned DB1.DBX0.0 will not work if you use the set/reset logic.

If you are prepared to accept that you will never assign an address of the type DB1.DBX0.0 to an output, you could carry on using the set/reset logic inside an FC. My advice would be to make the FC usable for all operands and make the variables IN_OUT if you want to use set/reset logic.
 
SimonGoldsworthy said:
Your understanding is correct. An OUT variable is always written to at the end of the FC, so if your logic does not evaluate it, you may get spurious results.


Sorry but I think my english is not good enough or I still don't understand what you want to explain. First off all a quote from Berger's manual:

"you define a block parameter as input-parameter if you only check or loads its value in the block program. If you only write to a block parameter (assign, set, reset, transfer) you use an output. You must always use an IN-OUT-parameter if a block parameter is to be both checked and written."

Why do you say that I can not S/R a OUT-variable?



Second; An OUT variable is always written to at the end of the FC, so if your logic does not evaluate it, you may get spurious results.

What do you mean by 'spurious'? Maybe better if you give an example of this spurious behaviour because I am lost in your text.
 
Cut/paste the following code into the source code folder and compile it and run it. See what happens when you try and control each "motor"

Code:
ORGANIZATION_BLOCK OB 1
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1

VAR_TEMP
  OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ; //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ; //Priority of OB Execution
  OB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ; //Reserved for system
  OB1_RESERVED_2 : BYTE ; //Reserved for system
  OB1_PREV_CYCLE : INT ; //Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ; //Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =
	  A	 I	  0.0; 
	  =	 L	 20.0; 
	  BLD   103; 
	  A	 I	  0.1; 
	  =	 L	 20.1; 
	  BLD   103; 
	  CALL FC	 1 (
		   bStop					:= L	 20.0,
		   bStart				   := L	 20.1,
		   bMotor				   := DB1.DBX	0.0);
	  NOP   0; 
NETWORK
TITLE =
	  A	 I	  0.2; 
	  =	 L	 20.0; 
	  BLD   103; 
	  A	 I	  0.3; 
	  =	 L	 20.1; 
	  BLD   103; 
	  CALL FC	 1 (
		   bStop					:= L	 20.0,
		   bStart				   := L	 20.1,
		   bMotor				   := DB1.DBX	0.1);
	  NOP   0; 
END_ORGANIZATION_BLOCK
FUNCTION FC 1 : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
  bStop : BOOL ; 
  bStart : BOOL ; 
END_VAR
VAR_OUTPUT
  bMotor : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =
	  A	 #bStart; 
	  S	 #bMotor; 
	  A	 #bStop; 
	  R	 #bMotor; 
	  NOP   0; 
END_FUNCTION
DATA_BLOCK DB 1
TITLE =
VERSION : 0.1

  STRUCT  
   bData1 : BOOL ; 
   bData2 : BOOL ; 
  END_STRUCT ; 
BEGIN
   bData1 := FALSE; 
   bData2 := FALSE; 
END_DATA_BLOCK
 
ok,
thanks to all, at last i understood the usage of temp vars. i tried calling the fc twice and simulated, then i saw what happens to the vars.

thanks again..
 
SimonGoldsworthy said:
Cut/paste the following code into the source code folder and compile it and run it. See what happens when you try and control each "motor"

My first reaction was; woooah, i thought that nothing from S7 could surprise me anymore...i was wrong, this surprised me again. This is something what I never have read in any training-manual.

I must examine this again when I have more time.
 
As with most things, the more you look, the more you find out. The restriction for output variables from FC's is that if a completely addressed data operand is assigned to an output, the output must be evaluated in the FC.

This means that outputs Q0.0 etc, DBX0.0 etc will work (as they are completely defined by the area pointer) if you use the set/reset logic in the FC.
It also means that an output assigned DB1.DBX0.0 will not work if you use the set/reset logic.

If you are prepared to accept that you will never assign an address of the type DB1.DBX0.0 to an output, you could carry on using the set/reset logic inside an FC. My advice would be to make the FC usable for all operands and make the variables IN_OUT if you want to use set/reset logic.

Resurrecting an old thread just to clarify something. I was searching for something to do with "Temp" variables inside an FC and stumbled across this old thread.

I was reading what Simon has written above and was perplexed.

The example Simon shows in his post dated Dec 19th shows FC1 being called twice. If the motor is switched on then both DB1.DBX0.0 and DB1.DBX0.1 both get brought on.

However... if I OPN the datablock in OB1 and then just address DBX0.0 and DBX0.1 in OB1 then the software works correctly.

I know that 'temp' areas just grab available data (hence the reason for instance DBs for STAT areas) so understand that the 'temp' area can change but can't understand why this software works as expected if we just use DBX (without the DB stipulated) but then doesn't work when we *do* stipulate the DB..?????

Any ideas??
 
Uptown,

Maybe this will help. The OPN command is implied when you directly access a Data block address.

A DB1.DBX0.0
= DB1.DBX0.1

...is the same as...

OPN DB1
A DBX0.0
= DBX0.1

...but NOT the same as...

OPN DB1

L DB2.DBW 0
T DB2.DBW 2

A DBX 0.0
= DBX 0.1

In this last sample, the DBX0.0 and DBX0.1 will refer to DB2 and NOT DB1! To do it correctly, another OPN DB1 is needed after the T DB2.DBW 2 line. I've seen this mistake many times.
 
Hi Sigmadelta

Thanks for that. I do understand that bit though. If you monitor in STL you'll see the contents of the registers DB1 and DB2 which will show which 'instance' DB you have open (if it's an FB) and also what DB is currently 'OPN'.

My question relates to why Simons example works if the datablock address on the 'output' variable type works if they are just addressed without the associated DB number before them.

Thanks :)
 
Perhaps because value of the DB register value starts with 1 until a DB address or OPN changes it.

FYI there are 2 DB registers, one for DB, and the other for DI (instance data block). When an FB is called with a DB, this DB number is placed in the DI register.
 
Code:
     A     I      0.0
      =     L     20.0
      BLD   103
      A     I      0.1
      =     L     20.1
      BLD   103
      Call
      BLD   1
      =     L     21.0
      UC    FC     1
            P#L 20.0
            P#L 20.1
            P#L 21.1
      A     L     21.1
      OPN   DB     1
      =     DBX    0.0
      BLD   2
      End Call
      NOP   0


 A     I      0.2
      =     L     20.0
      BLD   103
      A     I      0.3
      =     L     20.1
      BLD   103
      Call
      BLD   1
      =     L     21.0
      UC    FC     1
            P#L 20.0
            P#L 20.1
            P#L 21.1
      A     L     21.1
      OPN   DB     1
      =     DBX    0.1
      BLD   2
      End Call
      NOP   0

VS

Code:
      OPN   DB     1
      A     I      0.0
      =     L     20.0
      BLD   103
      A     I      0.1
      =     L     20.1
      BLD   103
      Call
      BLD   1
      =     L     21.0
      UC    FC     1
            P#L 20.0
            P#L 20.1
            P#DBX 0.0
      BLD   2
      End Call
      NOP   0

      A     I      0.2
      =     L     20.0
      BLD   103
      A     I      0.3
      =     L     20.1
      BLD   103
      Call
      BLD   1
      =     L     21.0
      UC    FC     1
            P#L 20.0
            P#L 20.1
            P#DBX 0.1
      BLD   2
      End Call
      NOP   0

Spot the difference?
 
As above....

You cannot pass a fully qualified DB access to an FC. FCs accept parameters as area pointers. DBX0.0 is an area pointer and hence can be passed to the FC. DB1.DBX0.0 is not an area pointer and has to be copied to/from a temp variable which can then be passed to the FC as an area pointer.
 
Last edited:
Thanks for the info TurpoUrpo and LD.

As I understand it then, this only applies to FC's as an FB will use the instance DB to store a copy of the IN and OUT parameters etc and therefore will not need to put a temporary copy on the local stack. Is this correct?

:)

I'm also still struggling with this line...
Your understanding is correct. An OUT variable is always written to at the end of the FC, so if your logic does not evaluate it, you may get spurious results.

When you say "if your logic does not evaluate it..", do you mean, if the logic doesn't 'read' it?

Apologies but still trying to wiggle the penny loose on this one! :)
 
Last edited:
The output must be written. If S/R instructions are used then at least one of the S/R instructions must execute with an RLO of 1

For an output using a fully qualified DB address, the value of temp local bit passed to the FC will get written to the fully qualified DB address. If the FC does not write to the temp bit, it's value will be what ever it was before the FC was called, and that will depending on the rest of the program.

(For simple code called from OB1, the temp bit may act as if it is a STAT variable - but as the code becomes more complex the chances of the temp bit not being overwritten by another block become remote)
 
The output must be written. If S/R instructions are used then at least one of the S/R instructions must execute with an RLO of 1

For an output using a fully qualified DB address, the value of temp local bit passed to the FC will get written to the fully qualified DB address. If the FC does not write to the temp bit, it's value will be what ever it was before the FC was called, and that will depending on the rest of the program.

(For simple code called from OB1, the temp bit may act as if it is a STAT variable - but as the code becomes more complex the chances of the temp bit not being overwritten by another block become remote)

Penny dropped!

Thanks for the patient explanation. That makes perfect sense.

Cheers (as always) :)
 

Similar Topics

Dear experts, I have a question about temp interface address, If i have a temp "temp75.temp78", and i found that this address in DB7, and this...
Replies
4
Views
1,345
Hi all, I would like to know if anyone has any good advice for connecting a generic PT100 temp probe to a Siemens S7-300. I have read some posts...
Replies
1
Views
3,766
hi all, i have a question about function's temp variables. i know that a temp variable must not be read before writing on it. so if i have to set...
Replies
11
Views
4,218
We have a project to communicate Siemens S7 plc using CP341 to Pyromat Plus 300 (Temp controller). We need to know the protocol used by this...
Replies
0
Views
1,862
Hi, I'm setting up a modbus master on an S7-300. It seems to work in OB1 but not when I use it in OB35. Does anyone have any ideas why? Could...
Replies
9
Views
52
Back
Top Bottom