Matlab writeDigitalPin() speed (slow)

Hello!
I am writing a program in Matlab for my Arduino Due and I have come across a problem with speed of this command: writeDigitalPin()
I made a test of speed in Arduino IDE:

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
 unsigned long start = micros();
// Call to your function
digitalWrite(10,HIGH);
digitalWrite(10,LOW);

// Compute the time it took
unsigned long kon = micros();
unsigned long delta = kon - start;
Serial.println(delta);
}

It is 4 micro seconds

I made a test of speed in Matlab:

delete(instrfindall)
a=arduino('com4', 'due', 'Libraries', 'SPI');
for b=1:1000
tic
writeDigitalPin(a,'D10',1)
writeDigitalPin(a,'D10',0)
toc
end

It is around 0,20s which is 200000micro seconds. I think this is far too much, do you have any solutions?
Thank you in advance.
Nejc

I think this is far too much

Do you have any idea HOW MatLab communicates to the Arduino that it should make the pin HIGH or LOW? If you did, you realize why the process takes far longer.

It's not unlike how long it takes you to eat a bowl of ice cream versus how long it takes to explain to someone else how to eat a bowl of ice cream.

It is around 0,20s which is 200 micro seconds

Nope.

Ups, my mistake. Do any of you know what's the difference, because other commands run a lot faster.
And I couldn't find how matlab communicates with Arduino, but I guess it loads the sketch on arduino.
Thank you for answer.

And I couldn't find how matlab communicates with Arduino

What code is on the Arduino?

Matlab sends a string to the serial port, along the lines of "Hey, Arduino, would you be so kind as to turn pin n on". Well, maybe no quite so wordy, but it is text, and the Arduino has to read and store all the serial data (which is slow to arrive) and then, when the end of packet marker arrives, parse the text to determine what to do. Then, it needs to do it.

The slow serial data transmission speed, the need to parse the data, and the need to convert strings that represent numbers (pin numbers, pin states, etc.), plus the need to make sure that the pin is indeed the right kind of pin (INPUT vs. OUTPUT; analog vs. digital; PWM vs. Servo vs. other) all take time.

Thank you for your answer.
I did some research and I managed to improve speed of this command for around 7 times, so it is quite faster.
Go to source code of function arduino() in Matlab (arduino.m)
Find fuction writeDigitalPin:

function writeDigitalPin(obj, pin, value)
            %   Write digital pin value to Arduino hardware.
            %
            %   Syntax:
            %   writeDigitalPin(a,pin,value)
            %
            %   Description:
            %   Writes specified value to the specified pin on the Arduino hardware.
            %
            %   Example:
            %       a = arduino();
            %       writeDigitalPin(a,'D13',1);
            %
            %   Input Arguments:
            %   a     - Arduino hardware
            %   pin   - Digital pin number on the Arduino hardware (string)
            %   value - Digital value (0, 1) or (true, false) to write to the specified pin (double).
            %
            %   See also readDigitalPin, writePWMVoltage, writePWMDutyCycle
            
            try
                
                if (nargin < 3)
                    obj.localizedError('MATLAB:minrhs');
                end
                
                pin = arduinoio.internal.validateInputPin(pin, arduinoio.internal.SubsystemEnum.Digital);
               
                configurePinResource(obj, pin, obj.ResourceOwner, 'DigitalOutput', false);
                
                value = arduinoio.internal.validateDigitalParameter(value);
                
                if pin(1) == 'A'
                    pin = getPinAlias(obj, pin);
                end
                
                writeDigitalPin(obj.Protocol, pin, value);
               
            catch e
                throwAsCaller(e);
            end
        end

all you have to do now is comment this line:

configurePinResource(obj, pin, obj.ResourceOwner, 'DigitalOutput', false);

so it looks like that:

function writeDigitalPin(obj, pin, value)
            %   Write digital pin value to Arduino hardware.
            %
            %   Syntax:
            %   writeDigitalPin(a,pin,value)
            %
            %   Description:
            %   Writes specified value to the specified pin on the Arduino hardware.
            %
            %   Example:
            %       a = arduino();
            %       writeDigitalPin(a,'D13',1);
            %
            %   Input Arguments:
            %   a     - Arduino hardware
            %   pin   - Digital pin number on the Arduino hardware (string)
            %   value - Digital value (0, 1) or (true, false) to write to the specified pin (double).
            %
            %   See also readDigitalPin, writePWMVoltage, writePWMDutyCycle
            
            try
                
                if (nargin < 3)
                    obj.localizedError('MATLAB:minrhs');
                end
                
                pin = arduinoio.internal.validateInputPin(pin, arduinoio.internal.SubsystemEnum.Digital);
               
%                 configurePinResource(obj, pin, obj.ResourceOwner, 'DigitalOutput', false);
                
                value = arduinoio.internal.validateDigitalParameter(value);
                
                if pin(1) == 'A'
                    pin = getPinAlias(obj, pin);
                end
                
                writeDigitalPin(obj.Protocol, pin, value);
               
            catch e
                throwAsCaller(e);
            end
        end

Than you have to declare every pin that you want as digital output with this command:

configurePin(a,pin,'DigitalOutput');

With that you can declare only once and when code runs, it won't be slow :slight_smile:

1 Like

yeeeey, thank you! :slight_smile:

Hello, I saw this post recently and I was wondering if anyone could point me in the direction of being able to do this with MATLAB 2019a or newer. I'm trying to interface with a stepper motor controller but the digital write pulses are too long.