Transfer AnyPointer To FC in Step 7

and the simple answer is.....................no you cant do that with Step7,


but we have a variety of workarounds if you are fond of making something that seems simple into something quite complex.

S7 has STL because it would be impossible to use without it.

It's like the programer for S7 one day just stopped and said, "Oh gezz just write it yourself if you want it to do something more."
 
Just posting this when I saw S7Guy had also posted ! Dont forget to save AR2 if any of this code has been called from a function block higher up.

Code:
FUNCTION FC 1 : VOID
TITLE =pass on any pointers to sfc20
VERSION : 0.1


VAR_INPUT
  pSource : ANY ; 
  pDestination : ANY ; 
END_VAR
VAR_OUTPUT
  sfc20Return : INT ; 
END_VAR
VAR_TEMP
  pSrc : ANY ; 
  pDest : ANY ; 
  dwtar2 : DWORD ; 
END_VAR
BEGIN
NETWORK
TITLE =source any pointer

	  TAR2  #dwtar2; //save ar2
	  L	 P##pSource; 
	  LAR1  ; 
	  LAR2  P##pSrc; 
	  L	 W [AR1,P#0.0]; 
	  T	 W [AR2,P#0.0]; 
	  L	 W [AR1,P#2.0]; 
	  T	 W [AR2,P#2.0]; 
	  L	 W [AR1,P#4.0]; 
	  T	 W [AR2,P#4.0]; 
	  L	 D [AR1,P#6.0]; 
	  T	 D [AR2,P#6.0]; 

NETWORK
TITLE =destination any pointer

	  L	 P##pDestination; 
	  LAR1  ; 
	  LAR2  P##pDest; 
	  L	 W [AR1,P#0.0]; 
	  T	 W [AR2,P#0.0]; 
	  L	 W [AR1,P#2.0]; 
	  T	 W [AR2,P#2.0]; 
	  L	 W [AR1,P#4.0]; 
	  T	 W [AR2,P#4.0]; 
	  L	 D [AR1,P#6.0]; 
	  T	 D [AR2,P#6.0]; 

NETWORK
TITLE =block move

	  CALL "BLKMOV" (
		   SRCBLK				   := #pSrc,
		   RET_VAL				  := #sfc20Return,
		   DSTBLK				   := #pDest);

	  NOP   0; 
NETWORK
TITLE =restore ar2

	  LAR2  #dwtar2; 

END_FUNCTION



This is beautiful and a good example of the need for STL in S7, even when using "LAD" for your main program.

I was attempting a similar idea in LAD using the "MOV" command with no luck.

I could never figure out how to get the variable into the block and then assign it to SFC20.

I see now more and more that S7 is really STL from the beginning.

It took me a fe minutes to see what you were doing, I wasn't looking closely at first, but now I get it.

So is it fair to say the reason this must be done this way is beacause of the limit on how much will fit into the registers?

Is that why you have to move each byte one at a time from LAR1 to LAR2?

Why can't you just load the whole thing at once is my base question.

Load all bytes of AR1 into AR2?

I don't use STL but something like this

L AR1 all
T AR2 all

Instead of load and transfer 0.0 to 0.0 and then 2.0 to 2.0 etc.
 
Last edited:
Any ANY pointer is 10 bytes long. The accumulators are 4 bytes long.

The any pointer is formatted as follows:
id/type - 1 word
length - 1 word
DB number - 1 word
Area pointer - 1 double word

hence the sequence of load/transfers. Important note: Ar1 and Ar2 point to the data
 
Important note: Ar1 and Ar2 point to the data

What do you mean by this?

they point to the data?

AR1 and AR2 are your holding registers for doing multi step operations, correct?

So are you saying that the data is not moved into AR1&2?
 
If i remeber well the AR are the position of the data and the accu is where the data is but i'm sure LD will correct me if i'm wrong :)

Example

LAR1 P#[X.Y] //Example Lar1 P#4.0
Opn db1
L Dbw[AR1,P#0.0] // L DBW4

Then you would open db1.DBW[X.Y] no data only positions
 
Last edited:
I thought I'd finally got this clear, but apparently this is not the case!

I'm monitoring the commissioning of a new project at the moment and the sub-contracters concerned have a very structured approach to programming that I think S7Guy would approve of. However, most of their programming is done using FBs, in this case over 400 against 29 FCs.

Of these FCs about half are so-called "Typicals" for all sorts of basic functions, including simple and redundant measured value handling. These "Typicals" are then repeatedly called from within the FBs that make up most of the program.

I've already had a couple of cases where they've been using fully qualified DB-addresses as parameters for the FC call and then trying to access the data directly instead of laying it onto a TEMP and accessing the TEMP - no great problem, fairly quickly spotted and solved.

Now I've got what feels like a related, but not quite identical, problem and I'm a bit puzzled.

Here's the calling FB and as you can see they're passing over a pointer to the start of the UDT for this particular measurement.

Oops, the facility to insert pictures in the middle of text seems to have disappeared, so both the calling FB and the called FC are appended as attachments.

Now what's confusing me is that according to Berger in chapter 19.3 it is permissible to pass on a UDT as an actual parameter. However, in table 19.5, which details what can and can't be used as parameters under the various possible calling conditions, in the case of an FB calling an FC, it's permissible to pass over a UDT for an IN or an OUT parameter, but not for an IN-OUT parameter.

The other thing that bothers me is that, in my opinion, they are not passing over a UDT itself, but rather an ANY-Pointer pointing to the instance UDT for this particular measurement - and that brings us back to where this Thread started!

Just to confuse the issue further, so far we've tested about half-a-dozen measurements and this is the first one to cause problems.

Can any of the "usual suspects" throw a bit of light on whether or not this is an acceptable practice, or whether it's just luck that it's worked so far?

FB421.jpg FC121.jpg
 
Ken,

If my understanding is correct, table 19.5 describes what can be passed on to another function inside the called block. Passing a UDT into an FC and then using it would be OK i.e. if a udt was declared as INOUT as UDT_Data the in your code you could refer to #UDT_Data.Item but you couldn't then call another block and pass #UDT_Data as an argument to the called block.

Nick
 
Wrong Scotsman Nick!

No, the data is purely being used within the FC and there are no other Blocks being called, however the ouput data (in particular the scaled MV) is not being written to the expected place in the UDT in DB421.

Cheers

Roy
 
The other thing that bothers me is that, in my opinion, they are not passing over a UDT itself, but rather an ANY-Pointer pointing to the instance UDT for this particular measurement -

What makes you form this opinion Roy ?
 
I think I was just having a bit of a terminology problem, probably compounded by having to work in German. As a result I went and had a closer look at the code and have just discovered that they've got two successive calls fed with the same pointer, so the data from the second call is simply overwriting the data for the first call (which happens to be the measurement we were looking at).

So it looks as though everything is OK, now that I've studied the program in detail I understand how (and more to the point, after reading and re-reading Berger, why) it works. I was just getting a bit trigger-happy after the previous fully qualified DB parameter incidents.

Edit: Oops, spoke too soon, I hadn't moved the mouse out of the way before scrolling from one network to the next one, so in fact the addresses are OK.

Back to the original problem, why isn't this one working? Guess I'll need to go and take a closer look at exactly what's happening.
 
Last edited:
Just to finish off the story, apparently (the problem was solved by the time I got back) the problem was an IN with the raw value from the PEW being declared as a WORD instead of an INT. The program was basically written in Function Block and data type checking was turned on. A small part of the program, checking whether the incoming signal is between 20 and 24 mA (ie differentiating between too high a signal and wire break) is written in STL and the INT compare wasn't working properly. The other signals which had been basically tested were by chance in the normal range, so that the problem didn't show up.
 

Similar Topics

Hello Everyone, I am using a raC_Opr_NetModbusTCPClient AOI module, as below,. So, I need some assistance to restrict in reducing the poling...
Replies
2
Views
131
I'm trying to verify a project with a PLC. The Transfer Setup menu item is grayed out and every time I click Verify with PLC, I get an error...
Replies
1
Views
85
Hello, I need to create an automatic transfer panel that connects to the generator when the mains power is cut. I can draw up to 60kW and draw up...
Replies
0
Views
105
Does anyone know what the data transfer rate for this series of CompactLogix PLC's? 1769-L24ER-QB1B to be exact. Cheers.
Replies
1
Views
130
Hi all, Im having trouble transferring a program from one panelview 550 to an new one. I can insert a flash card into the old panelview and upload...
Replies
20
Views
389
Back
Top Bottom