File Exchange

image thumbnail

Device Drivers

version (1.88 MB) by

Developing Simulink Device Driver Blocks: Step-By-Step Guide and Examples

47 Ratings



View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

This package contains a guide that explains, in a step-by-step fashion, how to develop device driver blocks (blocks that perform target-specific functions when executed on a target platform).
Example drivers for:
-) Arduino digital output
-) Arduino digital input
-) Arduino analog output
-) Arduino encoder read
are included.

While the examples are built using the Arduino as the hardware platform (specifically relying on the Simulink Support Package for Arduino), the method applies to any other supported target.

In this guide, the first method to develop device drivers is based on the S-Function Builder block. Following chapters also describe different methods based respectively on the Legacy Code tool, the MATLAB function block, and the System Object block. Advantages and disadvantages of each method are discussed in the guide.

Finally, note that for MATLAB 2013b you will need to apply a fix for the S-Function builder to develop blocks with no input. To do so, go to the following page: , scroll down to the bottom, and follow the instructions therein.

Comments and Ratings (110)

sager alswed

I want to use the S function builder to get analogRead from arduino uno, however in my code generation report shown an error : cannot open source file "Arduino.h" for file: C:\MATLAB\SupportPackages\R2016a\toolbox\target\supportpackages\arduinotarget\scheduler\include\arduinoAVRScheduler.h
how can I add the source file "Arduino.h" in my model?

ali soltani

very very very good


Perry (view profile)

Very nice guide that explains concepts well.....

I was trying to follow the Matlab System Object method for Raspberry Pi driver development. However, the example (digitalio_raspi_test.slx) failed to build with the error:
### Build procedure for model: 'digitalio_raspi_test' aborted due to an error.
Function TAR tried to add two files as "digitalio_raspi.h".

I am using 2016b and Raspberry Pi support package was downloaded about 1 month ago. I am interested in the System Object method since I will need to link several libraries.

Really helpful

Hi, anyone knows or have done a driver for the L3G gyroscope sensors from pololu?

Hi, anyone worked on encoder to read the speed in Raspberry Pi 3 using simulink blocks or SFunction?

@Murat Belge,
Works perfect! Thanks a lot :)

Murat Belge

@Mohamed: You can use a MATLAB function block to read temperature from a DS18B20. The MATLAB code is provided below. Note that it takes about 750ms for a single temperature conversion.

function temperature = readDS18B20()

persistent sensorPath;

if isempty(sensorPath)
    path = '/sys/bus/w1/devices/28-031561e430ff';
    fileSeperator = '/';
    sensorPath = [path,fileSeperator,'w1_slave'];

% Open file, read, and close it
fid = fopen(sensorPath);
w1_slave = fread(fid,1024);

