[MATLAB] Real Time Serial Data Logger

Data acquisition is a very important part of test engineering. By plotting the data acquired in real time, we can analyze how the design behave and to determine whether it meet specs or not. Some examples of application are logging aircraft altitude and LiPo battery cells temperature. In my previous project of designing an aircraft altitude controller, the real  time data logger is a key part of the project in determining how the system perform. In that project, I used Java to program a real time data plotter and it was such a pain. The code became so messy that I do not want to look at it ever again. It took such a long time too.

So this time, I turned to MATLAB. As a 4th generation programming language, this is so much easier since it got a Serial interface and plotting function built in. In the end of this post, we should get sometime like this:

Serial Data Log

In order develop the Data Logger, we first need to generate a signal. In this case, we will write a simple sketch in Arduino to print out values of a sine function.

// Serial Signal Generator
// Yu Hin Hau
// 7/9/2013
// CLOSE PLOT TO END SESSION

double x;

void setup() {

 Serial.begin(9600);
 x = 0;
}

void loop() {

Serial.flush();
 Serial.println(sin(x));
 x += .05;

 if(x >= 2*3.14)
 x = 0;

 //Allow Time to Process Serial Communication
 delay(50);
}

Okay, so our signal source is taken care of, we need to now develop the data logger. In MATLAB, there are several functions that are related to Serial communication.

First, we need to target a Serial COM Port. Replace [b]’COM5′[/b] with whatever port your device, Arduino in this case, is connected to. You can figure this out by going to the [b]”Device and Printer”[/b] tab in the Windows start menu. After opening the port, MATLAB should spit out a bunch of data regarding the port.

 s = serial('COM5') 

Next, we need to open the Serial port.

 fopen(s); 

Then, to read from it and store to var data, we do the following. The [b]’%f'[/b] tell MATLAB to store the data as a floating point value. If we don’t denote that, MATLAB will automatically assume it is a char.

 data = fscanf(s, '%f'); 

After finishing with the Serial COM port, it is very important remember to close it. Else other applications cannot access it.

 fclose(s); 

Using the basics of Serial Communication in MATLAB above, we can develop a real time data logger / plotter by storing the data into an array, then updating the plot every time MATLAB read from the Serial port. In the end we get the following code. It is by no mean perfect, but it should be good enough for most purpose. You can modify the [b]User Defined Properties[b] section to get most of what you need from the script. Try changing the [b]scrollWidth[/b] to 0, it will plot the entire log history instead of just a section. Make sure the delay isn’t too long, or else you might have a problem of sampling only certain points of the signal. Remember to end the program by closing the plot itself. If not, the port will not be closed and you will have to restart MATLAB to run it again. After you close the plot, you can still access the data log by accessing the data variable in the workspace.

Enjoy and create something awesome! 😀

% Serial Data Logger
% Yu Hin Hau
% 7/9/2013
% **CLOSE PLOT TO END SESSION

clear
clc

%User Defined Properties 
serialPort = 'COM5';            % define COM port #
plotTitle = 'Serial Data Log';  % plot title
xLabel = 'Elapsed Time (s)';    % x-axis label
yLabel = 'Data';                % y-axis label
plotGrid = 'on';                % 'off' to turn off grid
min = -1.5;                     % set y-min
max = 1.5;                      % set y-max
scrollWidth = 10;               % display period in plot, plot entire data log if <= 0
delay = .01;                    % make sure sample faster than resolution

%Define Function Variables
time = 0;
data = 0;
count = 0;

%Set up Plot
plotGraph = plot(time,data,'-mo',...
                'LineWidth',1,...
                'MarkerEdgeColor','k',...
                'MarkerFaceColor',[.49 1 .63],...
                'MarkerSize',2);
            
title(plotTitle,'FontSize',25);
xlabel(xLabel,'FontSize',15);
ylabel(yLabel,'FontSize',15);
axis([0 10 min max]);
grid(plotGrid);

%Open Serial COM Port
s = serial(serialPort)
disp('Close Plot to End Session');
fopen(s);

tic

while ishandle(plotGraph) %Loop when Plot is Active
    
    dat = fscanf(s,'%f'); %Read Data from Serial as Float
 
    if(~isempty(dat) && isfloat(dat)) %Make sure Data Type is Correct        
        count = count + 1;    
        time(count) = toc;    %Extract Elapsed Time
        data(count) = dat(1); %Extract 1st Data Element         
        
        %Set Axis according to Scroll Width
        if(scrollWidth > 0)
        set(plotGraph,'XData',time(time > time(count)-scrollWidth),'YData',data(time > time(count)-scrollWidth));
        axis([time(count)-scrollWidth time(count) min max]);
        else
        set(plotGraph,'XData',time,'YData',data);
        axis([0 time(count) min max]);
        end
        
        %Allow MATLAB to Update Plot
        pause(delay);
    end
