"byte.bit" access in a STL function

Lespinoy

Member
Join Date
May 2010
Location
Diepenbeek
Posts
5
Hi All,

I'm trying to write (STL) a function(blok) in S7
I just want to in-output a "byte" and use it in my function as "byte.bit" format. I don't want to use static-vars nor DB's...
The user of the function(blok) should be able to enter a byte (or a "word" or "Dword") on the blok to define a memory area (mb, mw, md) that i can use for "FP" and "PN" (edge detection). So I would want something like this:

Code:
function : fc1 : void
title ..
var_in
 Input_bit : bool ; //input to handle, assume I0.0
end_var

var_in_out
 M_area_byte : byte ; //byte memory (edge), assume MB32
end_var

begin
network
title
A    Input_bit        //this would be I0.0 and is no problem
FP   M_area_byte.7    //this should be interpreted as M32.7
J... (etc...)

end_function

I've been trying many different ways, it can't be that difficult, I'm just feeling plain stupid :-(
Please help!!
 
Last edited:
You should use right tool to do the job. Function Block and Vars. Why dont you want to?

It can be done but its lot messier than with right tool.

PS. you can use CODE tags to get:
Code:
a                  a

Formatting preserved like you enter.
 
@TurpoUrpo
Thanks for the code tag tip :)
Just want to keep it simple, the user should see (use) something like below without keeping track of instance DB's, multi-instace, etc stuff... It looked easy at first, but now it isn't anymore :-(


Code:
      ---------
I0.0 ! start   !
I0.1 ! stop    !
M10.0! reset   !
I0.3 ! jog     !
...  ! etc...  !
     !         !
     !    InPos! Q4.0
     !         !
MB32 ! Fx_Mem  ! 
      ---------

It's for young students, they don't know what an edge-detection or a DB is, but they can link an input to the function blok and therefore enjoy connecting a servo system to a PLC if it stays simple ;-)
 
Last edited:
I think you should use the correct term, you keep writing Function Block, yet do not want an instance DB, therefore you require a Function (not a function block). It makes it confusiong to read when you mix terms.

If I read your question right, you want to enter any data type and create a one shot from it, your example you use a BOOL, but in reality you do not want a BOOL, correct?

What do you want the one shot to do when its a WORD or DWORD? jump when non-zero? jump on data change? The latter will require a lot of storage memory of course.

The inpou parameter type would have to be ANY and then a lot of comparison work would be required after to determine what data type you are working with.

Its for young students you say who cannot understand the concept of IDB's or one shots, are you sure they are ready for indirect addressing and complex data comparision?
 
Peter, I understood it so that his students wont need to understand what is happening inside the block. They only need to use the block.

Here is example I made:

Code:
FUNCTION FC100: VOID    

VAR_INPUT            
    in1: BOOL;    
END_VAR

VAR_OUTPUT
    err : BOOL;
    edgeOut : BOOL;
END_VAR

VAR_IN_OUT            
    flags: ANY;
END_VAR

VAR_TEMP
    basePointer : DWORD;
    dataType : BYTE;
    eno : BOOL;
    edge : ARRAY[0..32] OF BOOL;
END_VAR

BEGIN
NETWORK
TITLE =
SET;
SAVE;
= eno;

