A MATLAB timer object will help. See, for example, this link Using MATLAB to process files in real-time after every instance a file is created by a separate program.
There may be some worry regarding the simultaneous write (your other process) and read (MATLAB) to a single file. Your situation may be more suited to a pipe rather than a file: Pipe vs. Temporary File but I will proceed with a MATLAB based solution for timed file reads and plot updates.
I emulated your situation and learned a few things:
- The MATLAB file handle stores the current position. However if the end of file flag is set for a file-id MATLAB will not look for new data when a subsequent call to
fread is made. See the work arounds using fseek in the readFile function below.
- 10 ms is optimistic. MATLAB doesn't miss points but each update typically adds four or more data points rather than just one.
- If the source of the data is using buffered file writes MATLAB won't see new data until the buffer is flushed to disk. The python code below was used to emulate the source of your data. The file was opened to write without buffering:
fobj = open('test.dat', 'wb', 0).
MATLAB code below:
function [t] = livePlot(period, filename)
//% inputs : period : update rate in seconds
//% filename : name of the file to get data from
//%
//% outputs: t : the timer object
//% >> stop(t)
//% ends streaming
//%%
close all;
t = timer('StartDelay', 1, 'Period', period, ...
'ExecutionMode', 'fixedRate');
//%% timer object callback functions
t.StopFcn = {@stopFigure};
t.TimerFcn = {@updateFigure};
//%% initialize timer object user data
d = get(t, 'UserData');
d.data = []; % array for the data to plot
axes('Position', [0 0 1 1], 'Visible', 'off');
d.axes_handle = axes('Position', [.2 .1 .7 .8]);
d.line_handle = plot(NaN,NaN);
d.fid = fopen(filename, 'r');
set(t, 'UserData', d);
start(t);
end
function stopFigure(obj, event)
//% close function handle
d = get(obj, 'UserData');
fclose(d.fid);
end
function updateFigure(obj, event)
d = get(obj, 'UserData');
//% read new data from file
tmp = readFile(obj);
//% append to array in user data
d.data = [d.data transpose(tmp)];
//% update the plot
set(gcf, 'CurrentAxes', d.axes_handle);
set(d.line_handle, 'XData', 1:length(d.data), 'YData', d.data);
//% store the timer object user-data
set(obj, 'UserData', d);
end
function [tmp] = readFile(obj)
//% read binary data. file-ID is in the timer user-data
d = get(obj, 'UserData');
tmp = fread(d.fid);
fprintf('Current file location : %d \n', ftell(d.fid));
//% fprintf('End of file indicator : %d \n', feof(d.fid));
//% reset the end-of-file indicator
fseek(d.fid, -1, 0);
fseek(d.fid, 1, 0);
//% fprintf('End of file indicator : %d \n', feof(d.fid));
set(obj, 'UserData', d);
end
Python code to write data to a file every ~ 10 milliseconds:
#!/anaconda/bin/python
import numpy as np
from time import sleep
sleep_time = 0.01
sigma = 5
fobj = open('test.dat', 'wb', 0)
for i in range(5000):
sleep(sleep_time)
x = int(np.random.normal(sigma))
fobj.write('%c' % x)
fobj.close()