Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

How to execute two MATLAB scripts simultaneously

Asked by Sabrina Wendt on 26 Feb 2011
Latest activity Commented on by avinash pabbireddy on 21 Nov 2013

How do I execute two MATLAB scripts simultaneously? The one script is recording an EEG measurement while the other script is generating a visual stimuli on the screen. I hope that it is possible! And if it is, it would be nice with a code example.

The script for recording EEG is:

      fs= 256;
      measurement_time=10;
          %% Setting up the dataloggers  
  % Set up the communication with the dataloggers
  ai = analoginput('guadaq',1);
  Serial = ai.DeviceSerial;
addchannel(ai,[1]);
% Apply general filtering
set(ai.Channel(1),'BPIndex',45); % bandpassfilter the raw-input
set(ai.Channel(1),'NotchIndex',2); % notchfilter the raw-input
% specify samplefrequency and the total number of samples that should
% be obtained before stopping the datatransfer
set(ai,'SampleRate',fs,'SamplesPerTrigger',measurement_time*fs);
% Define the filename for logging the data to harddisk. LoggingMode is set to Disk in order
% to stream the data to the harddisk. Use Disk&Memory to stream the data to harddisk and to
% memory. LogToDiskMode is set to Overwrite to replace an existing file with the same
% name.
set(ai,'LogFileName','test','LoggingMode','Disk','LogToDiskMode','Overwrite');
start(ai)
while ai.SamplesAcquired< measurement_time*fs
end
data = getdata(ai);
plot(data), grid on
% Saving the data file
outputfile= 'measurement.mat';
save(outputfile, 'data');
delete(ai)
clear ai-----

The script for generating a visual stimuli is:

% ---------------------- Psychophysics Toolbox ---------------------------
% By using the Matlab toolbox - psychophysics - two flickering squares are
% implemented. The program uses the refresh rate of the screen in order to 
% generate flicker, by shifting a chosen area between the background color
% (black) and a set color - here white.
% Last edited 7th of February 2011
% ------------------------------------------------------------------------
screenNum=0;
flipSpd=0;                                  
[wPtr,rect]=Screen('OpenWindow',screenNum);             % wPtr - designate the window, rect - screen size
monitorFlipInterval=Screen('GetFlipInterval', wPtr);    % Refresh time [s]
frame_rate = 1/monitorFlipInterval;                     % Frame rate [Hz]
%% -----------------------------------------------------------------------
p=8;                                % Sets the frequency for left hand square 
P = frame_rate/(2*p);               % Frequency [Hz]
q=4;                                % Sets the frequency for right hand square
Q = frame_rate/(2*q);               % Frequency [Hz]
color_black = [255 255 255];        % Defining black color
color_white = [0 0 0];              % Defining white colot 
CenX = rect(3)/2;                   % Center of width
CenY = rect(4)/2;                   % Center of height
Dis = 200;                          % Distance between the two squares
SqS = 300;                          % Square size
pos1=[CenX-Dis/2-SqS CenY-SqS/2 CenX-Dis/2 CenY+SqS/2];     % Position of left hand square
pos2=[CenX+Dis/2 CenY-SqS/2 CenX+Dis/2+SqS CenY+SqS/2];     % Position of right hand square        
black=BlackIndex(wPtr);             % Find the color lookup table values (black)
white=WhiteIndex(wPtr);             % Find the color lookup table values (white)
%% -----------------------------------------------------------------------
Screen('FillRect',wPtr,black);      % Fills a rectangle the size of the screen to be black
Screen(wPtr, 'Flip');               % Flip the screen from offscreen to onscreen
HideCursor;
tic
while toc<1;
end
Screen('FillRect',wPtr,black);      % Blacks the screen
vbl=Screen(wPtr, 'Flip');           % Collect the time for the first flip with vbl
for i=1:300 % "time of run"
    % Generate the flickering squares
    if mod(i,p)==0
        Screen('FillRect',wPtr,color_black, pos1);
    else
        Screen('FillRect',wPtr,color_white, pos1);
    end
      if mod(i,q)==0
          Screen('FillRect',wPtr,color_black, pos2);
      else
          Screen('FillRect',wPtr,color_white, pos2);
      end
Screen(wPtr, 'Flip');
end
Screen('FillRect',wPtr,black);      % Blacks the screen
vbl=Screen(wPtr, 'Flip', vbl+(flipSpd*monitorFlipInterval));
tic
while toc<1;
end
tic
Screen('CloseAll');
ShowCursor-------

Can you tell if your code will work, Paulo?

3 Comments

