STL Help again!!

STL???

Member
Join Date
Sep 2005
Location
UK
Posts
879
Hi,
I need to add some code to an existing program to provide error messages for all sensor faults. The address range of the sensors are M140.0 -> M159.7. The current method utilises pointers to load the address i.e LAR1 P#M140.0 into a Diagnostic block where it is broke down in to a number which decides which Textlist entry is displayed on the HMI.

Before this i want add my timeout block to generate an Error message if the sensor is active for more than a pre-determined time.

In the simulator the code below seems to work ok, However in actual operation the timer(#fault_Timer) doesn't timeout?

Could anybody give me some "Pointers"(no pun intended!!)


FUNCTION "Sensor Timeout" : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
State : BOOL ; //Test for 1 ~ State=True / Test for 0 ~ State=False
Fault_Timer : TIMER ;
Fault_time : S5TIME ;
Reset : BOOL ;
DB_No : BLOCK_DB ;
Offset : DWORD ; //Value to Minus From Address Register
Station_in_front : BOOL ;
END_VAR
VAR_OUTPUT
Alarm_State : BYTE ; //1 = On 2 = Off ~ 0 no processing
END_VAR
VAR_TEMP
SaveAR1 : DWORD ;
Address : DWORD ;
Byte_Value : WORD ;
END_VAR
BEGIN
NETWORK
TITLE =Reset

A #Reset;
R #Fault_Timer;
NETWORK
TITLE =Run conditions



AN #Station_in_front;
BEC ;

NETWORK
TITLE =Zero Alarm status list

L 0;
T #Alarm_State;

NETWORK
TITLE =Save the contents of AR1 for later processing

TAR1 ;
T #SaveAR1;
T #Address; //Load from AR1
NETWORK
TITLE =Check Address range

L DW#16#FFFF; //Byte filter
AD ;
SRW 3;
T #Byte_Value;

L 140; //Min Address
>=I ;
A( ;
TAK ;
L 159; //Max Address
<=I ;
) ;
JC OK; // Address range OK
JU END; // If out of range ~ Restore AR1 + End Block
NETWORK
TITLE =Sensor should be off

OK: A #State;
JC NW5;

AN M [AR1,P#0.0];
L #Fault_time;
SD #Fault_Timer;

A #Fault_Timer;
JC NW6;
JU END;
NETWORK
TITLE =sensor should be on

NW5: A M [AR1,P#0.0];
L #Fault_time;
SD #Fault_Timer;

A #Fault_Timer;
JC NW6;
JU END;
NETWORK
TITLE =Send Error Message state ON/OFF
//
//
//
NW6: AN #State;
JC OFF;
L 1;
JU WRT;
OFF: L 2;
WRT: T #Alarm_State;
NETWORK
TITLE =Send Sensor Number Message
//Message 1 = 40.0 for m140.0
//
L #Address;
L DW#16#FFFF; // mask off all except Byte/Bit area
AD ; // Apply 32 bit Mask
T #Address;
L #Offset; // Minus Offset to Point to first message address
SLD 3; // Move to Byte Area of the Pointer
-D ; // Subtract from Original Value
LAR1 ;


OPN #DB_No;
A #Fault_Timer;
= DBX [AR1,P#0.0]; // Write Message


NETWORK
TITLE =Block End restore address register 1

END: L #SaveAR1;
LAR1 ;


END_FUNCTION



Thanks again
STL
 
Online:

Online.JPG
 
How many times are you calling this block ? I presume you are using a different timer for each call.

Just an immediate comment, you should not execute a BEC in a FC before you have evaluated the logic for an output. The FC will always write a value to the output, so if it has not been evaluated the output will be a random value (the value will depend on the use of local data by other blocks, so sometimes it appears to work ok, sometimes it doesn't).
 
Hm, I don't like to use AR1 for parameter passing... I amn't sure do you access correct timer or not. Using of MD defined as area-internal pointer is more easy and safe. IMHO, something wrong with it. But if someone else before you did it through AR1... Try the following:

FUNCTION "Sensor Timeout" : VOID
TITLE =
VERSION : 0.1

VAR_INPUT
State : BOOL ; //Test for 1 ~ State=True / Test for 0 ~ State=False
Fault_Timer : TIMER ;
Fault_time : S5TIME ;
Reset : BOOL ;
DB_No : BLOCK_DB ;
Offset : DWORD ; //Value to Minus From Address Register
Station_in_front : BOOL ;
END_VAR
VAR_OUTPUT
Alarm_State : BYTE ; //1 = On 2 = Off ~ 0 no processing
END_VAR
VAR_TEMP
SaveAR1 : DWORD ;
Address : DWORD ;
Byte_Value : WORD ;
END_VAR
BEGIN
NETWORK
TITLE =Reset

A #Reset;
R #Fault_Timer;
NETWORK
TITLE =Run conditions



AN #Station_in_front;
BEC ;

NETWORK
TITLE =Zero Alarm status list

L 0;
T #Alarm_State;

NETWORK
TITLE =Save the contents of AR1 for later processing

TAR1 ;
T #SaveAR1;
L DW#16#FFFF; //Byte filter
AD ;
T #Address; //Load from AR1
NETWORK
TITLE =Check Address range

SRW 3;
T #Byte_Value;

L 140; //Min Address
>=I ;
A( ;
TAK ;
L 159; //Max Address
<=I ;
) ;
JC OK; // Address range OK
JU END; // If out of range ~ Restore AR1 + End Block
NETWORK
TITLE =Sensor should be off

OK: A #State;
JC NW5;

AN M [#Address];
L #Fault_time;
SD #Fault_Timer;

A #Fault_Timer;
JC NW6;
JU END;
NETWORK
TITLE =sensor should be on

NW5: A M [#Address];
L #Fault_time;
SD #Fault_Timer;

A #Fault_Timer;
JC NW6;
JU END;
NETWORK
TITLE =Send Error Message state ON/OFF
//
//
//
NW6: AN #State;
JC OFF;
L 1;
JU WRT;
OFF: L 2;
WRT: T #Alarm_State;
NETWORK
TITLE =Send Sensor Number Message
//Message 1 = 40.0 for m140.0
//
L #Address;
L #Offset; // Minus Offset to Point to first message address
SLD 3; // Move to Byte Area of the Pointer
-D ; // Subtract from Original Value
T #Address


OPN #DB_No;
A #Fault_Timer;
= DBX [#Address]; // Write Message


NETWORK
TITLE =Block End restore address register 1

END: L #SaveAR1;
LAR1 ;


END_FUNCTION

But better to transfer data offset to your function not through AR1, but through MD...
 
Hi Simon,
Currently there are 2 FC's which handle the sequencing/Error display. the syntax for the original setup is as follows:

AN "Part Control"
JC M042
A "VKE=1"
S "START-TUE"
S "START-TWA"
L S5T#10MS
T DBW 12
L S5T#500MS
T DBW 14
LAR1 P#M 240.6
AN "REQUEST START CYCLE"
JCN M008

LAR1 P#M 146.5
A "ST1".SENSOR._8S6
JCN M004

The Labels M008 & M004 denote the Jump destination depandant on if a High or Low signal is required to display. this is where my block call will be x2 for each block (4 in total)

Both FC101 and FC102 share the same pointer addresses, which i think is risky ~ But it works!
Just an immediate comment, you should not execute a BEC in a FC before you have evaluated the logic for an output
Point taken, i forgot about that ;)

I think i see the problem, although the pointer is accurate to the program stage,it isnt set to 1 anywhere and if viewed outside the block call is not visable as it is used in the second call?

Need to have a rethink!!

Thanks again
STL
 
Using the following higher-language constructions may cause the contents of the DB register and address register AR1 to be modified:



  • Fully-qualified DB access (for example, DB20.DBW10) as an actual parameter for a function (FC)
  • Function block (FB) and multiple-instance calls
  • Structure components of a formal parameter as an address within an FC or FB
  • Structure components of a formal parameter as an actual parameter for an FC or FB
What is A "ST1".SENSOR._8S6? Access to structure element...
 
Another question like Simon question: how do you define TIMER parameter in FC call?

CALL "Sensor Timeout"
State :=FALSE
Fault_Timer :=T111
Fault_time :=S5T#30S
Reset :="RESET ALARM"
DB_No :="HMI~ALARM"
Offset :=DW#16#64
Station_in_front:="ST1 IN LOAD POSITION"
Alarm_State :="HMI~ALARM".SIGNAL_STATUS_ST1



Thanks for all the reply's, You have got my thought process started again.

I'm going to completely rewrite this code, i wasnt happy with it anyway!
Unfortunately timewise i have to work with whats already there.

Gambrinus - thanks for the alternative addressing method.

regards STL
 
What is A "ST1".SENSOR._8S6? Access to structure element...

This is why i think the code wont work in my timeout block. It is a datablock bit address mapped from an ASI PID area.

A M [AR1,P#0.0];

As the Memory bit value is never written i'm assuming its zero, the actual decision based logic is via A "ST1".SENSOR._8S6

So i think the timer can never start!

I have to stay with P#M140.0 method due to time and space, but what i'm going to try and reference the DBX sensor address based on the pointer.

Hope this makes sense? If i'm way off base here please tell me

Thanks
 
STL??? said:
This is why i think the code wont work in my timeout block. It is a datablock bit address mapped from an ASI PID area.

A M [AR1,P#0.0];

As the Memory bit value is never written i'm assuming its zero, the actual decision based logic is via A "ST1".SENSOR._8S6

So i think the timer can never start!

I have to stay with P#M140.0 method due to time and space, but what i'm going to try and reference the DBX sensor address based on the pointer.

Hope this makes sense? If i'm way off base here please tell me

Thanks
If ASI is mapped to DB it have sense. But I nevertheless suggest you - don't use AR1 directly for address passing to FC, FB. And when you access UDT (is "SENSOR" an UDT?) elements save AR1 before it.

EDIT: I'm stupid sclerotic.:) A "ST1".SENSOR._8S6 doesn't change AR1 because address is given directly. AR1 changes when access to structure defined as FC, FB formal parameter occurs.
 
Last edited:
I'm not clear on the overall picture here. The sensors are addressed in the range M140.0 to M159.7 so that makes 160 sensors. Are there only a certain number of sensors that can be active at any given time ? (otherwise you need a different timer for each sensor)
 
Timers must be addressed indirectly too, it's a second question. But it requires 160 unused timers. May be STL?? haven't so much.
 
Hi Guys,
Apologies for the confusion, Originally the ASI mapping was to M memory, But it was decided to change this because the machine has 2 stations and two ASI Masters.

Why change it?

The original programmer mapped ASI Master 1 sensors to M140.0 to M159.7 then called the sequence program for the first station.
He then Mapped ASI Master 2 sensors to the same M addresses and then called the (copied) sequence program as station 2.

With the way it was done and monitoring issues, it was decided to give each masters sensors/valves unique addresses.

The changes made have reduced the scan time from 90mS down to 50mS on the older 315DP that is fitted.

Timer wise Gambrinus is right, i have not got many left at all.

Heres what i would like to do

M 140.0 (000) = DB5.DBX22.0
M 140.1 (001) = DB5.DBX22.1
M 140.2 (002) = DB5.DBX22.2
M 140.3 (003) = DB5.DBX22.3

Create a FC, so the contents of AR1 (P#M140.0 - P#M159.7) are utilised to create/point to the DBX address of the Sensor.
[the (000) = Textlist offset]

This then is checked for its status High/Low. If the criteria isnt met a timer counts down a predetermined time and sets a timeout Message unique to that sensor.

Just trying to figure out a way of doing this!!
 
Last edited:
Simon,
The way the code works is that if a sensor is evaluated and the condition not met, It conditionally jumps to a label where a FC generates a protool textlist value.

So there is only one pointer value worked on each call of the sequencer.
The problem is there is a sensor number on the display for diagnostics, But no actual error message to Log which sensor was defective.

The operators currently are having a field day with this logging downtime as sensor faults!!

We need traceability.
 

Similar Topics

Hi, I need to create a FC/FB to sort through DB error messages and prioritise them in the order of Importance. the values generated(x5)...
Replies
15
Views
4,506
Hello nice to meet you, im new in here, I'm currently trying to convert code written in STL for a S7-400 to SCL for an S7-1500, because when i run...
Replies
5
Views
316
Hi! I am working on a project were we will be replacing an 300 CPU with a 1500 CPU and we are working on migrating / converting code. There is a...
Replies
9
Views
1,067
Hello everyone, friends. I asked a similar question before, and you helped, but I'm very weak in STL and I'm having trouble learning it. What I...
Replies
2
Views
741
i hope you could help me to convert the network Stl to lad it's apart from program of machine and i try to find solution for the reason of error...
Replies
10
Views
1,917
Back
Top Bottom