Using parts of arrays in STEP7

Join Date
May 2009
Location
Halmstad
Posts
41
Hey all!

I am developing a general function block that will read quite some data from a PROFIBUS slave. This data is received with a length of 240 bytes at most at a time, but I need to save a lot more data than that. The data is received in a 241 byte long record. Now I've created a DB using SFC22 (CREAT_DB), and I want to put all the data in that DB, byte for byte. The data is variable though, it may not always be 240 byte.

I was thinking to save byte 7-n (n being the last byte of data) into the newly created DB, and then when reading the data from the next station (got a bunch of stations), just put the data from the second station after the first, and so on, with a couple of variables to keep track of what data belongs to what station. How do I do to accomplish this? I was thinking about SFC20 (BLKMOV), but it only takes a whole array as parameter and puts it in the beginning of the destination, not with an offset, as is needed in my function block.

Basically, I want to save a portion of an array into a second array, and fill this second array with more and more data from different stations.
 
You can create your own source and destination any pointers and pass them to SFC20

Here's an example:

Code:
FUNCTION FC200 : VOID
TITLE =transfer bytes between db's
//Transfer bytes of data between data blocks using SFC20
//
VAR_INPUT
  dbSourceDB : BLOCK_DB ;   //source data block
  iSourceDBNumber : INT ;   //source data block number (set to zero to use above)
  iSourceByteOffset : INT ; //source data byte offset 
  dbDestinationDB : BLOCK_DB ;  //destination data block
  iDestinationDBNumber : INT ;  //destination data block number (set to zero to use above)
  iDestinationByteOffset : INT ;	//destination data byte offset
  iNumberOfBytes : INT ;	//number of bytes to xfer
END_VAR
VAR_OUTPUT
  iMoveResult : INT ;   //result from block xfer SFC20
END_VAR
VAR_TEMP
  pSourceDB : ANY ; 
  pDestDB : ANY ;   