Jiro Doke on 26 Feb 2011

Please format your question so that it's easier to read the code. Highlight your code and click on the "Code{}" icon.

Paulo Silva on 27 Feb 2011

I can't run your codes but I keep what I already said, put stimuli in one m file and the eeg recorder in another, make another m file with two timers (each ones callback runs one of the m files) and run that m file, the timers can be started at the same time (start function) and both m files will run simultaneously or almost simultaneous, just be careful not to overwrite the saved eeg data, make the recorded save the data with a new name each time it's finish his job (maybe using the clock function to build a unique name)

Paulo Silva on 27 Feb 2011

Also be very careful with the timer settings, it's possible to start several stimuli and record at the same time and maybe crash matlab, to test make them just start the job once and stop.

Sabrina Wendt

Products

No products are associated with this question.

4 Answers

Answer by Ian on 27 Feb 2011
Accepted answer

I am using matlab to control a neurophysiological data aquisition system (DAQ, plexon omniplex), and am also using the psychophysics toolbox (PTB) to generate stimuli, so basically doing what you need to do. You have the following problem much greater than simply running two scripts:

  1. Synchronisation: how will you know that your EEG timestamp is the same as the PTB's flip timestamp?
  2. Communication: do you need information past between display and DAQ matlab scripts at all?

My solutions are the following: I control the omniplex using my PTB code, it uses a LabJack to send out physical voltage pulses (immediately after Screen('flip') in the PTB code!) to control my electrophysiological data aquisition system. I've tested this by feeding these TTLs into my DAQ, and also recording a signal from a photodiode on the screen that displays output from the PTB to ensure they are synchronised together. Without this, you cannot know whether your stimulus and response really are properly aligned, and this will impact your interpretation of your results.

To see my data coming in online I have to use a different matlab script and I simply open another matlab instance. You can spawn secondary matlab sessions that run your script programatically from your first script (assuming you want to run a script called myScript.m), using:

Windows:

eval('!matlab -nodesktop -nosplash -r "myScript.m" &')

OS X:

eval('!osascript -e ''tell application "Terminal"'' -e ''activate'' -e ''do script "matlab -nodesktop -nosplash -maci -r \"myScript.m\""'' -e ''end tell''')

To communicate between these two matlab scripts I use UDP using pnet (it comes with PTB, also available on matlab file exchange) to allow both matlab scripts to talk to each other, pass variables and keep my data visualisation locked to what the stimulus was/is doing. You can for example use UDP packet after the Screen('flip') in PTB so your EEG system knows within a few milliseconds when your display changed if you don't know how to use a photodiode to check this.

Another solution, and one I thought was too limited for my needs but may work for you is the Parallel computing toolbox, see this interesting stack overflow question:

http://stackoverflow.com/questions/4410339/how-can-i-parallelize-input-and-display-in-matlab

4 Comments

Ian on 28 Feb 2011

OK, synchronisation would be critical if you were looking at VEP for specific stimulus classes, I agree extracting the fundamental frequency doesn't need clear synchronisation. Spawning another matlab is the most straightforward way to do this, and not needing them synchronised or communicate makes this easy.

As I mentioned to Rob, you may want to check if you skip frames; your display code just flips the stimulus on every other frame and if you start dropping frames then your frequency of stimulation will actually be changing, which will affect your measurement.

avinash pabbireddy on 21 Nov 2013

i'm trying to collect emg data from ni data acquisition board and i want to collect force data simultaneously from a serial port can i run these two programs simultaneously so that i can collect both the data for a specific time

tic clc; close all; clear all; delete(instrfindall); s = serial ( 'COM5', 'BaudRate', 115200); set(s, 'Timeout',60); s.InputBufferSize =37020; tic fopen(s); %for i=1:20 data=fread(s); ---------------------------------------------------------- s = daq.createSession('ni'); s.addAnalogInputChannel('cDAQ2Mod1', 0, 'Voltage'); s.addAnalogInputChannel('cDAQ2Mod1', 1, 'Voltage'); s.Rate = 2000 s.DurationInSeconds = 60; [data5,time] = s.startForeground; toc

Ian
Answer by Jan Simon on 27 Feb 2011

You cannot run two scripts simultaneously in Matlab. Although you can start different threads in e.g. C, there is no guarantee, that the threads are performed simultaneously, because the OS decides about the order of execution and distribution to the different cores. Either you have to use a real-time OS and e.g. C. Or you can start two Matlab instances to run the two programs. Then I assume you need a synchronization, e.g. a light-diode scanning the screen - this has the advantage, that even the delay between Matlab's figure update and the display on the screen is considered.