l p##flags;
lar1;
l d[ar1,p#6.0];
t #basePointer;
l b[ar1,p#1.0];
t #dataType;

o(;
l b#16#02;
==I;
);
tak;
o(;
l b#16#04;
==I;
);
tak;
o(;
l b#16#06;
==I;
);
jcn err;
//inputted data either byte, word or dword

l #basePointer;
l dw#16#FF000000;
AD;
SRD 24;
l b#16#83;
==D;
jcn err;
//is m memory area

lar1 #basePointer;


a in1;
fp [ar1,p#0.7];
= edge[0];


l #dataType;
o(;
l b#16#04;
==I;
);
tak;
o(;
l b#16#06;
==I;
);
jcn end;
// is word or dword

a in1;
fp [ar1,p#1.7];
= edge[1];

l #dataType;
l b#16#06;
==I;
jcn end;
// is dword

a in1;
fp [ar1,p#2.7];
= edge[2];

a in1;
fp [ar1,p#3.7];
= edge[3];

end: nop 0;

//other than edge detection code here
a edge[0];
= edgeOut;

a eno;
save;
be;

//error
err: set;
s err;

clr;
save;
be;

END_FUNCTION

Oh and to add, it would be lot simpler, if it is allowed to take only one datatype.
 
Last edited:
Thanks for the reply's...
@Peter: sorry for the confusion, I prefer a function because a FB is acompagnied by a DB. So, if I want to connect multiple servo's I would have to work with multiple instance. It is as TurpoUrpo understood, the students just want to "feel" automation and have result without a lot of thinking...if they choose to go on in that direction the "thinking" wil follow automatically ;-)
@TurpoUrpo: thanks mate.. I did my share in VB & VC programming but i am new to PCL. That's some heavy registry programming in your code but i will try to analyse it! I'd hoped that the base adress of a "byte" could be approached as an object where the "bit" would be a property like "byte.bit". It works that way with DB's (exmpl.: DB0.bool1 ). Strange that even in SCL nothing is provided to do this because I can hook-up a base adress for a PQD or PID like this ( PQD[intBaseAddress + n] )without problems in SCL.
Grtz...Eddy
 
If the students don't "know" about DBs how will they "know" that a different MB will be required for each call of the function ?
 
Here's the simpler code if you always pass a MB

Code:
FUNCTION FC 100 : VOID
TITLE =
VERSION : 0.0


VAR_INPUT
  in1 : BOOL ;    
  Fx_Mem : BYTE ;    
END_VAR
BEGIN
NETWORK
TITLE =

      L     P##Fx_Mem; 
      LAR1  ; 

      A     #in1; 
      FP     [AR1,P#0.7]; //FP Fx_Mem.bit
      JC    cat; 


cat:  NOP   0; 
END_FUNCTION
 
Hi Guys,

I wish i had half the brains you all have, amazing!
But anyhow, i think i understand most of the code, so many many many thanks!!

I am just still puzzled by one thing: why is there a double "##" needed to load the adres-pointer to the variable in the accu? (i thought an extra was necessary if the used var identifier was a reserved keyword)

@ "L D[AR2,P#0.0]": My experience learns me that the students easily understand that the function needs a memory to work with. The link between FB and DB is not so obvious for them...don't know why but it is

Grtz...and thx again..
 
Last edited:
Its two different things, p# and #flags. p# tells it to load address of variable #flags. # (in #flags) tells compiler its symbolic variable in fc or fb interface.

I noticed three minor mistakes in my code. Can u find them? (LD, is that all?)

I dont fully get what you say, first you say its easily understood by your students that function needs memory, and then you say its obvious link between fb and db.. So basically you say its easy for them to understand fb and db. So why not use right tool?
 
Last edited:
Hi TurpoUrpo,
Sorry for the confusion...
It had to be "not so obvious"!! I edited my post and corrected it... Don't know where my head is the last days ;-) Didn't find the mistakes yet...but i will give it a shot one of the next days :)
 
How do you have a minor mistake ?:)

Either it works or it doesn't.

It works, so they are minor, its more like extra code. And one mistake does effect only in certain situation. You did not look the code trough did you? I will post them after Lespinoy has change to find them.
 
Last edited:
Too late....

Code:
FUNCTION FC 101 : VOID
TITLE =
VERSION : 0.0


VAR_INPUT
  in1 : BOOL ;    
END_VAR
VAR_OUTPUT
  err : BOOL ;    
  edgeOut : BOOL ;    
END_VAR
VAR_IN_OUT
  flags : ANY ;    
END_VAR
VAR_TEMP
  dataType : BYTE ;    
  edge : ARRAY  [0 .. 32 ] OF BOOL ;    
END_VAR
BEGIN
NETWORK
TITLE =

      L     P##flags; 
      LAR1  ; 
      L     B [AR1,P#1.0]; 
      T     #dataType; 

      O(    ; 
      L     B#16#2; 
      ==I   ; 
      )     ; 
      TAK   ; 
      O(    ; 
      L     B#16#4; 
      ==I   ; 
      )     ; 
      TAK   ; 
      O(    ; 
      L     B#16#6; 
      ==I   ; 
      )     ; 
      JCN   err; 
//inputted data either byte, word or dword
      L     B [AR1,P#6.0]; 
      L     B#16#83; 
      ==I   ; 
      JCN   err; 
//is m memory area

      L     D [AR1,P#6.0]; 
      LAR1  ; 


      A     #in1; 
      FP     [AR1,P#0.7]; 
      =     #edge[0]; 


      L     #dataType; 
      O(    ; 
      L     B#16#4; 
      ==I   ; 
      )     ; 
      TAK   ; 
      O(    ; 
      L     B#16#6; 
      ==I   ; 
      )     ; 
      JCN   end; 
// is word or dword

      A     #in1; 
      FP     [AR1,P#1.7]; 
      =     #edge[1]; 

      L     #dataType; 
      L     B#16#6; 
      ==I   ; 
      JCN   end; 
// is dword

      A     #in1; 
      FP     [AR1,P#2.7]; 
      =     #edge[2]; 

      A     #in1; 
      FP     [AR1,P#3.7]; 
      =     #edge[3]; 

end:  NOP   0; 

//other than edge detection code here
      A     #edge[0]; 
      =     #edgeOut; 

      SET   ; 
      R     #err; 
      SAVE  ; 
      BE    ; 

//error
err:  S     #err; 
      CLR   ; 
      SAVE  ; 
      BE    ; 

END_FUNCTION
 
:D

You modified it more! nice to see things i did not think! Thank you. I learned a lot again! You missed two tough, that I had in mind (I see there was lots of extra code :D )

Code:
edge : ARRAY  [0 .. 32 ] OF BOOL ;

should be:

edge : ARRAY [0..3[B]1[/B]] OF BOOL;

and edge array should be set to zero at the start of fc just to be sure..
 

Similar Topics

Hello everyone, friends. I need help with something. I want to read and change Bit and Byte numbers via HMI. I found a code snippet for this as...
Replies
18
Views
3,032
Hello All! I am having difficulties mapping register values. In the TURCK register there are 24 unique register bytes corresponding to different...
Replies
2
Views
2,571
Hi Just have a quick question, I am updating HW config of a system which uses a few DI / RO and AI inside with an ET200S. Card one uses byte...
Replies
10
Views
3,335
Hi. I use TwinCAT, but I guess its a general IEC61131-3 question. So I have a Profibus slave with 16 digital input. I like to link this...
Replies
2
Views
4,231
Hi there, Can any tell me a simple way of decting if more than one bit is set in a byte. when using a S7 400. Cheers
Replies
20
Views
8,208
Back
Top Bottom