% Convert to text
w1_slave = char(w1_slave');

% Find raw temperature data in 1/1000th of a degree Celcius
stringToFind = 't=';
stringToFindLength = length(stringToFind);
temperatureIndices = strfind(w1_slave,stringToFind)+stringToFindLength;
temperatureIndexStart = temperatureIndices(end);
temperatureIndexEnd = temperatureIndexStart+5;
temperatureString = char(w1_slave(temperatureIndexStart:temperatureIndexEnd));

% Convert to Celcius
temperature = real(str2double(temperatureString))/1000;

any idea to get the temperature readings from DS18B20 in Raspberry Pi using any of these files?

peter sender

I can't download the file!



zheng Hu

Why can I not downland?


Dzung (view profile)

Hi, could anyone tell me how to develop my own hardware support packages? Thanks in advanced.

Giampiero Campa

Giampiero Campa (view profile)

Hazem, maybe you forgot to build the S-Function, by clicking "Build" on the S-Function Builder ?

hazem saaad

I have a serious problem and I need help.When I run the simulink file,I get the following message "
Error in S-function 'encoder_slsp/Encoder': S-Function 'sfcn_encoder' does not exist".



Thanks for the great job Giampiero! I've tried the samples on Uno with 2015a and it works perfectly.
Now I try to write a CAN driver for the CAN-BUS shield.
First, I'd like to make an init function to set the CAN speed with a Matlab system block. This block has no I/Os, but when I try to update the model, I get:
MATLAB System block 'can_test/MATLAB System' error occurred when invoking 'isOutputFixedSizeImpl' method of 'CANSetup'. The error was thrown from '
 'C:\Program Files\MATLAB\R2015aSP1\toolbox\simulink\simulink\+SLStudio\ToolBars.p' at line 1175'.

Reported by CANSetup: Incorrect number of outputs for the isOutputFixedSize method; 1 were requested, but the method returns 0, as specified by the getNumOutputs method.

I don't understand, since I've put num = 0 for both getNumOutputsImpl and getNumInputsImpl functions.

Then I need to include the CAN and SPI libraries. How can I do that with the system block method?

Thank you.

Giampiero Campa

Giampiero Campa (view profile)

Ok, great ! Thanks !
I'm going to try too then, at some point (maybe in a few weeks or so) just out of curiosity...

Thanks again.


Thanks for you response.

I tried it before I wrote the comment and it worked normally without the need to rebuild the S-Function every time the sample time or the parameters are changed.

However, just to make sure I checked it again right now but it works for me.

Giampiero Campa

Giampiero Campa (view profile)

Hi Marcell, thanks for the feedback.

You can certainly place the S-Function Builder block in a subsystem and write a mask for it, and you can use it to pass "normal" parameters (the ones defined as such in the data properties pane). This will work as these parameters are read from the mask and passed down to the S-Function before each execution.

However, I'm pretty sure that both the Sample Time and the initial conditions, which are defined in the initialization pane, are hardcoded in the executable (and the TLC file) every time you press the "Build" button in the S-Function builder.

Therefore, if you encapsulate the S-Function Builder block in a subsystem, build a mask for it, and change the sample time in this mask, I am afraid that the change will NOT get propagated down until you rebuild the S-function (so you - or the user - have to look under the mask, double click the S-Function Builder block, and click on "Build".

I think that doing so is misleading for the user, who might think that the sample time gets propagated down without any problem every time it gets changed from the upper level mask.

Now, that being said, I haven't explicitly checked this in the last 2 or 3 years at least, so, just in case I'm wrong (which I don't think it's the case, but still), I invite you to try and double check for yourself, (and let me know).



Wonderful package thank you it helped me a lot with my work.

I just wanted to point out, that one can actually use the S-function approach with user defined sample times from the mask. One just have to place the S-function block into a subsystem and define a sample time parameter in the subsystem’s mask. Then specify a parameter with the value of the name of the sample time parameter of the subsystem’s mask. Then write the parameter’s name in the sample time value field inside the initialization tab of the S-function.

This method also eliminates the need to right click the S-function in order to change the mask parameters.


lays25 (view profile)

I also tried using the method suggested earlier by Phil and MathWorks Classroom Resources Team (referencing to page 20 of the Guide) - adding "extern "C"" and renaming the wrapper file to .cpp but then I get another problem. The model is built and downloaded to my Arduino and... nothing happens. There is no communication, TX/RX diodes are off and I get the following error: Unable to connect to the 'Arduino Due' target for 'encoder_slsp'.

arman sani

The detail of the walk-through is exquisite. Thank you very very much.

Robert Noble

To start, excellent package, great info, lots of detail A+++.
I'm using R2013a, with Windows XP, Microsoft SDK 7.1, Arduino MEGA 2560.
I have been working on a LCD block using an S-function builder block. I spent a long time trying to get it to work but struggling due to an error. The start of the error is shown below. After trawling the internet searching and finding very little I tried changing the LiquidCrystal.h and .cpp files I had in my working directory to the ones from the MATLAB support package folder. This fixed the problem, briefly. On shut down, my computer did a Windows update. The day after, I had a go at adding more to the block, on opening the model file I got a load of warning messages about File I/O from "arduino.h" (I don't have the message to hand). Now my LCD block won't build and I get a java error to do with getting ports. So, started again, and it worked, added some inports to the S-function, and crash. I now get intermittent java errors when trying to build, or I get the realtime_make_rtw hook error shown below. Again.

This is extremely frustrating and I am running out of ideas. Any info/ help would be fantastic. Thanks in advance.


The call to realtime_make_rtw_hook, during the after_make hook generated the following error:
The build failed with the following message: "C:/MATLAB/SupportPackages/R2013a/arduino-1.0/hardware/tools/avr/bin/avr-gcc" -I"C:/ArduinoStuff/arduinoMEGA2560_LCD_02_rtt" -I"C:/ArduinoStuff" -I"C:/Program Files/MATLAB/R2013a/extern/include" -I"C:/Program Files/MATLAB/R2013a/simulink/include" -I"C:/Program Files/MATLAB/R2013a/rtw/c/src" -I"C:/Program Files/MATLAB/R2013a/rtw/c/src/ext_mode/common" -I"C:/Program Files/MATLAB/R2013a/rtw/c/ert" -I"C:/MATLAB/SupportPackages/R2013a/arduino-1.0/hardware/arduino/cores/arduino" -I"C:/MATLAB/SupportPackages/R2013a/arduino-1.0/hardware/arduino/variants/mega" -I"C:/MATLAB/SupportPackages/R2013a/arduino/include" -I"C:/MATLAB/SupportPackages/R2013a/arduino-1.0/libraries/Servo" -mmcu=atmega2560 -std=gnu99 -Wall -Wstrict-prototypes -g -Os -D"MODEL=arduinoMEGA2560_LCD_02" -D"NUMST=1" -D"NCSTATES=0" -D"HAVESTDIO=" -D"ONESTEPFCN=0" -D"TERMFCN=1" -D"MAT_FILE=0" -D"MULTI_INSTANCE_CODE=0" -D"INTEGER_CODE=0" -D"MT=0" -D"CLASSIC_INTERFACE=0" -D"TID01EQ=0" -D"F_CPU=16000000" -D"_RUNONTARGETHARDWARE_BUILD_=" -D"_ROTH_MEGA2560_=" -D"_RTT_NUMSERVOS_=0" -c -x none ./arduinoMEGA2560_LCD_02.c ./arduinoMEGA2560_LCD_02_data.c ./ert_main.c ./sfcn_LCD_wrapper.cpp ./HardwareSerial.cpp ./Print.cpp ./WInterrupts.c ./WMath.cpp ./WString.cpp ./new.cpp ./wiring.c ./wiring_analog.c ./wiring_digital.c ./io_wrappers.cpp
In file included from ./ert_main.c:18:
C:/MATLAB/SupportPackages/R2013a/arduino-1.0/hardware/arduino/cores/arduino/Arduino.h:24:1: warning: "true" redefined
In file included from ./arduinoMEGA2560_LCD_02.h:23,
from ./ert_main.c:17:
./rtwtypes.h:158:1: warning: this is the location of the previous definition
In file included from ./ert_main.c:18:
C:/MATLAB/SupportPackages/R2013a/arduino-1.0/hardware/arduino/cores/arduino/Arduino.h:25:1: warning: "false" redefined
In file included from ./arduinoMEGA2560_LCD_02.h:23,
from ./ert_main.c:17:
./rtwtypes.h:154:1: warning: this is the location of the previous definition
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
In file included from ./sfcn_LCD_wrapper.cpp:40:
C:/ArduinoStuff/LiquidCrystal.cpp:6:22: error: WProgram.h: No such file or directory
In file included from ./sfcn_LCD_wrapper.cpp:39:
C:/ArduinoStuff/LiquidCrystal.h:82: error: conflicting return type specified for 'virtual void LiquidCrystal::write(uint8_t)'
C:/MATLAB/SupportPackages/R2013a/arduino-1.0/hardware/arduino/cores/arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
./io_wrappers.cpp: In function 'void Serial_read(int, int, uint8_t*, int*)':
./io_wrappers.cpp:40: warning: 'libFcnOutput' may be used uninitialized in this function
make: *** [arduinoMEGA2560_LCD_02.o] Error 1

The build process will terminate as a result.

Robert Noble

Rusty Boyd


I'm having a problem with the LCT method. In both the example, I have problems with the 'DNO_OP=//' directive in the instruction,
legacy_code('compile', def, '-DNO_OP=//')
In the dout example, it only generates a warning. In my code, it generates a fatal error (the two warnings make sense in context of the error):
Error using mex
error: expected expression
warning: expression result unused [-Wunused-value]
  NO_OP( *u1, *u2);
warning: expression result unused [-Wunused-value]
  NO_OP( *u1, *u2);
Error in legacycode.LCT/compile (line 375)
Error in legacycode.LCT.legacyCodeImpl (line 84)
Error in legacy_code (line 87)
[varargout{1:nargout}] = legacycode.LCT.legacyCodeImpl(action, varargin{1:end});

In the dout example, it generates only 3 warnings.
I've tried bypassing LCT and using mex directly with the exact same results. I've tried both 2015a and 2015b - no diff. I'm using OS X 10.10.5 (14F27) and Xcode Version 6.4 (6E35b).

I hope someone can help.

Mohsen Omrani

A bit complicated for a novice programmer but the detail the go through is amazing. Thanks.

Barza Nisar

Excellent tutorial, thank you!

Suytry KY

Hi everyone,
I use the s-function encoder block in the model to read encoder pulses. If i use only one encoder, it is fine. But the simulink stop working when i use 2 or 3 encoder to read from my robot motors. Can anyone help me to solve this problem because i am supposed to use simulink with arduino to read encoder for my thesis project. NOTE: I do as external mode for real-time test.
Thanks in advance!

Henrik Simon


I also tried this guide with my raspberrypi.

Is there also a librarie for the raspberry?
# include <Arduino.h>
# endif

Does this instruction works with a raspberry?

John Parsons

Giampiero, very very helpful information, thank you. Question for Nancy can you publish your SD code? i would find this very useful.

huan xia

so great!

I bumped into the following error message and found a solution:

The call to realtime_make_rtw_hook, during the after_make hook generated the following error:
The build failed with the following message: make: *** No rule to make target `../../../../../../../../../../../../MATLAB/SupportPackages/R2014a/arduino-1.0.5/hardware/arduino/cores/arduino/HardwareSerial.h', needed by `HardwareSerial.o'. Stop.

The issue was that I was building the model from a directory where the path was too long. i.e. C:/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvxyz/

When I built the model in directory with a shorter path i.e. C:/Documents, I no longer experienced this error.


Sina (view profile)

Also, I have done what you mentioned. But the main problem is to do with the C++ and C differences I suppose. I will email you the error description I get when building the simulink model on Arduino.


Sina (view profile)

Thanks a lot Giampiero,
That helped a lot. How do I go about declaring global variables/ functions/ libraries? I know in the libraries pane there are 3 sections,
1. Library / Object / Source file
2. Includes
3. External Function Declarations

Can you make an example?
Alternatively, would you mind taking a quick look at my simple model? I can email it to you.


Giampiero Campa

Giampiero Campa (view profile)

Hi Sina,
well, you can't just copy and paste all your code in the output pane, remember that the initialization and global variable and function definitions must go into the Library->Includes pane, the initialization code (that is the part contained in the "setup" function below) must go into the Discrete Update pane, and only the part contained into the "loop" function, which needs to be executed at every time step, must go into the Output pane.

I'd suggest you have another look at the guide, and start building up things gradually from a simple example that works.



Sina (view profile)

Hi Giampiero and Everyone,
I have a question, I used this guide and built a block to be able to read some input numbers from simulink and pass the numbers to an arduino code so that using motor driver and encoder library it can run the motor. I have written this as my output:

/* wait until after initialization is done*/
if (xD[0]==1){
    /*don't do anything for the Mex-file generation */

    #ifndef MATLAB_MEX_FILE
/* MYCODE which is normally run on arduino and uses two libraries: Encoder and DualVNH5019MotorShield */

#include <Encoder.h>
#include <DualVNH5019MotorShield.h>

unsigned int DEBUG = 1;
unsigned int ms_delay = 200;

// setup pin variables
const int encoderChanA = 2; // pin2 for interrupt0 on timer2
const int encoderChanB = 3; // pin3 for interrupt1 on timer2
Encoder motorEncoder(encoderChanA,encoderChanB);
// setup pins for motor control and current sense
unsigned char INA1 = 8; // sets motor direction
unsigned char INB1 = 10; // sets motor direction
unsigned char EN1DIAGA = 5; // sets motor speed, pin5 for PWM on timer0 (to avoid problems with interrupts on timer2)
unsigned char CS1 = A1;
DualVNH5019MotorShield mdriver(INA1,INB1,EN1DIAGA,CS1,INA1,INB1,EN1DIAGA,CS1); // repeat arguments to simulate second driver (part of API but not actually used)
// setup global variables
float currentMotorSpeed = 0;
long currentEncoderPosition = 0;
int currentMotorCurrent = 0;
float desiredSpeed = 0;
int u = 0; // placeholder input variable 0-9
// Function declaration

void setup()
  // setup code here
  pinMode(encoderChanA, INPUT);
  pinMode(encoderChanB, INPUT);
  digitalWrite(encoderChanA, HIGH);
  digitalWrite(encoderChanB, HIGH);

void loop()
  // 2) read encoder position, and motor current
  currentEncoderPosition =;
  currentMotorCurrent = mdriver.getM1CurrentMilliamps();
  // 3) Set speed for motor 1, speed is a number betwenn -400 and 400

This code uses functions that are declared in the included libraries. and I did include those in the supported libraries pane and added the libraries to current matlab folder.
It builds the block but the model cannot be built on my Arduino Uno. (there are some errors)
Would you please elaborate?


Carlos (view profile)

Many thanks for your tutorial, now Simulink has become even more powerful to me. Is there a way to remove the tedious pasting the .cpp and .h at the current MATLAB directory for successful compilation?


Does someone make a simulink block to use DS1302 real time clock?
I try it, but I did not succeed.
Please, help with some sugestions.

Simulink with arduino : data acquisition
Hello all ,
i'm working on data acquisition from a sensor attached to the arduino : MPU6050 using a model in simulink , i have installed the hardware support in simulink but i don't know how to start building the model , the model must read the data from arduino by deploying it into the arduino
my connection arduino <=> MPU6050 is :

   Arduino MPU 6050
     3.3V VCC
     GND GND
     A5 SCL
     A4 SDA
     GND AD0

any help will be appreciated


Nancy (view profile)

Solved! Thanks


Nancy (view profile)

when I tried to deploy a simulink model that contains fuzzy logic controller block it didn't work :s . Is there a way to deploy it to Arduino Mega ?


amir (view profile)

Great! after 1 month working on an encoder with 8400cpr to read the data by arduino mega2560 and NO answer, today I did it just using by this work.


Simon (view profile)


I built an own arduino Stepper library for arduino uno and now i want to embed it into simulink.
The problem i have is that i use:


instead of the common:


structure, because the init() function in the common structure interferes my library functions.

I tried to use the s-function builder instruction with my library and i had the same issues as i had when writing functions of my library into the common(setup(),loop()) structure.

My question:

Is there a way to use the main() structure instead of the void(),loop() structure using the s-function builder {with arduino uno and the simulink support package of matlab}?

What i tried so far:
- deleting the init() function call in the main function of the s-function builder block created modelname_rtt folder.
- changing the init(){as a part of the wiring.c} so that it executes the setup for my library.

By the way thanks for your great tutorials.

Best Regards,

Giampiero Campa

Giampiero Campa (view profile)

For Daniel and other interested, Nancy was able to solve the issue by doing 3 things:

1) Copying the utilities folder to the current directory In addition to copying its content in the same folder.

2) Including the SD.h in addition to the SD.cpp

3) Transfering the whole directory to a file path that has no spaces.

Note that #3 is always necessary to make things work due to the use of GCC. In this case i think #1 (and perhaps also #2) made the trick.

Giampiero Campa

Giampiero Campa (view profile)

i don't know how to make it work with external mode and i am sure is not easily doable with this method. It might be not even feasible. I'll let you know more if i find anything.

Also, if i don't know what error it is that you are finding, it's hard for me to have a clue :)


