gromit

SLC500 f(x) 10-breakpoints

19 posts in this topic

How can I create a ten-point function generator with one input and one output and ten segments, as per the attached table?

degC kPa
0.01 0.6117
10 1.2281
20 2.3392
30 4.2469
40 7.3851
50 12.352
60 19.947
70 31.202
80 47.416
90 70.183

sat_h2o_table_curve.pdf

Share this post


Link to post
Share on other sites

I'm not aware of a function generator or breakpoint set type of instruction within the SLC.

Can you descrbie the data as a formula?  If so, then use the CPT.

If not, then you'll need to define 9 rungs with comparison logic for the temperature, then use 9 SCP to get the value of kPa.  The assumption is that each segment is linear.

1 person likes this

Share this post


Link to post
Share on other sites

I just tried a number of curve fits here: https://mycurvefit.com/ 

and (a) I don't think it's linear based on the data I got in a spreadsheet (b) surely they gave you a formula?

Spreadsheet output below. M is for the formula Y=mX+B (equation of a straight line) and I assumed B = 0

Slope is the result of the Slope of a line equation  where Slope = (Y2-Y1) / (X2-X1). There's nothing linear about either result :

Y X Slope M
0.01 0.6117   0.016348
10 1.2281 16.20701 8.142659
20 2.3392 9.00009 8.549932
30 4.2469 5.241914 7.063976
40 7.3851 3.18654 5.416311
50 12.352 2.013328 4.047927
60 19.947 1.316656 3.007971
70 31.202 0.888494 2.243446
80 47.416 0.616751 1.687194
90 70.813 0.427405

1.270953

Share this post


Link to post
Share on other sites

I don't think they gave him a formula and stop calling him Shirley.

Basically, by breaking it into more segments, one can begin to assume linearity.

Edited by pcmccartney1
1 person likes this

Share this post


Link to post
Share on other sites

:doh::clap:

Now is a good time for the FGEN block, that doesn't exist in the SLC

Edited by Michael Lloyd

Share this post


Link to post
Share on other sites

Check out the red text below. Maybe that will give you an idea of what you need to do. Indirect addressing might help. BTW - this is a Control Logix function block, not something in the SLC. It's basically calculating the slope of a line segment based on each segment delineated by the X/Y coordinates given in your table, not a line.

Function Generator (FGEN)

The FGEN instruction converts an input based on a piece-wise linear function.

Available Languages

image\ladder_icon.jpg Ladder Diagram

This instruction is not available in ladder diagram logic.

image\fb_icon.jpg Function Block

 

image\st_icon.jpg Structured Text

FGEN(FGEN_tag,X1,Y1,X2,Y2);

Operands

image\fb_icon.jpg Function Block

Operand

Type

Format

Description

FGEN tag

FUNCTION_GENERATOR

structure

FGEN structure

X1

REAL

array

X-axis array, table one. Combine with the Y-axis array, table one to define the points of the first piece-wise linear curve.
Valid = any float

Y1

REAL

array

Y-axis array, table one. Combine with the X-axis array, table one to define the points of the first piece-wise linear curve.
Valid = any float

X2

REAL

array

(optional)
X-axis array, table two. Combine with the Y-axis array, table two to define the points of the second piece-wise linear curve.
Valid = any float

Y2

REAL

array

(optional)
Y-axis array, table two. Combine with the X-axis array, table two to define the points of the second piece-wise linear curve.
Valid = any float

image\st_icon.jpg Structured Text

The operands are the same as for the Function Block Diagram FGEN instruction.

FUNCTION_GENERATOR Structure

Input Parameter

Data Type

Description

EnableIn

BOOL

Function Block:
Enable input. If cleared, the instruction does not execute and outputs are not updated.
Default is set.

Structured Text:
No effect. The instruction executes.

In

REAL

The analog signal input to the instruction.
Valid = any float
Default = 0.0

XY1Size

DINT

Number of points in the piece-wise linear curve to use from table one. If the value is less than one and Select is cleared, the instruction sets the appropriate bit in Status and the output is not changed.
Valid = 1 to (smallest of X1 and Y1 array sizes)
Default = 1

XY2Size

DINT

Number of points in the piece-wise linear curve to use from table two. If the value is less than one and Select is set, the instruction sets the appropriate bit in Status and the output is not changed.
Valid = 0 to (smallest of X2 and Y2 array sizes)
Default = 0

Select

BOOL

This input determines which table to use. When cleared, the instruction uses table one; when set, the instruction uses table two.
Default is cleared.

Output Parameter

Data Type

Description

EnableOut

BOOL

Enable output.

Out

REAL

Output of the instruction. Arithmetic status flags are set for this output.

Status

DINT

Status of the function block.

InstructFault (Status.0)

BOOL

Instruction generated a fault.

XY1SizeInv (Status.1)

BOOL

Size of table 1 is invalid or not compatible with the array size.

XY2SizeInv (Status.2)

BOOL

Size of table 2 is invalid or not compatible with the array size.

XisOutofOrder (Status.3)

BOOL

The X parameters are not sorted.