2 Comments

Paulo Silva on 27 Feb 2011

You are absolutely right, 1 vote for you and another for Ian.

Sabrina Wendt on 28 Feb 2011

Thanks for the illuminating but sad answer. It is not that important that the scripts are synchronized - the most important thing is that the EEG is sampled with a constant sampling frequency and that the stimuli is a constant flicker / constant frequency.

Jan Simon
Answer by Paulo Silva on 26 Feb 2011

I made this code yesterday, it displays the memory used by matlab in real time, it updates the plot every half second, in your case it might work with only a timer but you could add another timer with almost the same parameters except the callback function, for example t would record the EEG and t1 would generate the stimuli, in the callback functions you can just insert the m file name you already have for each job you want to perform.

Without knowing more about your scripts it's not easy to know if this approach would work.

function test
fig=figure;[user,sys] = memory;a=0;
set(fig,'CloseRequestFcn','delete(gcf);')
ax=axes;set(ax,'Ylimmode','manual');
h = plot(ax,NaN, NaN,'LineWidth',5);
set(ax,'Ylimmode','manual');
set(ax,'YLim',[0 sys.PhysicalMemory.Total/10^6])
ylabel('Memory used by matlab in Megabytes');
t = timer('TimerFcn',@readdata,...
    'Period', 0.5,'executionmode','fixedSpacing');start(t)
    function readdata(g1,gg1)
        if (~ishandle(fig)),stop(t),return,end
        m=memory;mem=m.MemUsedMATLAB;
       set(h,'XData', [get(h, 'XData'), a],...
            'YData', [get(h, 'YData'), mem/10^6]);
        xd=get(h,'XData');yd=get(h,'YData');a=a+1;
        if numel(xd)>=100
            set(h,'XData',[xd(80:100)]);set(h,'YData',[yd(80:100)]);
        end
    end
end

3 Comments

Sabrina Wendt on 26 Feb 2011

Hey Paulo
I have now added my two codes that I would like to have executed at the same time.
Hope you (or others) can help!
\Sabrina

Paulo Silva on 27 Feb 2011

function testt
%stop(timerfind) %stop all timers
%delete(timerfind) %delete all timers
StopAfter=2;
RunTimes=0;
t1 = timer('TimerFcn',@rec,...
'Period', 5,'executionmode','fixedDelay','StartDelay',10);
t2 = timer('TimerFcn',@stm,...
'Period', 5,'executionmode','fixedDelay','StartDelay',10);
start(timerfind);
function rec(g1,gg1)
disp('rec')
RunTimes=RunTimes+1;
if RunTimes>=StopAfter
stop(timerfind)
delete(timerfind)
disp('timers stopped')
end
end
function stm(g1,gg1)
disp('stm')
end
end

Paulo Silva on 27 Feb 2011

I finally found that Jan is right, if I put pause(1) in one of the functions the other will wait, that ain't good, I hope you can do the same like Ian did.
Sorry about the timers, I was sure that would work but it didn't.

Paulo Silva
Answer by Rob Purser on 28 Feb 2011

Hi,

The Data Acquisition Toolbox has the exact capability you want built in. There's a demo called "Using Callback Functions to Create Live Displays and Analysis" that is part of the product that teaches you how to do this.

Also, check out the "daqscope" demo that is part of the toolbox for a real world example of plotting the data as it arrives. It's more complex, but shows many of the techniques in a full application.

-Rob Purser

Manager of Test and Measurement

Mathworks

3 Comments

Sabrina Wendt on 28 Feb 2011

Hey Rob
Thanks for your answer! I found out today that I can open MATLAB two times and then run the two scripts using each MATLAB - it works! But surely it will be smarter to have it all running in one MATLAB :-)
\Sabrina

Ian on 28 Feb 2011

Rob, the problem is DAT doesn't guarantee it will not block matlab long enough that the psychophysics toolbox won't skip frames as I understand. Sabrina *needs* to guarantee she meets her timing deadlines which will be somewhere from 10-16ms, and in between that there will be little time to acquire and plot the data. If the display skips frames, her frequency of stimulation will change unreliably and she cannot safely perform a fourier analysis of the EEG signal.

Unless the DAT uses a parallel thread which guarantees non-blocking? When displaying data, you don't need millisecond precision, but when generating precise psychophysical stimuli, you do :)

Walter Roberson on 16 Jun 2011

Hmmm .. _possibly_ "Acquiring Data and Generating Signals at the Same Time" ?? http://www.mathworks.com/products/daq/demos.html

Rob Purser

Contact us