Interfacing the Arduino with Matlab Using Events
12th February 2010
Opening a basic serial connection to the Arduino in Matlab is not difficult and is documented. Data is sent to the device using the fprintf() function and received using fscanf().
s = serial('COM3', 'BaudRate', 9600);
fopen(s);
fprintf(s, 'Hello World!');
line = fscanf(s);
fclose(s);
If we have data continually being sent by our device there are two ways of capturing it. We can create a loop within Matlab to constantly check if any data has been received however this doesn’t seem like brilliant coding practise. Alternatively we can make use of the Matlab’s BytesAvailable event and read the input buffer only when data is received.
Unfortunately, unlike languages like C++, Matlab is only able to pass variables by value and not by reference. So if we create an array in our workspace to hold the received data, our callback function will be unable to update it. However in Matlab it is possible to nest functions within the body of another. The variables defined in the outer function will be accessible to the inner function.
% Calling the function myFunc will display the number 10.
% Demonstrates that nested function has access to variables.
function myFunc
myVar = 10;
innerFunc()
function innerFunc
myVar
end
end
The code to establish a serial connection is written into a Matlab function which also contain an array of all received data. The callback function of the BytesAvailable event is defined as a nested function and hence can add to the data array when new data is received. This allows us to perform analysis on the data in parallel to it being read.
The full sourcecode of my function is shown below:
%
% SerialArduino
%
% Makes a serial connection via COM3 to the Arduino. Uses the
% BytesAvailableFcn event to trigger a function to record data sent by
% device. The recorded value and time are stored in the vectors values
% and times respectively.
%
% Inputs: Time (in seconds) to listen to device.
% Outputs: Times and Values
%
% Tested in Matlab 2009b
%
% Written 12 February 2010
% by Leo Kent
%
% http://leo.me.uk/
%
function [times values] = SerialArduino (time)
% Declare the vectors to hold time and value data.
times = zeros(0,1);
values = zeros(0,1);
% Setup serial connection.
ser = serial('COM3', 'BaudRate', 9600);
% Attach the callback function.
ser.BytesAvailableFcnMode = 'terminator';
ser.BytesAvailableFcn = @Callback;
% Open the connection.
fopen(ser);
% Record the time at which we open the connection.
start_time = tic;
% This is the callback function for when bytes are availble.
% It adds the received value to the values array and gets time.
function Callback(obj, event)
% Get the new values.
v = str2double(fscanf(obj));
t = toc(start_time);
% Update the vectors.
values = [values; v];
times = [times; t];
end
% Wait 5 seconds and close connection.
time = 5;
pause(time);
% Close the serial port connection.
fclose(ser);
% Plot the output.
plot(times, values);
end
13th December 2010 at 11:21 pm
??? Input argument “time” is undefined.
Error in ==> SerialArduino at 53
pause(time);
i have error like this, can you help me?
14th December 2010 at 10:47 am
`time` should be a defined variable. Change this to 5 and it should work. [Will update post].
14th December 2010 at 11:21 am
Ok, thank’s. i try it again and success
14th December 2010 at 11:28 am
i have src like this :
sensor_src = ‘/dev/rfcomm26′;
baud_rate = 19200;
% set up sensor
%==============================================
system(sprintf(‘stty -F %s %d raw’, sensor_src, baud_rate));
system(sprintf(‘stty -F %s’, sensor_src));
pause(2);
% open sensor
sensor = fopen(sensor_src, ‘r’);
% sensor is now active
ACTIVE_SENSOR = 1;
i just want ask, how to make it compatible with windows?. im using COM3 and BaudRate 9600.
any Suggestion Sir?
28th February 2011 at 3:58 am
if i write a code in matlab that has input from say gps and a function that tests data and if it does not meet parameters then another function calculates corrections. how do I output only the corrections to the arduino board or software that uses only the matrix to get the board to create its output based on the matrix received?