Minho (view profile)

I have question. If i want sfcn_encoder bolck use external mode. How can I do?
I do wrapper.c -> wrapper.cpp and add extern "C".
But It has error.

I am having the same issue as Nancy.


Nancy (view profile)

I'm trying to use the SD card library , I get this error when I build the model;

 The call to realtime_make_rtw_hook, during the after_make hook generated the following error:
    The build failed with the following message: make: *** No rule to make target `../../../../../../../../../../../../MATLAB/SupportPackages/R2014a/arduino-1.0.5/hardware/arduino/cores/arduino/HardwareSerial.h', needed by `HardwareSerial.o'. Stop.

Any help will be appreciated.



zhubo (view profile)



Hello i started with arduino (uno) and matlab by modeling a blinking model. But i have a problem to run the model with my arduino uno card. I go to the tools menu for 1st time for to Prepare to Run the model and at the 2nd time, i don't see the option : Run. That is my problem. Is someone can help me. Thanks


German (view profile)

Nice work, very helpful


JimC (view profile)

This is a great help to get started. I've been able to tweak the encoder block for speeds.
I can't seem to create a driver block that uses the serial comms commands though. I tried including the HardwareSerial.h and .cpp files in the library pane and ran renc2cpp.
Any trick needed?



phil (view profile)

