Calculate an average value with an s7-300 plc

c.g.freitas

Member
Join Date
Jul 2006
Location
Penteada
Posts
2
Hi everyone.

I'm relative inexperienced with plc's but very curious. I'm starting to use an s7-300 siemens plc, and I'm starting to program with LAD.I was trying to make a small programe to calculate an average value but I'm having problems. So i'm looking for someone who knows how to program with LAD a simple program to calculate average values. Could you help me?

Thanks
 
My biggest suggestion is don't limit yourself to ladder. If you use statement list you can exploit one of the truly nice things in the Siemens platform. They allow you to operate on the accumulator. This will allow you to enter the averaging equation much like you would on a piece of paper.

Generally you need to provide more information on exactly what you are not understanding. Presumably you know how to calculate an average using a calculator or a piece of paper. The concept is the same in a plc. The difference is syntax. If you have a syntax or construction question please let us know what you need to know and we can help.

Keith
 
Here's the source code for a 10 point averaging filter written in ladder. To get this into your Step 7 project, go to the sources folder, insert a new object of type STL source. Open the the STL source and then cut/paste the code below. Compile the source and this will create FB3 in your block folder.

Code:
FUNCTION_BLOCK FB 3
TITLE =Averaging filter
VERSION : 0.1

VAR_INPUT
  rDataToFilter : REAL ; 
END_VAR
VAR_OUTPUT
  rFilteredData : REAL ; 
END_VAR
VAR
  FilterData : ARRAY  [1 .. 10 ] OF REAL ; 
END_VAR
VAR_TEMP
  rSum : REAL ; 
END_VAR
BEGIN
NETWORK
TITLE =Init sum to zero
	  L	 0.000000e+000; 
	  T	 #rSum; 
	  NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[9]; 
	  T	 #FilterData[10]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _001; 
	  L	 #FilterData[10]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_001: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[8]; 
	  T	 #FilterData[9]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _002; 
	  L	 #FilterData[9]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_002: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[7]; 
	  T	 #FilterData[8]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _003; 
	  L	 #FilterData[8]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_003: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[6]; 
	  T	 #FilterData[7]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _004; 
	  L	 #FilterData[7]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_004: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[5]; 
	  T	 #FilterData[6]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _005; 
	  L	 #FilterData[6]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_005: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[4]; 
	  T	 #FilterData[5]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _006; 
	  L	 #FilterData[5]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_006: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[3]; 
	  T	 #FilterData[4]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _007; 
	  L	 #FilterData[4]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_007: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[2]; 
	  T	 #FilterData[3]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _008; 
	  L	 #FilterData[3]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_008: NOP   0; 
NETWORK
TITLE =Ripple values + sum as we go
	  A(	; 
	  L	 #FilterData[1]; 
	  T	 #FilterData[2]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _009; 
	  L	 #FilterData[2]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_009: NOP   0; 
NETWORK
TITLE =Insert new data + sum
	  A(	; 
	  L	 #rDataToFilter; 
	  T	 #FilterData[1]; 
	  SET   ; 
	  SAVE  ; 
	  CLR   ; 
	  A	 BR; 
	  )	 ; 
	  JNB   _00a; 
	  L	 #FilterData[1]; 
	  L	 #rSum; 
	  +R	; 
	  T	 #rSum; 
_00a: NOP   0; 
NETWORK
TITLE =calc average
	  L	 #rSum; 
	  L	 1.000000e+001; 
	  /R	; 
	  T	 #rFilteredData; 
	  NOP   0; 
END_FUNCTION_BLOCK
 
STL is best for this type of thing.

Example below, DB named 'average' set up

average.JPG



STL prog below does average calc. This should just give an example of how STL can be used.

OPN "Average"

L "Average".NoVar // end if no values
L 0
<=I
BEC

L 0.000000e+000 // Zero Total Count
T "Average".Total_Count

L P#10.0 // Point to First value to be part of average
T #Source_add

L "Average".NoVar // Number of loops
Loop: T #Loop_Count

L DBW [#Source_add] // load value
ITD // convert to double integer
DTR // convert to Floating Point
L "Average".Total_Count
+R
T "Average".Total_Count // total count

L #Source_add
L P#2.0 // offset pointer to next word (add 2 bytes)
+D
T #Source_add

L #Loop_Count // loop until all values have been added to totaliser
LOOP Loop

L "Average".Total_Count // total value
L "Average".NoVar // number of variable
ITD
DTR // change no of variables to FP
/R // divide floating point numbers
RND // round to double int value (other options available for this)
DTB // Convert DINT to BCD
BTI // Convert BCD to Integer
T "Average".Average // store as average

[EDIT: Looking at it, the DTB and BTI shouldn't be needed as the average would be an integer, the FP to DINT should be enough, the lower half of the DINT would be the INT anyway.]

I know STL can be difficult at first, but as said you really need to learn it, it is quite simple once you get the hang of it.

Your programs can be mainly ladder and small routines like the above can be programmed into a function or function block and called from the main ladder aprt.
 
Last edited:
c.g.freitas

Forgot to mention, the block called was an FC with a couple of TEMP declarations. Loop_Count = INT and Source_Add = DWORD.

Simon.

I noticed byour example was an FB, I just wanted to know why FB and not FC.

This is not a critisism, just something I have noticed a lot of people do. I only create an FB if I have data I want to store in STATS.

The most bizzare I've seen is a recent project, where the programmer had created FB's to act as core blocks, calling other blocks from within. These had no declarations at all, as it was an FB an IDB had to be created, the onlt time I've ever opened a DB to find it empty, not a single variable.

I have noticed a lot of people choose FB's as first choice, myself its always FC as first choice, and FB if I really must.
 
I used an FB so I could declare the filter storage as part of the static data area rather than using a data DB. I almost always use multiple instance FB's so the filter storage ends up buried in the middle of an instance DB. If I need more filters or need to change their size then I just regenerate the instance DB. I find this easier to manage rather than using global data DB's. I created the posted code in ladder at the request of c.g.freitas. The averaging filter I normally use is in fact an FC that is passed an any pointer for the filter storage area. This way I can choose to use the stat area of an instance DB or a global data DB. As the poster requested ladder, I thought an averaging filter that used any pointers a bit off topic.

(Note that you can call an FB without an instance DB using the UC instuction)
 
Last edited:
A bit off topic

SimonGoldsworthy said:
(Note that you can call an FB without an instance DB using the UC instuction)

I'm involved with some equipment engineered in Germany at the moment. They quite often use the UC FB instruction.

One of those moments when you learn something new for me, I had thought you could only do this for FC's and FB's without declarations.

I found they did this for FB's with loads of declarations, by either having the same format exactly as the FB they are called from (same I/O and the UDT's in STAT's, it can be shorter, but match exactly up the point it finishes) or by opening the IDB before accessing any declarations.
 

Similar Topics

I'm working on an application where I need to calculate the average incoming flow into a wet well cell for the past 30 mins by tracking the rate...
Replies
1
Views
3,355
I have a sensor that detects the speed of conveyor belt, by counting a pulse. On the assembly line come bottles at regular intervals and which are...
Replies
3
Views
3,596
Hi everyone, This is my first time posting, so please forgive any omissions or mistakes. I am attempting to control the velocity of a stepper...
Replies
18
Views
992
Good morning, I have a question. I don't know much about ST yet I would like to calculate the average number of products per hour. how do I do...
Replies
22
Views
2,957
Can someone help me with this? I'm no good at SCL - virtually everything I've done so far has been ladder logic. The return value from the...
Replies
13
Views
1,104
Back
Top Bottom