Simulink Raspberry Pi Driver Blocks

Following on from adding support to wiringPi for the MCP4725 DAC, I wanted to add driver blocks to Simulink such that one could use them to create graphical models for the Raspberry Pi that could interface with the real-world – a workable alternative to expensive real-time targets.

Using the S-Function Builder and some other user created blocks (which didn’t work – see below) as a basis, the process isn’t too difficult thanks to the generic function prototypes wiringPi uses. All the low-level stuff is done in the library as explained in my previous post, the S-Function just has to call mcp4725Setup() at first step, followed by analogWrite() at each proceeding step. See the screenshots below.

‘Build’ creates the target language compile (.tlc) and .c code for the blocks such that Simulink Embedded Coder can incorporate them into the generated code. The process of generating, deploying to the Raspberry Pi and compiling over SSH is all very slick! Slick until compilation stops due to undefined references. The undefineds are the standard wiringPi functions – the Simulink makefile does not include the wiringPi library by default, even though the MATLAB Raspbian image has wiringPi installed. The error occurs with the older example blocks too so it looks like something changed at some point down the line.

Remote Build Makefile Setup

After a long time digging around in the remote build templates I finally found an undocumented command to get it working: xmakefilesetup. Run this in the MATLAB command window with the Raspberry Pi model open. The settings should be as below. Navigate to Linker > Arguments and add ‘lwiringPi’ on the end (this tells the linker to use the wiringPi library and so the wiringPi functions will be linked). If you’re using my ADC/DAC blocks with ADS1115 and MCP4725, you’ll also have to update the wiringPi library with my library by logging on via SSH and following these steps.

Add '-lwiringPi' to the linker 'Arguments' command string.
Add ‘-lwiringPi’ to the linker ‘Arguments’ command string. This will affect upon all Linux remote build models.

I created a model with four driver blocks with example usage that can be copied and pasted into other models – remember to ‘Build’ the s-functions in the model directories and install my version of wiringPi. It can be downloaded below.

rpi-driver-blocks

cropped-JBRLogo.png

