Change pin mode for Arduino in Simulink

I'm trying to compile a Simulink program that uses a stateflow chart with an Arduino board as my target. I keep getting the error: "Both the 'Digital Output' block and the 'Digital Input' block use the pin number 7. Change the value of the parameter 'Pin number' on the 'Digital Output' block, or the value of the parameter 'Pin number' on the 'Digital Input' block so that the parameter conflict is resolved." However, I need to be able to change the pin mode in my application. A pulse has to be sent to the ultrasonic sensor and then it has to wait for a return pulse. I'm not sure how to change the pin mode in Simulink from output to input. Any help on this would be appreciated. Thanks.

 Accepted Answer

Ryan G
Ryan G on 21 Sep 2012
What's going on is each pin can only do 1 thing, as pin 7 can ONLY be used for output or ONLY be used for input.
Looking at this ultrasound sensor and the code that follows, they are discretely switching the pin 7 later on. There is an answer here which says this cannot be done directly.
There are 2 options as I see it:
1) Instead of using the Simulink I/O blocks, you can write an s-function that will perform the digital i/o
2) Find a sensor that uses 2 pins instead of 1.
You should have the code for the digital I/O already (I think that's what's on the sensor link above) so all you would need to do is implement that via s-function.

8 Comments

I don't see how I would be able to write an s function for the arduino board. I know I can use arduino specific functions such as pinMode() if I download and install this support package: http://www.mathworks.com/academia/arduino-software/arduino-matlab.html . However this requires a server program to be running on the arduino board in order to be able to interpret the commands. It seems like if I tried incorporating an s function that includes arduino specific commands with the control logic in simulink then it would no longer work because the onboard server program would get overwritten with the new program.
Under the hood the I/O blocks are s-functions, although I honestly do not know what's in them. There may be something on file exchange or in the Arduino community but I couldn't really say.
The main issue with what you're trying to do has a lot to do with the way Simulink is trying to operate as a single unit, not line by line. Although there are ways to try and tell Simulink which one you want to trigger first (input or output) it doesn't necessarily play well with the code that will be generated on the arduino target.
I'm a bit less familiar with how MATLAB talks to arduino but it may be possible to use the MATLAB arduino calls in a matlab function block, but that seems like a long shot.
I have tried using a matlab function block. There seems to be a bunch of errors when trying to get it to work with the code generator. For example, it complained that the delete function wasn't supported by the code generator. I tried commenting that out and then it complained try-catch statements weren't allowed. I tried moving statements out of the try-catch block but then it complained of an undefined variable even though it was defined in the properities block. I'm not sure what properities are but maybe I can correct this after looking into it further. I know my code works because it runs as a stand alone m script. It only runs into problems when I try using it as a function in Simulink. Also the errors have to do with the Arduino.m file that comes with the support package.
Does MATLAB generate code for arduino for the m-file or just run it as-is and send the commands to the target? Simulink will actually generate code, send that to arduino and then you can run the arduino standalone with that code.
You can look into the coder.extrinsic function to add the code to Simulink, but I'm not sure how well that would work for the target application here.
The Matlab m-file just sends commands to the arduino over the serial port and a program running on the arduino interprets the commands and can send data back. In this case I would actually prefer if Simulink didn't try to compile C code. If it would just run as a purely Matlab program running on my PC then that would work out great. Is it possible to run coder.extrinsic on everything?
Technically you could write a m-file function, define extrinsically:
coder.extrinsic('myfunc')
and then use that in the embedded MATLAB.
If you are comfortable with non-realtime operation, you could write the MATLAB code and send the data from the MATLAB code to Simulink via the sim command, save the final states, which is an option in simulink configuration parameters, then loop back around reloading the last states and simulating for 1 time step each loop iteration. Every iteration of the loop you save the states and reload them in simulink but don't run simulink on the target.
Thank you. That worked. By encapsulating all my m-code into a function and then using the coder.extrinsic command in an Matlab function simulink block, I was able to get the sensor readings. I also modified the server code that's installed on the Arduino to be able to read in the return pulse and so that I would only have to send one command from Matlab over the serial link in order to get the distance measurement. The only problem I see with this solution is that I have to leave the Arduino tethered to my computer but that's OK.
It's great to hear that you worked this out. May I suggest you make an enhancement request since it looks like using the same pin I/O is a common workflow for this type of sensor.

Sign in to comment.

More Answers (0)

Categories

Tags

Asked:

on 21 Sep 2012

Community Treasure Hunt

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

Start Hunting!