Custom Arduino Servo Write block does not work unless built-in Arduino Servo Write block is in model

16 views (last 30 days)
I'm using Simulink Arduino Hardware Support Package to generate code on Arduino DUE and I created my own custom block (using Legacy Code Tool) to use Arduino API Servo.Write function - if you ask why, my goal is to use Servo.WriteMicroseconds but i wanted to start with something easy.
The problem is that despite writing the code correctly and model compiling without errors the custom Servo.Write block does not work at all. Intrestingly, if i place in my model built-in Arduino Support Package "Standard Servo Write" block (so there is custom and built-in at the same time) and then generate code (Build, Deploy & Start) suddenly my own custom block also starts to work!
When i compared code generated with my own block and the code generated when original Servo Write block is in model the practically look the same beside the obvious difference in step function.
But one thing I've noticed is that when model with my own block is compiling it throws out a warning in Diagnostics Viewer:
customservo_arduino.o: In function `customServoAttach':
customservo_arduino.cpp:(.text.customServoAttach+0x4): warning: undefined reference to `Servo::attach(int)'
customservo_arduino.o: In function `customServoWrite':
customservo_arduino.cpp:(.text.customServoWrite+0x2): warning: undefined reference to `Servo::write(int)'
customservo_arduino.o: In function `_GLOBAL__sub_I_myservo':
customservo_arduino.cpp:(.text.startup._GLOBAL__sub_I_myservo+0x2): warning: undefined reference to `Servo::Servo()'
So I believe that unless there is a built-in Arduino block inside the model something is being defined differently. To my surprise, I've looked at the original MW_ServoWriteRead.h/*.cpp source files and wrappers to Arduino code in there and I believe that I included all libraries that were included there so it should work.
Here are codes used to generate custom block
LCT script
def = legacy_code('initialize');
def.SFunctionName = 'customservo_sfun';
def.OutputFcnSpec = 'void NO_OP(uint8 p1, uint8 u1)';
def.StartFcnSpec = 'void NO_OP(uint8 p1)';
legacy_code('sfcn_cmex_generate', def);
legacy_code('compile', def, '-DNO_OP=//')
def.SourceFiles = {fullfile(pwd,'..','src','customservo_arduino.cpp')};
def.HeaderFiles = {'customservo_arduino.h'};
def.IncPaths = {fullfile(pwd,'..','src'), 'C:\ProgramData\MATLAB\SupportPackages\R2022a\aIDE\libraries\Servo\src'};
def.OutputFcnSpec = 'void customServoWrite(uint8 p1, uint8 u1)';
def.StartFcnSpec = 'void customServoAttach(uint8 p1)';
legacy_code('sfcn_cmex_generate', def);
legacy_code('sfcn_tlc_generate', def);
customservo_arduino.cpp file
#include <inttypes.h>
#include "Arduino.h"
#include "Servo.h"
#include "customservo_arduino.h"
Servo myservo;
// Digital I/O initialization
extern "C" void customServoAttach(uint8_T pin)
// Write a logic value to pin
extern "C" void customServoWrite(uint8_T pin, uint8_T val)
// [EOF]
customservo_arduino.h file
#include <inttypes.h>
#include <stdio.h>
#include "rtwtypes.h"
#ifdef __cplusplus
extern "C" {
void customServoAttach(uint8_T pin);
void customServoWrite(uint8_T pin, uint8_T val);
#ifdef __cplusplus

Answers (0)


Find more on Deployment, Integration, and Supported Hardware in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!