1

Im new to matlab coding so im still trying to get my head around things. Pretty much im working with interia sensors which output the sensors orientation data every 10ms. Im able to store this data into a text file which is continuously updating.

My task now is to plot this data in real time. This involves continuously accessing and reading from the text file (every 10ms if possible) and graph this data with respect to time. Can any of you guys give me some guidance onto what would be the most effective way to do this.

At this moment in time, the text file only stores data about one parameter (the x coordinate of the sensor). I can store this data in 2 way: Method 1: New data every 10ms. Each is stored in a new line. Method 2: I can make the text file only have the most recent piece of data (erasing previous data) Im able to use either of these methods.. whatever you guys think would be easier.

Ive tried using other 3rd party software to graph this data from the text file, but they all seemed really jumpy and couldnt read from the text file fast enough.

Thanks.

2 Answers 2

2

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()
Sign up to request clarification or add additional context in comments.

6 Comments

sorry for the late reply. With the python code above, does it: Open the text file, continuously write data every 10ms then close the file. Or does it open the file>write data>close file and repeat every 10ms. Because i was under the impression it would have to use the 2nd method as i thought the file will not update until it has been closed. (thus matlab will be unable to access the new data until the file has been closed) Also thanks for answer, it has been really helpful
Also another problem i have encountered with this solution, it seems to be able to access the data in real time although it is not plotting the results correctly. The entire plot window seems to be randomly drawing lines from 9 to 56->57 on the y axis. The text file generated has the format, for example: 70 75 78 82 77 76 etc.. (Where each number is on a new line) so a single column text file. But as explained about, it doesnt seem to be plotting these values with respect to time. Any help would be greatly helpful. Thanks.
The python data generation code implements the first of your two possible approaches. The python code is opened so that there is no buffering before writing to disk (The '0' third argument to 'open').
With regards to your second comment: Are you mixing binary reading and text files? The MATLAB command fread that I used above reads binary data from a file. This file should not be human readable using a text editor. If you want MATLAB to read text files replace fread with fscanf.
Sweet. Thanks, all working now If i were output 2 sets of values to the textfile now, how would i plot this. Will i still use fscanf, or will i need to use another read in function which can perhaps store data into an array. fscanf doesnt seem to be able to distinguish the difference between each column of data. At the moment im using "tmp = fscanf(d.fid, '%f', inf);" but this just reads in data from start of file to end of file without considering txt file format. At the moment im saving the 2 sets of data into different txt files & reading them in separately. But this doesnt seem effective.
|
0

You can't plot using hard real time conditions, thus it can always happen that matlab misses a 10ms timeslot. You have to use option 2 to get all data.

To get started: Write a function which only reads the new data which was written since last call. To achieve this, do not close the file handle. It stores the position.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.