Description

The following illustration shows how the FGEN instruction converts a twelve-segment curve.

 

The X-axis parameters must follow the relationship:

X[1] < X[2] < X[3] < ... < X[XY<n>Size],

where XY<n>Size > 1 and is a number of points in the piece-wise linear curve and where n is 1 or 2 for the table selected. You must create sorted X-axis elements in the X arrays.

The Select input determines which table to use for the instruction. When the instruction is executing on one table, you can modify the values in the other table. Change the state of Select to execute with the other table.

Before calculating Out, the X axis parameters are scanned. If they are not sorted in ascending order, the appropriate bit in Status is set and Out remains unchanged. Also, if XY1Size or XY2Size is invalid, the instruction sets the appropriate bit in Status and leaves Out unchanged.

The instruction uses this algorithm to calculate Out based on In:

  • When In £ X[1], set Out = Y[1]

  • When In > X[XY<n>Size], set Out = Y[XY<n>Size]

  • When X[n] < In £ X[n+1], calculate Out = ((Y[n+1]-Yn)/ (X[n+1]-Xn))*(In-Xn)+Yn

Arithmetic Status Flags

Arithmetic status flags are set for the Out output.

Fault Conditions

None

Execution

Condition

Function Block Action

Structured Text Action

prescan

No action taken.

No action taken.

instruction first scan

No action taken.

No action taken.

instruction first run

No action taken.

No action taken.

EnableIn is cleared

EnableOut is cleared, the instruction does nothing, and the outputs are not updated.

N/A

EnableIn is set

The instruction executes.
EnableOut is set.

EnableIn is always set.
The instruction executes.

postscan

No action taken.

No action taken.

Example

In this example, the FGEN instruction characterizes a flow signal which is then totalized using a TOT instruction. The FGEN_01X1 and FGEN_01Y1 arrays are REAL arrays of 10 elements each to support up to a 9 segment curve. You can use arrays of any size to support a curve of any desired number of segments.

image\fb_icon.jpg Function Block

 

image\st_icon.jpg Structured Text

FGEN_01.IN := Local:1:I.Ch0Data;

FGEN(FGEN_01,FGEN_01x1,FGEN_01Y1);

FlowTotal.In := FGEN_01.Out;

TOT(FlowTotal);

Share this post


Link to post
Share on other sites

Thanks Michael, the FGEN instruction is exactly what I am trying to achieve.

So what is the best way to recreate it in RSLogix500, or RSLogix5 for that matter?

Share this post


Link to post
Share on other sites

Not sure about the PLC5, but with a SLC you might be able to use the limit (LIM) and Compute (CPT) instructions with this:

When X[n] < In £ X[n+1], calculate Out = ((Y[n+1]-Yn)/ (X[n+1]-Xn))*(In-Xn)+Yn

Where LIM is constrained by this: X[n] < In £ X[n+1]

and each CPT would be based in this except you would use indirect addressing and index the pointer with logic similar to what is below ((Y[n+1]-Yn)/ (X[n+1]-Xn))*(In-Xn)+Yn

If you're real good you could initiate something like what's in the attached PDF to loop through and index the pointer so that you only need one LIM and Compute rung inside the LBL called loop in the attached PDF. Logic explanation to follow.

Rung 0 - Clear the Index

Rung 1  - Start the loop routine (in this case it's working on one of many Analog arrays, calculating alarms, etc

Rung 2 - Increment the index

Rung 4 - Test if the index has max'd out, if not go back to loop and if it is go back to Run 0 

Again, CLX logix not SLC logic but it could be adapted.

RSLogix 5000 Report(s).pdf

Edited by Michael Lloyd

Share this post


Link to post
Share on other sites
        degC          kPa
X0 0.01 Y0 0.6117
X1    10 Y1 1.2281
X2    20 Y2 2.3392
30 4.2469
40 7.3851
50 12.352
60 19.947
70 31.202
80 47.416
90 70.183

Share this post


Link to post
Share on other sites

I couldn't figure out how to format the post above this... the point of it was to show you what Xn and Yn is about

If n = 0 Xn = X0 and Yn = Y0 also Xn+1 = X1 and Yn+1 = Y1

N is the index pointer. Ie it points to the variable. In your case your going to need two 10 point floating point arrays, one for deg C and one for kPA.

Like F0, F1, F2 ... F9 for X and F10, F11, F12,... F19 for Y which means your going to need to index two pointers, one starting at 0 and one starting at 10.

 

Edited by Michael Lloyd

Share this post


Link to post
Share on other sites

Ok, so the FGEN is only available in structure text or function block, but after reading, I think it describes exactly what I originally stated about the comparisons and then SCPs x 9.

 

As always, Michael is much more eloquent then I.

Edited by pcmccartney1
1 person likes this

Share this post


Link to post
Share on other sites

Pretty much.

 

I maybe putting too much into using indirect addressing and it’s been so long since I’ve needed to do that I’m probably making it seem simpler than it is, or not.

FGEN can be very handy. 

Edited by Michael Lloyd

Share this post


Link to post
Share on other sites

Differences in platforms and about 30 years.  And I'm a brute force programmer, find it hard to debug indexed logic.

Edited by pcmccartney1
2 people like this

Share this post


Link to post
Share on other sites

Why bother with segments? It is a smooth monotone curve and according to Excel fifth order polynomial would approximate it nearly to perfection (and much better than ten zig-zag straight segments). polynomials are easy to implement in PLC logic too so it is a win-win. Just saying...

 

 

 

1 person likes this

Share this post


Link to post
Share on other sites

This is what my approach is:

1. Place both columns into Excel

2. Calculate differences until there is no change. This tells you order of the polynomial curve needed.

3. Google curve fitting with excel (newer Excel, cannot find what i was used to) :  https://www.extendoffice.com/documents/excel/2642-excel-best-fit-line-curve-function.html

4. Follow instruction to add polynomial fit of sufficient order. 

5. That's it, you have the equation...  Works on any platform. No fancy built-in instruction required. One can rearrange it into series of multiplications and additions for better performance. Voila...

Blue dots are scatter plot of the points. Doted line is curve fitted. Since highest order coefficients are very small, they could be removed at minimal expense in accuracy and that would further reduce number of instructions although 5x MUL and 5x ADD is really not heavy load. It is much more computationally efficient than using comparisons etc. or in case of AB PLC, one can simply use CPT (lame... ;-))