END_VAR
BEGIN
NETWORK
TITLE =any pointer for source
	  LAR1  P##pSourceDB; 
	  L	 W#16#1002; //specify ANY pointer, type 02 = BYTE
	  T	 W [AR1,P#0.0]; 
	  L	 #iNumberOfBytes; //number of bytes to transfer
	  T	 W [AR1,P#2.0]; 
	  L	 0; 
	  L	 #iSourceDBNumber; //if iSourceDBNumber = 0 then 
	  ==I   ; //  opn db and use DBNO to find number
	  JC	opnS; //  else use iSourceDBNumber
	  JU	trnS; 
opnS: OPN   #dbSourceDB; 
	  L	 DBNO; //data block to use
trnS: T	 W [AR1,P#4.0]; 
	  L	 DW#16#84000000; //global data block for area pointer
	  L	 #iSourceByteOffset; 
	  SLD   3; 
	  +D	; 
	  T	 D [AR1,P#6.0]; //start of data block
NETWORK
TITLE =any pointer for destination
	  LAR1  P##pDestDB; 
	  L	 W#16#1002; //specify ANY pointer, type 02 = BYTE
	  T	 W [AR1,P#0.0]; 
	  L	 #iNumberOfBytes; //number of bytes to transfer
	  T	 W [AR1,P#2.0]; 
	  L	 0; 
	  L	 #iDestinationDBNumber; //if iDestinationDBNumber = 0 then 
	  ==I   ; //  opn db and use DBNO to find number
	  JC	opnD; //  else use iDestinationDBNumber
	  JU	trnD; 
opnD: OPN   #dbDestinationDB; 
	  L	 DBNO; //data block to use
trnD: T	 W [AR1,P#4.0]; 
	  L	 DW#16#84000000; //global data block for area pointer
	  L	 #iDestinationByteOffset; 
	  SLD   3; 
	  +D	; 
	  T	 D [AR1,P#6.0]; //start of data block
NETWORK
TITLE =copy data
	  CALL "BLKMOV" (
		   SRCBLK				   := #pSourceDB,
		   RET_VAL				  := #iMoveResult,
		   DSTBLK				   := #pDestDB);
	  NOP   0; 
NETWORK
TITLE =Make sure the ENO shows the BLKMOV result
	  A	 BR; // BR is 1 for no error
	  JC	ok; 
	  JU	nok; 
ok:   SET   ; // Make the ENO high
	  SAVE  ; 
	  JU	end; 
nok:  CLR   ; // Make the ENO low
	  SAVE  ; 
end:  NOP   0; 
END_FUNCTION
 
Last edited:
Thanks, this was just what I was looking for, excellent!

Two more questions though; I'm not very used to working with pointers and DB's, so how do I transfer a whole array to a temporary DB? The DB could be taken as an input variable to the FB if it makes it easier.

Also, I have a problem passing parameters to this function. In my block, I got a few Block_DB as input parameters, but Step7 won't accept me using these as input parameters to this function. E.g. one input parameter is called DBL1, and is of type Block_DB. How do I get this to fit as an input parameter to this function?

Thanks
 
Just so that I understand what you want to achieve:

How is the number of bytes to transfer determined ?
Does the number of bytes vary freely at runtime, or is it following some kind of fixed structure ?
 
Hi LD,

Was checking out your code, and had a small question.
After a quick check, i see you have an Inputvariable of type DB_block, then u only use it to open the block and get the number out of it, what is the advantage of this?
Is there a big difference with just having a integer as input, then load this integer to a temp(type word) and opn the db, or in this case to transfer the value in to the anypointer directly.

Or isn't there any difference, and just to make the function work for any case since, you also program the jump "trnd"


Thx
 
why are you transferring to a temp DB? Is it because you want to use the values in a local area.

I ave done this by transferring into local temp words using SFC20, better than creating a DB if that's your purpose.
 
Since this function LD wrote requires two DB's, I thought I had to put them in DB's?

I think LD's response was to your first question, it depends on what you want to do with the data when its in the temp DB, if you need to then access it in different FC/FB's (unrelated not called directly from here) then perhaps a temp DB is OK.

If on the other hand, you just need access to the data in the block where the transfer is taking place (as a convenient common area), then perhaps transferring into local temp flags is more efficient, both for memory and scan.
 
I need to access the destination DB from otherwere in the program, but the source should only be accessed in the FB that the transfer is conducted.

This block is to read the data, and put in in DB's, that other function(block)s are accessing.

How do I use local temp flags?
 
Robert - the code I posted is a function that shows you how to create an any pointer at run time and pass this to SFC20 to perform a block move. You should use this principle for creating your own code.
 
.. and had a small question.
After a quick check, i see you have an Inputvariable of type DB_block, then u only use it to open the block and get the number out of it, what is the advantage of this?
Is there a big difference with just having a integer as input, then load this integer to a temp(type word) and opn the db, or in this case to transfer the value in to the anypointer directly.

Or isn't there any difference, and just to make the function work for any case since, you also program the jump "trnd"


Thx

I coded the block to deal with two cases, either the DB is passed as a BLOCK_DB parameter, in which case the DB number will appear in the cross reference, or the DB is specified as an integer value (the DB will not appear in the cross-reference), but may be useful if you need to perform some processing in a loop indexing through a list of DB's
 
Thx LD
So if i understand well, when you have a fixed DB it is better to use the datatype BLOCK_DB, then you can use Cross Ref
If the DB is variable through the program it would be better to use the integer as variable.

Thx
 
Also, I have a problem passing parameters to this function. In my block, I got a few Block_DB as input parameters, but Step7 won't accept me using these as input parameters to this function. E.g. one input parameter is called DBL1, and is of type Block_DB. How do I get this to fit as an input parameter to this function?

Thanks

You will have to extract the DB number from the Block_DB parameter and pass on the DB number as an integer. Here's an example showing it working:

dbdb009.JPG
 

Similar Topics

Good Afternoon , I have a 5 Hp SEW Eurodrive motor S.O.# 87.8070060501.0002.22.90 KA67/T motor. I'm trying to find the Terminal Block that...
Replies
6
Views
2,046
Hi All, Could anyone give me some pointers of how to calculate the parts per min, on a simple semi auto machine, using S7 300 PLC and a...
Replies
5
Views
6,581
Hi, I'm trying to use the IO Device Library (Product Versions) which is configured to work with the 1756-EN4TR & 1756-EN2TR but my system uses...
Replies
0
Views
41
Hello, As part of our project, we are using an M241 controller. This controller interfaces with an industrial computer and a router via a switch...
Replies
2
Views
74
I'm trying to write a data in Arduino using MODWR function block .I used the code I got from online for both PLC and Arduino. I made the wiring...
Replies
4
Views
84
Back
Top Bottom