MATLAB Answers

How do I make a device driver block that outputs data from a global array?

18 views (last 30 days)
I am using Simulink and the Simulink Support Package for Arduino Hardware to generate and run C/C++ code on an Arduino Mega 2560. Everything works great, but I would like to develop a custom device driver. I went through the "Create a Digital Read Block" and I got that working.
For my application I need the source block to output the contents of a global array instead of just a scalar value. Coder.ceval only returns a scaler value.
So my question is how do I modify this function so I can output an array
function y = stepImpl(obj) %#ok<MANU>
y = double(0);
if isempty(coder.target)
% Place simulation output code here
else
% Call C-function implementing device output
y = coder.ceval('source_output');
end
end

  0 Comments

Sign in to comment.

Accepted Answer

Matt Griffith
Matt Griffith on 23 Dec 2020
Hey Everyone,
I finally figured out something that works. coder.opaque was not the answer, or if it was I could not get it working. This is probaly somewhat of a hack, but it works. So the really cool part about setting up a device driver block is that it allows you to copy paste cpp code straight from an example arduino sketch and use it, however I couldn't find any way for the device driver block to output a global array that I had defined in my driver cpp file.
The solution was to use a stateflow chart instead. All I had to do was make a structure that had my array in it in my global array in my driver .h file and then include that header file in the configuration paramters -> simulation Target -> header file.
Then I could drop in a stateflow chart that just outputs the array. This example was very helpful.
sf_custom

  0 Comments

Sign in to comment.

More Answers (1)

Mark McBroom
Mark McBroom on 12 Dec 2020
You will need create the matrix in your MATLAB function and then pass it to your C Function as an argument, encapsultated in teh coder.wref() function so that MATLAB will pass it by reference to your C code. See this link for details and example: https://www.mathworks.com/help/simulink/slref/coder.wref.html

  3 Comments

Matt Griffith
Matt Griffith on 12 Dec 2020
Oh I get it now. I read the help on coder.ref() , but I didn't understand I would define my array in Matlab instead of C. Ok one wrinkle.
In my C code I defined my array as volatile, because it is used by a pin change ISR. How do I do that now that I am defining my array in Matlab and then passing the reference to my C function?
Matt Griffith
Matt Griffith on 15 Dec 2020
Ok I'm having trouble setting up coder.opaque. Inside the matlab command window I can create the system and successfully call .step(). I also have the system in Simulink and I can simulate, no big surprize as it doesn't do anything for simulation, however when I try to build I get the following error message:
Simulink detected an error 'Top-level output parameter y0 has unknown or opaque type.'. The error occurred for MATLAB System block 'EncoderTest/MATLAB System'. To prevent this error, modify the System object to avoid code that does not support code generation.
Maybe coder.opaque isn't the answer. This was supposed to be just a simple test to get things up and running. Ideally what I want to do is return a 6 element array of uint32 type that was declared as volatile. I'm just mentioning that to keep that in mind.
I have attached the .m file for the system and the .slx file, but unfortunately I can't attach .cpp or .h files :( If I had to guess I would say the problem is here:
function EncoderCounts = stepImpl(obj) %#ok<MANU>
EncoderCounts = coder.opaque('int','0');
if isempty(coder.target)
% Place simulation output code here
EncoderCounts = 0;
else
% Call C-function implementing device output
coder.ceval('EncoderDriverStep');
end
end

Sign in to comment.

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by