38 thoughts on “Simulink Raspberry Pi Driver Blocks”

  1. Thank you so much for this page ! I could build-up an s-function to communicate with a phidgetBridge with load cells.

  2. Hi John,

    I am doing some image processing work on raspberry pi using simulink and I would like to transmit it through bluetooth to another raspberry pi board. How can I access the Raspberry PI bluetooth port from simulink ?

    Regards

    Walid

  3. Hello,

    I try to compile S-Function for Raspbery Pi in Simulink. But when i press Build i have an error : No supportes compiler or SDK was found.

    Someone know a good C compiler for raspberry Pi or how to fix this error please ?

    Great job with this tuto 🙂

  4. Thanks for the post John! Linking wiringPi using xmakefilesetup solved the “undefined reference” errors I was facing.

    Cheers,
    Esther

  5. Hi everyone,

    I’m facing a problem : the command line xmakefilesetup give me an error !! (Matlab R2016a)

    Error using xmakefile.Setup
    The XMakefile feature has been removed. There is no known work-around.
    Error in xmakefilesetup (line 11)
    hObj = makefile.Setup;

    Have you an idea to link the wiringPi differently or how to solve the xmakefilesetup error ?

    Thank’s in advance for your help !!

    Sebastien

    1. It sounds like Mathworks have moved towards a more Makefile based toolchain setup: http://uk.mathworks.com/help/coder/examples/adding-a-custom-toolchain.html

      I imagine there is a Raspberry Pi toolchain that can be edited in the same way as the Intel x64 one above. I’m not using R2016 yet and don’t have the time to look into it at the moment. If you find something please share it.

      If you need to get going quickly, I can only advise you roll back to R2015. You can download older releases from Mathworks. I came across no other way to add the wiringPi lib to the cross-compiler.

  6. Dear Mr. John,

    I want to use your ADS1115ADC1-Block because I am using the MCP3008 to read AC signals, which I need for a standalone application. I think that all settings are done which are described here but I get an error message as seen below.

    Do you have any idea which settings are missing or set incorrectly?

    The call to realtime_make_rtw_hook, during the after_make hook generated the following error:
    Error executing SSH command: make: Entering directory ‘/home/pi/measDistanceSensor_rtt’
    “gcc” -I”./” -O3 -D”MODEL=measDistanceSensor” -D”NUMST=1″ -D”NCSTATES=0″ -D”HAVESTDIO=” -D”ON_TARGET_WAIT_FOR_START=1″ -D”ONESTEPFCN=0″ -D”EXT_MODE=1″ -D”TERMFCN=1″ -D”MAT_FILE=0″ -D”MULTI_INSTANCE_CODE=0″ -D”INTEGER_CODE=0″ -D”MT=0″ -D”CLASSIC_INTERFACE=0″ -D”ALLOCATIONFCN=0″ -D”TID01EQ=0″ -D”USE_TARGET_UDP=” -D”RUNONTARGETHARDWARE_BUILD=” -D”EXIT_FAILURE=1″ -D”EXTMODE_DISABLETESTING=” -c ./linuxUDP.c ./ext_svr.c ./ext_work.c ./rtiostream_interface.c ./updown.c ./rtiostream_tcpip.c ./rtiostream_utils.c ./ert_main.c ./measDistanceSensor.c ./measDistanceSensor_data.c ./sfcn_MCP3008_Out_wrapper.c
    “gcc” ./linuxUDP.o ./ext_svr.o ./ext_work.o ./rtiostream_interface.o ./updown.o ./rtiostream_tcpip.o ./rtiostream_utils.o ./ert_main.o ./measDistanceSensor.o ./measDistanceSensor_data.o ./sfcn_MCP3008_Out_wrapper.o -lm -ldl -lpthread -lrt -o ./MW/measDistanceSensor -lwiringPi
    ./sfcn_MCP3008_Out_wrapper.o: In function sfcn_MCP3008_Out_Update_wrapper':
    sfcn_MCP3008_Out_wrapper.c:(.text+0x64): undefined reference to
    ads1115Setup’
    collect2: ld returned 1 exit status
    _measDistanceSensor.mk:122: recipe for target ‘MW/measDistanceSensor’ failed
    make: *** [MW/measDistanceSensor] Error 1
    make: Leaving directory ‘/home/pi/measDistanceSensor_rtt’

    The build process will terminate as a result.

    Error executing SSH command: make: Entering directory ‘/home/pi/measDistanceSensor_rtt’
    “gcc” -I”./” -O3 -D”MODEL=measDistanceSensor” -D”NUMST=1″ -D”NCSTATES=0″ -D”HAVESTDIO=” -D”ON_TARGET_WAIT_FOR_START=1″ -D”ONESTEPFCN=0″ -D”EXT_MODE=1″ -D”TERMFCN=1″ -D”MAT_FILE=0″ -D”MULTI_INSTANCE_CODE=0″ -D”INTEGER_CODE=0″ -D”MT=0″ -D”CLASSIC_INTERFACE=0″ -D”ALLOCATIONFCN=0″ -D”TID01EQ=0″ -D”USE_TARGET_UDP=” -D”RUNONTARGETHARDWARE_BUILD=” -D”EXIT_FAILURE=1″ -D”EXTMODE_DISABLETESTING=” -c ./linuxUDP.c ./ext_svr.c ./ext_work.c ./rtiostream_interface.c ./updown.c ./rtiostream_tcpip.c ./rtiostream_utils.c ./ert_main.c ./measDistanceSensor.c ./measDistanceSensor_data.c ./sfcn_MCP3008_Out_wrapper.c
    “gcc” ./linuxUDP.o ./ext_svr.o ./ext_work.o ./rtiostream_interface.o ./updown.o ./rtiostream_tcpip.o ./rtiostream_utils.o ./ert_main.o ./measDistanceSensor.o ./measDistanceSensor_data.o ./sfcn_MCP3008_Out_wrapper.o -lm -ldl -lpthread -lrt -o ./MW/measDistanceSensor -lwiringPi
    ./sfcn_MCP3008_Out_wrapper.o: In function sfcn_MCP3008_Out_Update_wrapper':
    sfcn_MCP3008_Out_wrapper.c:(.text+0x64): undefined reference to
    ads1115Setup’
    collect2: ld returned 1 exit status
    _measDistanceSensor.mk:122: recipe for target ‘MW/measDistanceSensor’ failed
    make: *** [MW/measDistanceSensor] Error 1
    make: Leaving directory ‘/home/pi/measDistanceSensor_rtt’

    Sincerely,

    George

      1. I didn’t install your fork of the wiringPi library. Now, everything is operating correctly.
        Thank you for everything!

        LG

        George

      2. Hi Mr John, I follow the step to install the wiringPi on the Linux from Matlab but still fail. I would like to know to for the SD memory I should use the Noobs file from rasbian or the Boots file from the simulink support package.

  7. Hey guys,

    i need to build a simulink block for I2C connection with my rasperry (read at least). I have no clue how to realise that. Everything i tried failed. Does anyone have some advice or instructions to help me out?

    Thanks

  8. hello:
    I have a problem, when I use the Simulink to convert the square wave speed, the use of S-function, there will be the following error:
    “Block ‘test4/change/S-Function’ is a non-inlined s-function, which is not supported with the current configuration. Consider selecting the support ‘non-inlined s-functions’ option on the Configuration Parameters > Code Generation > Interface pane”
    In accordance with the instructions after the choice is still the same mistake, it is not clear why?
    I hope you can help look, thank you very much.

  9. Do you have any idea which settings are missing or set incorrectly?

    STDERR: sfcn_DAC_Out_wrapper.c.o: In function sfcn_DAC_Out_Outputs_wrapper':
    sfcn_DAC_Out_wrapper.c:(.text+0x50): undefined reference to
    analogWrite’
    sfcn_DAC_Out_wrapper.c.o: In function sfcn_DAC_Out_Update_wrapper':
    sfcn_DAC_Out_wrapper.c:(.text+0xa4): undefined reference to
    mcp4725Setup’
    collect2: error: ld returned 1 exit status
    make: *** [../rp3.elf] Error 1

    Thank’s in advance for your help !!

        1. Compiling with R2015a R2015b on Win7 did not suffer these errors.
          I have this errors only with R2016a.
          Where to begin with troubleshooting? Any suggestions \ questions to diagnose root-cause are appreciated.

          1. Ah ok. The issue is 2016a as a commenter above explains. xmakefile.setup has been removed, this is the error in 2016a (I have not seen it myself as I am not using RPi blocks at the moment:

            “Error using xmakefile.Setup
            The XMakefile feature has been removed. There is no known work-around.”

            The error is fairly verbose! “There is no known work-around”. If you find one, please update this so others can see, otherwise just roll back to 2015.

                1. Ok thanks. Are you able to expand on that for others to see? What command do you use rather than xmakefilesetup (where the -lwiringPi used to go)?

  10. Hi, when I build the model I get the following error:

    C:\Users\Ilaria\Documents\MATLAB\sfcn_MCP3008_Out_wrapper.c(17) : fatal error C1083: Cannot open include file: ‘wiringPi.h’: No such file or directory
    NMAKE : fatal error U1077: ‘”C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\Bin\amd64\cl.EXE”‘ : return code ‘0x2’
    Stop.

    C:\Users\Ilaria\Documents\MATLAB\ADC_grt_rtw>echo The make command returned an error of 2
    The make command returned an error of 2

    C:\Users\Ilaria\Documents\MATLAB\ADC_grt_rtw>An_error_occurred_during_the_call_to_make
    ‘An_error_occurred_during_the_call_to_make’ is not recognized as an internal or external command,
    operable program or batch file.

    Does anyone know where is the file ‘wiringPi.h’ missing from?

    1. Hello, I’m not sure where and what I am supposed to install on the Windows side.
      I get this error now, which looks like the compiler misbehaving.
      Any one got a clue?

      Creating standalone executable “..\ADC.exe” …

      sfcn_MCP3008_Out_wrapper.obj : error LNK2019: unresolved external symbol analogRead referenced in function sfcn_MCP3008_Out_Outputs_wrapper
      sfcn_MCP3008_Out_wrapper.obj : error LNK2019: unresolved external symbol ads1115Setup referenced in function sfcn_MCP3008_Out_Update_wrapper
      sfcn_MCP3008_Out_wrapper.obj : error LNK2019: unresolved external symbol wiringPiSetup referenced in function sfcn_MCP3008_Out_Update_wrapper
      ..\ADC.exe : fatal error LNK1120: 3 unresolved externals
      NMAKE : fatal error U1077: ‘”C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\Bin\amd64\link.EXE”‘ : return code ‘0x460’
      Stop.

      C:\Users\Ilaria\Documents\MATLAB\ADC_grt_rtw>echo The make command returned an error of 2
      The make command returned an error of 2

      C:\Users\Ilaria\Documents\MATLAB\ADC_grt_rtw>An_error_occurred_during_the_call_to_make
      ‘An_error_occurred_during_the_call_to_make’ is not recognized as an internal or external command,
      operable program or batch file.

  11. Hi Ilaria,

    The compilation errors are because you are compiling on the host computer (the one you are working on) rather than the Raspberry Pi. You should be set in ‘External’ mode and configured to use a Raspberry Pi as the remote target.

    I recommend you read and attempt the Mathworks’ examples, get that working first, then do the same process with these blocks: https://uk.mathworks.com/help/supportpkg/raspberrypi/examples/getting-started-with-raspberry-pi-hardware.html

    John.

    1. Hi John,

      thanks for your help. My model is running now, however still not showing the correct voltage value on the scope.
      I’m using a MCP3008 to convert a variable voltage produced by a 10 kOhm potentiometer connected to CH0, as described on the following Matlab tutorial:

      https://uk.mathworks.com/help/supportpkg/raspberrypiio/examples/analog-input-using-spi.html

      I am expecting to get a voltage in the range 0 – 3.3V on the scope, but instead I get a value of -1.

      Any idea why this is happening?

      Ilaria

      1. -1 generally means the chip is not reading correctly. Perhaps it is not connected properly or SPI is not enabled? I would follow the steps from within the MATLAB environment and if that doesn’t work, attempting to manually use it from within Raspbian.

        1. Thanks, I was about to delete my previous comment as I actually managed to solve the problem, by replacing ads1115Setup(100,0) with mcp3004Setup(100,0) in the sfcn_MPC3008_Out_wrapper.c. The waveform I get on the scope seems reasonable, however the output needs to be attenuated by a factor of 300.

  12. Hello Guys,
    I am working in a project with a Raspberry Pi and an autopilot Pixhawk. With Simulink, I developed an algorithm to deploy on Raspberry Pi, but I need to send the results of this algorithm to Pixhawk via Serial Communication, however there is no block of serial communication in Simulink.
    My question is: in order to follow the steps presented here to create a Serial Communication Block to Raspberry Pi in Simulink, do I need to use Linux on my computer? Because, as far as I noticed, the wiringPi library is compatible with Linux only.
    Thanks in advance.

    1. WiringPi is a library for accessing the hardware level IO of the Raspberry Pi; running it on another Linux host won’t work. You don’t need a Linux host to cross-compile for the Raspberry Pi and create a driver block – this example was done on Windows. Have a read on ‘cross-compiling’. The Raspberry Pi package actually works by copying the code and compiling on the Pi itself however.

      The good news is that there is a Serial Driver block developed by Mathworks now: http://uk.mathworks.com/help/supportpkg/raspberrypi/ref/serialwrite.html . You will need 2017a to use it.

  13. Dear respected sir, Hope you are in good health with success and happiness.

    I’m trying to make a heart bit/pulse monitoring system using Raspberry pi. I’m using Heart Rate Pulse Sensor Pulsesensor Sensor which gives analog value as output. But you know raspberry pi is not able to read analog value.

    Therefore I’m trying to convert analog value to digital as input for Rasperry pi.
    I’m using MATLAB to code Raspberry pi.

    Please could you help me about how to convert Analog data to digital data sothat it can be feed into Raspery pi?

    Please sir, Help me. I’m waiting for response……..

Leave a Reply