Has anybody been able to make an interrupt block?


uavc (view profile)

In case anyone wanted to compare the Output Driver S-Function Block to Arduino code, here is the arduino code:

#include <Arduino.h>

int xD[0];
int pin[] = {12};
int in[0];

void setup()
  if (xD[0]!=1) {
    /* don't do anything for MEX-file generation */
    /* initialization done */

void loop()
  /* wait until after initialization is done */
  if (xD[0]==1) {
    /* don't do anything for mex file generation */


Mehmet (view profile)


I wonder,how overruns on Arduino Hardware affect software . Because all example drivers give ovverruns error without input and output drivers.



Neil (view profile)

Hello thank you for the reply. I have finally got it working with much success. I'm still not sure where the "inlined" error came from but now it's gone.

I have a question for you. I'm trying to use global variables throughout the simulink model. It works if I call the variable within the same s-function as your guide said. However, if I call that variable in another S-function it gives me an error " error: <variable> undeclared (first use in this function)" pertaining to the wrapper file. I find this strange since all my calls to functions within the "#includes" headers work.

For example, my includes section looks as shown below:

#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int uart0_filestream = -1;

# endif

I can call all functions within the first 3 headers, however, if I call uart0_filestream in another block I get the error.


Neil (view profile)


Neil (view profile)

I have not been able to get this to work at all. I'm using MATLAB 2013a Student version. I generate C code using the steps provided. However, when I try to download it to the Arduino, it gives me an error that the function is not in-lined and therefore cannot be downloaded to the target. It tells me to go into the configurations->Simulink Coder and turn in-lining off but since I'm using the student version I don't see this option. Has anyone gotten this error before? I see no where in the documentation


phil (view profile)


phil (view profile)

has anybody been able to get the Arduino Ethernet library to work>? i keep getting errors which seems to be related to the IP adress class

C:/MATLAB/Targets/R2012b/arduino-1.0/hardware/arduino/cores/arduino/IPAddress.h:33: undefined reference to `vtable for IPAddress'

the code in this file:
class IPAddress : public Printable {
    uint8_t _address[4]; // IPv4 address
    // Access the raw byte array containing the address. Because this returns a pointer
    // to the internal structure rather than a copy of the address this function should only
    // be used when you know that the usage of the returned uint8_t* will be transient and not
    // stored.
    uint8_t* raw_address() { return _address; };

i havent even called any functions. at this point i am simply trying to include the ethernet library.

Giampiero Campa

Giampiero Campa (view profile)

IMPORTANT UPDATE: For MATLAB 2013b you will need to apply a fix for the S-Function builder (otherwise an incorrect argument list will be generated for a block that has no inputs).

Go to the following page:
scroll down to the bottom, and follow the instructions therein (it basically
comes down to saving the zip file, opening winzip as administrator, and
unzipping the file in the MATLAB folder (e.g. C:\Program Files\MATLAB\2013b).

Also note that another issue in MATLAB 2013b causes high memory usage on the
Arduino side, and thus prevents the upload of models that have many blocks
and/or high memory requirements. This might sometimes be a problem for boards
with smaller memory footprint like the Uno or Nano.


uavc (view profile)


uavc (view profile)

found the problem. the libraries I had to include in the simulink s-function builder was

# include <Arduino.h>
# endif

in that order. I accidentally put the second line first as I thought these were just regular includes, without recognizing that the include was running an if loop (ifndef.... end if) to check:


    The #ifndef operator checks whether something has not been defined using the #define keyword. It must be followed by#endif.

Problem solved. XD


uavc (view profile)


I'm trying to build the output block according to the tutorial. I'm sure this is a basic question but I couldn't quite build the S-function.


c:\docs\avr/io.h(330) : fatal error C1021: invalid preprocessor command 'warning'
  C:\PROGRA~1\MATLAB\R2013A\BIN\MEX.PL: Error: Compile of 'sfcn_exout_slsp_wrapper.c' failed.


I had earlier problems that the s-function builder wasn't compiling because it couldn't find Arduino.h, inttypes.h avr/io.h, avr/pgmspace.h, avr/sfr_defs
Arduino.h is the only .h file that is called directly from the s-function builder library so I guess the other files are being called by Arduino.h etc. I included the entire path of the Arduino library on the stock c:\program files(x86) directory but it didn't compile still. Hence, I just copied the whole folder into my working directory, still wouldn't work. What made it work was that I had to copy every single .h file (mentioned above) into the working directory (the answer to MATLAB command "pwd") before it would compile and then it led to this error above. I think it's an include error, so how do I ask the s-function builder to look everywhere within my working directory (which is especially important for the avr/xxx.h files.

any idea how to solve it? thanks!

Juan Jimenez

Great introduction to learn how to build custom driver blocks. Congrats!

Joshua Hurst

Hi Christian,

If you were looking specifically for I2C, MPU6050, or other I2C devices/hardware I posted a simple C-based I2C solution using WirnigPiI2C and you can find this here:

Let me know if this helps you!



Dan (view profile)

amzaing one that works. Thanks.


I have the same problem as Glen but with Arduino Mega and Support Package for Arduino. When i run the Target Hardware it does not include the wrapper .cpp in the _rtt folder, are there any solutions already?

thank you


Giampiero Campa

Giampiero Campa (view profile)

send me the files with the exact procedure that you are following and the error you are getting, i'll see if i can do anything.


Glen (view profile)


I have tried a number of different things to try and get the wrapper.cpp file included into the source_files listed in the .mk (make) file, rather than it being skipped. This has included editing the rtwmakecfg and trying to find the toolchain that is used to compile the .mk file. Editing the rtwmakecfg was unsuccessful. I did edit a Linux tool chain located in the "coder" directory. But I don't think it is the one that is used. The toolchain that is listed in the .mk file I cannot find - gmake, LinuxRemoteBuild.


Glen (view profile)


I have been trying again to get the MPU6050/HMC5883L model to build on the RPi. In the make file (.mk) which is included in the (_rtt) folder, when I rename the _wrapper.cpp file it is listed as a "SKIPPED_FILE". When I do not rename the wrapper.c is included in the "SOURCE_FILES". I have tried to get it included by editing the SFB.mat file but still no luck.

Joshua Hurst

Hi Glen,

I have a student working on the mpu6050 code for RasPi right now - getting it work in C and Python first. Then I will be porting it to Simulink most likely next week.

Feel free to send me an email directly and I can try to look at your files when I start start porting my students code:

In general for the Rpi you have to make sure the c-code compiles and on its own. If you look at the RPi examples I posted you have to make sure the #includes reference the local directory structure on the RPi - not your box. Just look at the Quadrature Encoder example for the RPi and you will see I had use: #include </home/pi/wiringPi/wiringPi/wiringPiI2C.h>. Which is where the files are on the RPi, not my actual computer. And don't forget to include the actual C files as well:
#include </home/pi/wiringPi/wiringPi/wiringPi.h>
#include </home/pi/wiringPi/wiringPi/wiringPi.c>

Let me know if this helps!



Glen (view profile)

Hi Giampiero,

Many thanks for your reply. I should explain more. I am trying to incorporate the libraries for the MPU6050 and HMC5883L. The code I have previously compiled on the PI. I used the Arduino MPU6050 S-Function Builder Example from Joshua Hurst as a Starting point and replaced the Arduino Libraries with the Libraries I have for the PI - including the I2Cdev. The S-function builds successfully. I then change the _wrapper from .c to .cpp and apply the extern "C" changes. However, when I run on target hardware - using the MATLAB Pi Support Package - it does not include the wrapper .cpp or any .cpp file in the folder (_rtt) it downloads to the PI to compile and run. If I leave the wrapper.c unchanged it does get incorporated into the _rtt folder but then I have unreferenced .cpp files not included.

I can send you my work so far if it helps.

Many thanks for your support.

Best Wishes

Hi Glen, there are several RasPi drivers, i believe with external libraries too, linked in the Acknowledgement section of this page.

I (Giampiero) would suggest trying them first to see if you can make them work, if so, start from them to see if you can build your driver. That being said i'll investigate further this case to see if anyone has any idea.


Glen (view profile)

Hi Giampiero,

I am trying build a model incorporating an S-Function Builder for my RaspPi. Because it includes C++ files I change the wrapper file extension to .cpp and at extern "C" infront of the Outputs and Update wrapper. However, when I run the model a further file is built with the extension _rtt and it does not include my wrapper file and other .cpp files within the file that gets downloaded to the RaspPi, hence I get undefined references.

I have tried a number of things but starting to go around in circles.

Any help would be appreciated.

Best Wishes

Giampiero Campa

Giampiero Campa (view profile)

you need to scroll up to see the upper part of the text. Maximizing the window might also help a little.


Mark (view profile)

Within the "afmotor_slsp" model, there is a block containing instructions titled "Double Click for Explanations". When I double-click, the instructions start with step 3...what are the first two steps???

   Thank you for your step by step explanation. I have tried to create my own servo and I am getting the following error when I have changed the name of the wrapper file generated to .cpp from .c

The call to realtime_make_rtw_hook, during the after_make hook generated the following error:
The specified file "servornd_wrapper.c" does not exist on the IDE and MATLAB paths.

Could you help me resolve this error.
Thanks in advance.

helped me a lot

thank you for that tutorial

Giampiero Campa

Giampiero Campa (view profile)

I'm glad that's working, Nathan.
Thanks Phil, that's great!


phil (view profile)

guys i have put together a little macro that will automatically make the necessary modification to the wrapper.c file
I found myself having to redo this for every rebuild of the S function and it was getting annoying.
The exe will add the extern "C" in front of the voids save/close and rename it to .cpp
gl - phil

Nathan Crosty

@Classroom Resources,
That was the trick. I can now use any library I wish in the S-Function builder. Thank you very much

Nathan Crosty

I added this line to my Library/Object/Source files pane in the s-function builder. It seems to take care of the path issue.

INC_PATH C:\arduino-1.0.3\libraries\Time

Nathan, if you include a .cpp file then you should rename the generated wrapper function from .c to .cpp, and also open it and write: ' extern "C" ' before the two function calls.

Please have a look at page 20 of the guide, which explains how to do this, and let me know if it works.


phil (view profile)

@ Nathan...
did you put the included files in the current matlab folder?

Nathan Crosty

I tried to follow your example and it worked great for interfaces that are in Arduino.h such as digital and analog IO. I ran into problems when trying to include other Arduino Libraries.

I noticed that you had included "AFMotor.cpp" and "AFMotor.h" in your examples, which I guess is similar what I am attempting with "DS1307RTC.h" and "DS1307RTC.cpp" which are libraries for keeping time.

I can build the sfunction with the sfunction builder when it is structured like you have it in your examples. When I go to build the applicaiton, however, I run into an issue that seems to be related to cpp code when the compiler is expecting c code. I am using the Arduino integration package found here

The compiler message I get when it attempts to build the header file with a class definition is this:

C:/ARDUIN~1.3/hardware/tools/avr/bin//avr-gcc -c -mmcu=atmega2560 -I. -DF_CPU=16000000 -Os -Wall -Wstrict-prototypes -std=gnu99 -I. -I.. -IC:/PROGRA~1/MATLAB/R2011a/rtw/c/ert -IC:/PROGRA~1/MATLAB/R2011a/extern/include -IC:/PROGRA~1/MATLAB/R2011a/simulink/include -IC:/PROGRA~1/MATLAB/R2011a/rtw/c/src -IC:/PROGRA~1/MATLAB/R2011a/rtw/c/src/ext_mode/common -Ic:/OU_SYSTEMS_ENG/GH/gh-dev/Simulink_Models/Drivers/GH_TopLevel_Test_arduino -Ic:/OU_SYSTEMS_ENG/GH/gh-dev/Simulink_Models/Drivers -Ic:/OU_SYSTEMS_ENG/GH/gh-dev/Simulink_Models -Ic:/OU_SYSTEMS_ENG/GH/gh-dev/Simulink_Models/Custom_Includes -Ic:/OU_SYSTEMS_ENG/GH/gh-dev/Simulink_Models/ArduinoML/blocks -IC:/arduino-1.0.3/hardware/arduino/variants/mega2560 -IC:/arduino-1.0.3/hardware/arduino/cores/arduino -IC:/arduino-1.0.3/libraries/Time -IC:/arduino-1.0.3/libraries/DS1307RTC -Ireferenced_model_includes -I../slprj/arduino/_sharedutils -IC:/ARDUIN~1.3/hardware/arduino/cores/arduino ../sfun_systime_get_wrapper.c -o sfun_systime_get_wrapper.o
In file included from ../sfun_systime_get_wrapper.c:39:
C:/arduino-1.0.3/libraries/DS1307RTC/DS1307RTC.h:12: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'DS1307RTC'
../sfun_systime_get_wrapper.c:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'sysTime'

Please let me know if you have any thoughts. I am wondering if this is still an issue with the newer Arduino support in later versions of ML/Simulink.

Joshua Hurst

Thanks Giampy!

With your driver guide we were able to make driver blocks for:

 - MPU6050 3 axis accelerometer/gyroscope
 - HC-SR04 ultrasonic range/distance sensor
 - L3GD20 3 axis gyroscope

And with all this we made a miniature Segway! You can find all the drivers and supporting libraries for the listed sensors here:

Thanks again!

Joshua Hurst


phil (view profile)

Thank you! It compiles and runs on the Arduino Mega. The screen however does not show characters properly and its all scrambled. I am not sure what is happening... :(
When using the arduino IDE everything works fine. Here is a zip with some screenshots. I would appreciate if you could perhaps have a look and see if i am missing something...
thanks again - phil (

Giampiero Campa

Giampiero Campa (view profile)

Phil, i think the variable "lcd" needs to be defined as a global. Try to define it in the libraries pane, after all the includes, see page 16 of the guide.


phil (view profile)

./io_wrappers.cpp: In function 'void Serial_read(int, int, uint8_t*, int*)':
./io_wrappers.cpp:40: warning: 'libFcnOutput' may be used uninitialized in this function
cc1plus.exe: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
./DDvers1_wrapper.cpp: In function 'void DDvers1_Outputs_wrapper(const boolean_T*, const real_T*, const real_T*, int_T)':
./DDvers1_wrapper.cpp:73: error: 'lcd' was not declared in this scope
./DDvers1_wrapper.cpp:77: error: 'lcd' was not declared in this scope
In file included from ./ert_main.c:18:
C:/MATLAB/Targets/R2012b/arduino-1.0/hardware/arduino/cores/arduino/Arduino.h:24:1: warning: "true" redefined
In file included from ./DisplayDriverv1.h:23,
from ./ert_main.c:17:
./rtwtypes.h:158:1: warning: this is the location of the previous definition
In file included from ./ert_main.c:18:
C:/MATLAB/Targets/R2012b/arduino-1.0/hardware/arduino/cores/arduino/Arduino.h:25:1: warning: "false" redefined
In file included from ./DisplayDriverv1.h:23,
from ./ert_main.c:17:
./rtwtypes.h:154:1: warning: this is the location of the previous definition

Roni Peer

Roni Peer (view profile)

Great walk through for newbies!


phil (view profile)

just what i was looking for!
it would be great if you guys could share your driver blocks!

i am currently writing one for an LCD display...quite a challenge.

Giampiero Campa

Giampiero Campa (view profile)

NOTE: If you are working with external libraries and you get an “undefined reference” error that means that your code references objects defined elsewhere (in other files) and, at linking time, the linker cannot find where they are.

In this case you need to make sure that all the .c and .cpp files of the library you are using are in the current MATLAB folder and that they are all included in the "Includes" field of the "Libraries" pane of the S-Function Builder (include the .c and .cpp files directly not the .h files).

Also, make sure that you read the last section (i.e. the last 2 pages) of the driver guide, entitled: "Working with external libraries".


Arkadi (view profile)

Great tutorial, Thank you.

This is exactly what I was searching for. A Step-by-Step guide to develop new and custom Simulink blocks for Arduino targets.

Thank you !

Tucker McClure

This is a good introduction to making all the device code I need inside blocks so that I can just drag and drop blocks and get all the processor-specific code. Say I need to add a new encoder. Copy and paste the block and change the pin numbers. Done. Thanks, Giampiero!


Updated license


Minor modification to documentation (e.g. updated copyrights).


Added System Object and Legacy Code Tool approach, examples, and documentation.


Documented masking S-Function Builder blocks and the MATLAB Function approach.

Also removed the motor shields -related files since updated versions can be found in the "motor shields" file exchange entry.


Included drivers for AF Motor Shield V2, and Embedded MATLAB-based examples.


Fixed small typos, updated copyright, and added troubleshooting section to the guide.


Fixed a few typos and added a troubleshoot page at the end of the guide.


The PDF document was slightly refined.

MATLAB Release
MATLAB 8.0 (R2012b)

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video