matlabvectorindexingsimulinkenumeration

Simulink: Use Enumeration As Index


I feel like this is something that'd be absurdly easy in C# but is impossible in Simulink. I am trying to use an enumerated value as an array index. The trick is: I have an array that is sized for the number of elements in the enumeration, but their values are non-contiguous. So I want the defined enumeration and Simulink code to read the value at A(4). Obviously, it will instead read A(999). Any way to get the behavior I'm looking for?

classdef Example < Simulink.IntEnumType
    enumeration
        value1 (1)
        value2 (2)
        value13 (13)
        value999 (999)
    end
end

// Below in Simulink; reputation is not good enough to post images.
A = Data Store Memory
A.InitialValue = uint16(zeros(1, length(enumeration('Example'))))

// Do a Data Store Read with Indexing enabled; Index Option = Index vector (dialog)
A(Example.value999)

Solution

  • After a weekend of experimentation, I came up with a working solution: using a Simulink Function to call a MATLAB function that searches for the correct index using the "find" command. In my particular instance, I was assigning the data to Data Store Memory, so I was able to just pass the enumeration index and a new value to these blocks, but you could just as easily have a single input block that spits out the requested index. (My reputation is still too low to post pictures, so hopefully my textual descriptions will suffice.)

    Data Store Memory 'A': Data type = uint16, Dimensions = length(enumeration('RegisterList'))
    
    Simulink Function: SetValueA(ExampleEnum, NewValue)
    --> MATLAB Function: SetA_Val(ExampleEnum, NewValue)
        --> function SetModbusRegister(RegisterListEnum, NewValue)
    
            global A;
    
            if(isa(ExampleEnum, 'Example'))
                A(find(enumeration('Example') == ExampleEnum, 1)) = NewValue;
            end
    

    From there, you use the Function Caller blocks in Simulink with the "Function prototype" filled in with "SetValueA(ExampleEnum,NewValue)" anywhere you wish to set this data. The logic would get more complicated if you wished to use vectors and write multiple values at once, but this is at least a starting point. It should just be a matter of modifying the Simulink and MATLAB functions to allow vector inputs and looping through those inputs in the MATLAB function.

    EDIT 1

    Slight update: If your MATLAB function is set up such that you cannot use variable-length vectors in it, just replace the "find" function with the "ismember" function. Using a scalar in ismember always returns a scalar, and the MATLAB compiler won't complain about it.