EDIT ----

Just noticed that order of columns in initial post is reversed (first Y then X) so the function will be inverse (mirrored about X=Y axis). Result will be unfortunately something with roots which works but - it is ugly and slow even on controller that support such instructions. To get the function in a polynomial form using method as described, new sample points are needed (at least if doing it in Excel or manually). Data points should be chosen so that they are evenly spaced along X-axis, not Y-axis. This is now easily done since we have a very good fit formula from existing data sample. I would suggest to take more points because initially slope is steeper and then rounds off. With new data points one can do this again to get function in polynomial form using same approach.

curve fitting.jpg

1 person likes this

Share this post


Link to post
Share on other sites
4 hours ago, panic mode said:

This is what my approach is:

1. Place both columns into Excel

2. Calculate differences until there is no change. This tells you order of the polynomial curve needed.

3. Google curve fitting with excel (newer Excel, cannot find what i was used to) :  https://www.extendoffice.com/documents/excel/2642-excel-best-fit-line-curve-function.html

4. Follow instruction to add polynomial fit of sufficient order. 

5. That's it, you have the equation...  Works on any platform. No fancy built-in instruction required. One can rearrange it into series of multiplications and additions for better performance. Voila...

Blue dots are scatter plot of the points. Doted line is curve fitted. Since highest order coefficients are very small, they could be removed at minimal expense in accuracy and that would further reduce number of instructions although 5x MUL and 5x ADD is really not heavy load. It is much more computationally efficient than using comparisons etc. or in case of AB PLC, one can simply use CPT (lame... ;-))

EDIT ----

Just noticed that order of columns in initial post is reversed (first Y then X) so the function will be inverse (mirrored about X=Y axis). Result will be unfortunately something with roots which works but - it is ugly and slow even on controller that support such instructions. To get the function in a polynomial form using method as described, new sample points are needed (at least if doing it in Excel or manually). Data points should be chosen so that they are evenly spaced along X-axis, not Y-axis. This is now easily done since we have a very good fit formula from existing data sample. I would suggest to take more points because initially slope is steeper and then rounds off. With new data points one can do this again to get function in polynomial form using same approach.

curve fitting.jpg

Very handy! 

Share this post


Link to post
Share on other sites

Thank you, so when programming PLCs and MCUs, i tend to rearrange equation from

y= A*x^n + B*x^(n-1) + C*x^(n-2) ....

into form

y = (((c0*X + c1)*x + c2)*x + c3)*x + c4

which is then just couple of repeating lines of code (text or ladder, or whatever)

y = c0             // init

y = y*x + c1   // first step

y = y*x + c2   // next step

y = y*x + c3   // etc.

this dramatically reduces chance of typo and number of power terms is very easy to control. don't get me wrong CPT is a nice instruction but not every platform has something like that. i like to use code that is closer to bare metal so it can work on any platform. kind of like RISC ;-)

1 person likes this

Share this post


Link to post
Share on other sites

Thanks for the detailed feedback.
I will see if I can build and test it, but I was hoping that something was already developed and tested that I could use so as not to introduce any glitches that might otherwise fault my online PLC.
I'll see if I can build something that follows the "y = (((c0*X + c1)*x + c2)*x + c3)*x + c4", and if I think I haven't introduced a major fault I will try to run it.

Share this post


Link to post
Share on other sites
On ‎7‎/‎29‎/‎2019 at 4:22 PM, pcmccartney1 said:

Differences in platforms and about 30 years.  And I'm a brute force programmer, find it hard to debug indexed logic.

Truth be known, I use an index in one routine and it's little more than a loop that references a single value that's indexed +1 on every loop, otherwise I can't stand troubleshooting indexed addresses (on anyones platform)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now