end

%Close Serial COM Port and Delete useless Variables
fclose(s);
clear count dat delay max min plotGraph plotGrid plotTitle s ...
        scrollWidth serialPort xLabel yLabel;


disp('Session Terminated...');


13 thoughts on “[MATLAB] Real Time Serial Data Logger

  1. Thank You very much!! you save my life!!! i was need that code!! i implemented in a GUIDE & it work really great!! =)

    • hi, I haven’t really try that in Matlab (moved on to python for my projects), but basically, you read the serial and extract the two data variable according to whatever delimiter you used (space, comma…). After that, probably add a “hold on” command and then duplicate the plot() command with different parameters using the 2nd variable as your data. And of course do the update phase like the first.

  2. Pingback: Plotting Realtime Yaw, Pitch, Roll (#YPR) data from Razor IMU 9dof with Matlab | Enhancing knowledge in control systems theories and its applications in the real world.

  3. Hi, what changes should I make to plot two signals instead of one signal?
    I did the following changes, but it is still not working:
    * Modification 1: Changed ” data = 0; ” to ” data = zeros(2,1); ” so that I set an array of two to hold both ADC signals
    * Modification 2: Changed ” dat = fscanf(s,’%f’); ” to ” dat = fscanf(s,’%f,%f’); ” to receive both signals
    * Modification 3: Changed ” data(count) = dat(1); ” to ” data(count,:) = dat’; ”

    Your help would be much appreciated.

  4. Hi,I haven’t really try that in Matlab , you read the serial and extract the 3 data variable according to whatever delimiter you used (space, comma…). After that, probably add a “hold on” command and then duplicate the plot() command with different parameters using the 3nd variable as your data. And of course do the update phase like the first

    code:

    clear all;
    close all;
    clc;
    %User Defined Properties
    serialPort = ‘COM3’; % define COM port #
    plotTitle = ‘Serial Data Log’; % plot title
    xLabel = ‘Elapsed Time (s)’; % x-axis label
    yLabel = ‘Acceleration’; % y-axis label
    plotGrid = ‘on’; % ‘off’ to turn off grid
    min = -1; % set y-min
    max = 4; % set y-max
    scrollWidth = 10; % display period in plot, plot entire data log if 0)
    set(plotGraph,’XData’,time(time > time(count)-scrollWidth),…
    ‘YData’, data(3,time > time(count)-scrollWidth));
    set(plotGraph1,’XData’,time(time > time(count)-scrollWidth),…
    ‘YData’, data(2,time > time(count)-scrollWidth));
    set(plotGraph2,’XData’,time(time > time(count)-scrollWidth),…
    ‘YData’, data(1,time > time(count)-scrollWidth));

    axis([time(count)-scrollWidth time(count) min max]);
    else
    set(plotGraph,’XData’,time,’YData’,data(3,:));
    set(plotGraph1,’XData’,time,’YData’,data(2,:));
    set(plotGraph2,’XData’,time,’YData’,data(1,:));

    axis([0 time(count) min max]);
    end

    %Allow MATLAB to Update Plot
    pause(delay);
    end
    end

    %Close Serial COM Port and Delete useless Variables
    fclose(s);

    clear count dat delay max min plotGraph plotGraph1 plotGraph2 plotGrid…
    plotTitle s scrollWidth serialPort xLabel yLabel;

    disp(‘Session Terminated’);

    prompt = ‘Export Data? [Y/N]: ‘;
    str = input(prompt,’s’);
    if str == ‘Y’ || strcmp(str, ‘ Y’) || str == ‘y’ || strcmp(str, ‘ y’)
    %export data
    csvwrite(‘accelData.txt’,data);
    type accelData.txt;
    else
    end

    clear str prompt;

  5. please provide a matlab code for this problem

    I am confused how to plot a data acquired from the hardware to Matlab.

    I have built a hardware which has 5 sensors interfaced in it. the output of 5 sensors are transmitted serially to the port COM3.

    For example: My hardware shows output like this in port *COM3👇🏻
    SENSOR 1: 50
    SENSOR 2: 250
    SENSOR 3: 500
    SENSOR 4: 450
    SENSOR 5: 550

    This was output of my hardware. Now how to get that output to be plotted in matlab in real time that is my confussion.

    if anyone knows how to solve this , please let me know.

  6. Hii.. First of all thanks a lot for this code.
    I want to show these plots in MATLAB GUI. can you please send code for plotting real time data from arduino in matlab gui.

  7. Pingback: Matlab serial read bug | ASK Dev Archives

  8. Hello friend . Forst of all thank you very much for sharing this knowledge with us all . I am completely unaware of MATLAB software and would like to know whether I’ll be able to store the graph or not as I need to store the graph.
    THANK YOU

Leave a comment