1 year ago
#332607
Multiplexer
Simulink Legacy Code Tool - custom Arduino servo write block problem
I'm trying to create my own servo.write block in Simulink for Arduino DUE deployment (and External Mode). Before you ask why if there is one available inside the Simulink Arduino Support Package, generally my final goal is to create a block that will use Arduino servo.writeMicroseconds function (there is no out of the box block for this one) but first i want to try with something simple to debug to see if i can get it to work....
I've been using this guide (https://www.mathworks.com/matlabcentral/fileexchange/39354-device-drivers) and one of working examples in there as a template and started modifying it (originally it implemented Digital Output driver). I took the LCT approach.
The the original digitalio_arduino.cpp/h files from the guide (example with digital read/out) were the files I modified as they were working without any issues out-of-the-box. Step by step i made following modifications:
Remove DIO read (leave only write) from CPP and H files
Change StartFcnSpec to digitalIOSetup and make changes in H file so port is always in OUTPUT mode
Include Servo.h library within CPP file and create Servo object
Up to this point, all edits went fine, no compile errors, all header files were detected by Simulink and diode kept blinking as it should so the code actually worked (i ran it in External Mode).
But as soon as i made the final modification and replaced pinMode() with myservo.attach() and digitalWrite() with myservo.write() (of course i changed the data type in writeDigitalPin function from boolean to uint8_T) the code, despite compiling and building without any issue didn't work at all. Specified servo port was completely dead, as it even wasn't initialised. Changing value on S-Function input didn't yield any results.
Of course If i replaced custom block with built in Servo Write block from Hardware Support Package, everything worked fine so its not hardware issue.
I'm completely out of ideas what could be wrong, especially that there are no errors so not even a hint where to look.
Here is the LCT *.m script used for generating S-Function:
def = legacy_code('initialize');
def.SFunctionName = 'dout_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','digitalio_arduino.cpp')};
def.HeaderFiles = {'digitalio_arduino.h'};
def.IncPaths = {fullfile(pwd,'..','src'), 'C:\ProgramData\MATLAB\SupportPackages\R2021b\aIDE\libraries\Servo\src'};
def.OutputFcnSpec = 'void writeDigitalPin(uint8 p1, uint8 u1)';
def.StartFcnSpec = 'void digitalIOSetup(uint8 p1)';
legacy_code('sfcn_cmex_generate', def);
legacy_code('sfcn_tlc_generate', def);
legacy_code('rtwmakecfg_generate',def);
legacy_code('slblock_generate',def);
Here is digitalio_arduino.CPP file
#include <Arduino.h>
#include <Servo.h>
#include "digitalio_arduino.h"
Servo myservo;
// Digital I/O initialization
extern "C" void digitalIOSetup(uint8_T pin)
{
//pinMode(pin, OUTPUT);
myservo.attach(pin);
}
// Write a logic value to pin
extern "C" void writeDigitalPin(uint8_T pin, uint8_T val)
{
//digitalWrite(pin, val);
myservo.write(val);
}
// [EOF]
And here is digitalio_arduino.H file
#ifndef _DIGITALIO_ARDUINO_H_
#define _DIGITALIO_ARDUINO_H_
#include "rtwtypes.h"
#ifdef __cplusplus
extern "C" {
#endif
void digitalIOSetup(uint8_T pin);
void writeDigitalPin(uint8_T pin, uint8_T val);
#ifdef __cplusplus
}
#endif
#endif //_DIGITALIO_ARDUINO_H_
As I mentioned I've been using a working example as a reference. So I've modified it step by step to see if maybe there is a point when suddenly some error comes up but everything compiles yet does not work :/
I was wondering maybe if there is an issue with the Servo.h library or the Servo object and did some tinkering with these, like i removed Servo myservo;
line of code to see if anything happens and just like expected, i started receiving errors that Servo is not defined. If I did not include Servo.h at all or forget to add IncPath to Servo.h as before compile errors about Servo not being supported symbol or not being able to find Servo.h library - so actually the code seems to be "working" in a way, it seems to have everything it needs to work :/
I also looked at the MathWorks implementation of Servo Write block, the MWServoReadWrite to see how Arduino API is being used and no surprise, it's being used in the same way as I've been trying to. They include Servo.h, they are using servo.attach() and servo.write() to control the servo port. And that's it. Yet for them it works, for me does not :/
When I inspect generated C code that runs on Arduino (with my custom S-Function block in it), it seems that all the functions are placed exactly where they are supposed to be, they receive correct arguments. I expected at least that I'll find a hint in there, i.e. missing code or anything else.
matlab
arduino
simulink
legacy-code
s-function
0 Answers
Your Answer