I am trying to manipulate a sub-array of an existing array. Can Codesys do this? I guess this is more of a syntax question.
In Python, there is slice() is there a Codesys equivalent?
Here's some pseudocode of what I am trying to do
VAR
Array1: ARRAY [1..3, 1..3] OF BOOL;
Statement: BOOL;
END_VAR
IF
Statement := TRUE
THEN
Array1[1,1..3] :=TRUE;
END_IF
[1,1..3] or [1,1:3] are not valid syntax. What is the appropriate way to access multiple cells?
You cannot set single value to a range of array elements. Syntax [1,1..3] or [1,1:3] will not work. You can only access one element at a time.
Array1[1,1] := TRUE;
Array1[1,2] := TRUE;
Array1[1,3] := TRUE;
Or
Array1[1,1] := Array1[1,2] := Array1[1,3] := Statement;
Related
I would like to create a reflect.Value that represents a multiple-level nested pointer to a final value. The nesting level is not known at compile time. How can I create pointers to pointers using reflect?
I already stumble at the "unaddressable value" hurdle when trying to create a pointer to a pointer.
dave := "It's full of stars!"
stargazer := reflect.ValueOf(&dave)
stargazer = stargazer.Addr() // panic: reflect.Value.Addr of unaddressable value
Same for stargazer.UnsafeAddr(), etc. While stargazer.Elem().UnsafeAddr() etc. works, I can't see how this helps in (recursively) creating a new non-zero pointer to a pointer...
Use the following code to create a pointer to the value in stargazer.
p := reflect.New(stargazer.Type())
p.Elem().Set(stargazer)
// p.Interface() is a pointer to the value stargazer.Interface()
Example:
dave := "It's full of stars!"
stargazer := reflect.ValueOf(dave)
for i := 0; i < 10; i++ {
p := reflect.New(stargazer.Type())
p.Elem().Set(stargazer)
stargazer = p
}
fmt.Printf("%T\n", stargazer.Interface()) // prints **********string
I'm trying to add my own enum in MotionWorks.
After creation of new data type the only available types are ARRAY,STRING,STRUCT.
Writing the following code:
TYPE SimulationType:
(
Passing := 0,
Random := 1,
Failing := 2
) INT := 0;
END_TYPE
does not compile.
Yaskawa seem to be complying to ENUM (according to this list) but I can't figure out how to declare it.
Edit:
I can do the following:
TYPE
ResultType:(Pass, Random, Fail);
END_TYPE
But it doesn't seem to create an enum, as I can't access it's value. I can access it like a structure.
Edit 2:
If I declare:
TYPE
ResultType:(Pass, Random, Fail);
END_TYPE
And set variable
ExpectedResultType : ResultType;
Then in the code I try to use:
IF ExpectedResultType = ResultType.Pass THEN
Done := TRUE;
END_IF;
It compiles, but will not run.
Trying to use this code will not compile:
CASE ExpectedResultType OF
ResultType.Pass:
Done := TRUE;
Error := FALSE;
ResultType.Random:
Done := TRUE;
ResultType.Fail:
Error := TRUE;
Done := FALSE;
END_CASE;
Enums in MotionWorks are declared in data types as this example:
TYPE
MyEnum:(Zero,One,Two,Three);
END_TYPE
ENUMs in MotionWorks can't be assigned a value. First enum will always be equal to 0 (zero), second one to 1 (one), and so on.
Then enums can be used in IF .. END_IF statements like this:
I'll call my variable "i". The variable must be declared as INT. Any other type will not work.
In the code use it like this:
IF i = MyEnum#Zero THEN
(* do some work *)
ELSIF i = MyEnum#One THEN
(* do some other work *)
END_IF
ENUMs can't be used in CASE statements in MotionWorks.
This what I have for Schneider which is IEC61131 so it should be the same
TYPE E_HomeLimitSwitch:
(
ePositiveDirectionRisingEdge := 0,
eNegativeDirectionRisingEdge := 1,
ePositiveDirectionFallingEdge := 2,
eNegativeDirectionFallingEdge := 3
);
END_TYPE
I don't think you INT:=0 should be there.
You can only set the default value to one of your local enum members. Not to other values or even a number as you tried.
Try this instead in line 6:
) INT := Passing;
unlike Codesys, Yaskawa's MotionWorksIEC does not fully support enumerations. In ST language enum usage is quite popular in CASE statements but MotionWorksIEC does not support enum use in case statements.
But, you still can define enums as shown below.
TYPE
PackMLState:(Starting,Starting,Aborting,Aborted,Helding,Held,Etc);
END_TYPE
You can use the enum type as;
IF machineState = PackMLState#Starting THEN
;;
END_IF
Comparing Codesys and MotionWorksIEC (Which is basically Phoenix Contact, KW Software Multiprog), there are some differences. For clarification, the lack of enum use in Cases doesn't make Multiprog an inferior IDE.
I have a []*Cookie array, but how to get []Cookie array? I tried to use the * symbol but there was a syntax error.
Go does not provide an automatic conversion from slice of pointers to values to a slice of values.
Write a loop to do the conversion:
result := make([]Cookie, len(source))
for i := range result {
result[i] = *source[i]
}
I saw in some Specman e code example the use of := (colon-equal sign), e.g.:
var regs_type := rf_manager.get_exact_subtype_of_instance(graphics_regs);
When and why should we use := ?
Thank you for your help.
The := means declare a variable of the type the expression on the right returns and assign it to that value. Basically, in your example, the function get_exact_subtype_of_instance(...) returns a value of type rf_struct. The regs_type variable will be declared to that type.
This code is equivalent to (but shorter than):
var regs_type : rf_struct = rf_manager.get_exact_subtype_of_instance(graphics_regs);
This syntax is particularly helpful when casting:
var foo := some_struct.as_a(FOO some_struct_type);
example code (edited code snippet): http://play.golang.org/p/eZV4WL-4N_
Why is it that
for x, _ := range body.Personality {
body.Personality[x].Mutate()
}
successfully mutates the structs' contents, but
for _, pf := range body.Personality{
pf.Mutate()
}
does not?
Is it that range creates new instances of each item it iterates over? because the struct does in fact mutate but it doesn't persist.
The range keyword copies the results of the array, thus making it impossible to alter the
contents using the value of range. You have to use the index or a slice of pointers instead of values
if you want to alter the original array/slice.
This behaviour is covered by the spec as stated here. The crux is that an assignment line
x := a[i] copies the value a[i] to x as it is no pointer. Since range is defined to use
a[i], the values are copied.
Your second loop is roughly equivalent to:
for x := range body.Personality {
pf := body.Personality[x]
pf.Mutate()
}
Since body.Personality is an array of structs, the assignment to pf makes a copy of the struct, and that is what we call Mutate() on.
If you want to range over your array in the way you do in the example, one option would be to make it an array of pointers to structs (i.e. []*PFile). That way the assignment in the loop will just take a pointer to the struct allowing you to modify it.