MATLAB Answers

Khafka
0

Realtime Plotting of RS232 Data Help

Asked by Khafka
on 30 Mar 2011
Hi there all,
I'm trying to plot ultrasound data in realtime in Matlab which is being sent to the computer via RS232. The below code works in batches - i.e. I can click run and Matlab will plot the 6 data points correctly...
but... I can not get it work in real time. The graph needs to update automatically, can anyone please help?
function [back,bottom,front,left,right,top]= ReadUltrasoundOld
%-------------------------------------------------------------------------------
% This module strips the US data from the RS232 link of it's commas
% and puts it in a usable format for real time graphing.
%-------------------------------------------------------------------------------
back = zeros(0,1); %For US data on the X Axis
bottom = zeros(0,1); %For US data on the Y Axis
front = zeros(0,1); %For US data on the Z Axis
left = zeros(0,1); %For US data on the X Axis
right = zeros(0,1); %For US data on the Y Axis
top = zeros(0,1); %For US data on the Z Axis
%--------------------------------------------------------------------------
%Set up the serial port with the settings used by the NIOS and wireless link.
s=serial('COM1');
set(s,'BaudRate',19200);
set(s,'DataBits',8);
set(s,'Parity','none');
set(s,'StopBits',1);
set(s,'flowcontrol','hardware');
set(s,'Timeout',1000);
%Async means that re read the port continusaly.
s.ReadAsyncMode = 'continuous';
%Set the Terminator to be a Carriage Return this can be changed as requred
%but CR is a simple end char.
set(s,'Terminator','CR');
s.BytesAvailableFcnMode = 'terminator';
%On receiving data on the port send the code to the function.
s.BytesAvailableFcn = @IncomingData;
%Open the Serial Port
fopen(s);
%--------------------------------------------------------------------------
%Send Request Data
while isempty(top)
fprintf(s,'u');
pause(0.5);
end
%--------------------------------------------------------------------------
%Strip recieved data into usable format
function IncomingData(obj,~)
%Read in the line
data = fgetl(obj);
%We get the data as one long line of data in the form
%back,bottom,front,left,right,top
%Split it using strtok about a comma ','
%Deal with the back data
[back,data] = strtok(data,',');
back = str2double(back);
back = [back];
back = 0-back;
%Deal with the bottom data
[bottom,data] = strtok(data,',');
bottom = str2double(bottom);
bottom = [bottom];
bottom = 0-bottom;
%Deal with the front data
[front,data] = strtok(data,',');
front = str2double(front);
front = [front];
%Deal with the left data
[left,data] = strtok(data,',');
left = str2double(left);
left = [left];
left = 0-left;
%Deal with the right data
[right,data] = strtok(data,',');
right = str2double(right);
right = [right];
%Deal with the top data
[top,data] = strtok(data,',');
top = str2double(top);
top = [top];
%Send a blank to stop the transmission
fprintf(s,'0');
%flush the input buffer so we do not over load it
flushinput(obj);
end
%--------------------------------------------------------------------------
%Now close the serial port.
fclose(s);
delete(s);
%--------------------------------------------------------------------------
%Stripped data assigned to x,y,z coordinates
back
bottom
front
left
right
top
front = [ 0 front 0 ];
back = [ 0 back 0 ];
top = [ 0 0 top ];
bottom = [ 0 0 bottom ];
right = [ right 0 0 ];
left = [ left 0 0 ];
origin = [ 0 0 0 ];
%--------------------------------------------------------------------------
%Figure Handle
figureHandle = figure('NumberTitle', 'off',... %removes figurenumbers
'Name','Big Bertha Realtime Force Field Display',... %adds a title
'Color',[0 0 0]);
%Axis Handle
axesHandle = axes('Parent',figureHandle,...
'YGrid','on',...
'YColor',[0.9725 0.9725 0.9725],...
'XGrid','on',...
'XColor',[0.9725 0.9725 0.9725],...
'ZGrid','on',...
'ZColor',[0.9725 0.9725 0.9725],...
'Color',[0.6 0.6 0.6]);
hold on;
%x,y,z,title Labels
xlabel({'X axis';'left right'},'Color',[1 1 0]);
ylabel({'Y axis';'top bottom'},'Color',[1 1 0]);
zlabel({'Z axis';'front back'},'Color',[1 1 0]);
title('Ultrasound Data','Color',[1 1 0]);
%x,y,z limits
xlim(axesHandle,[min(-255) max(255)]);
ylim(axesHandle,[min(-255) max(255)]);
zlim(axesHandle,[min(-255) max(255)]);
%Graph Plotted
plotHandle = plot3(right,top,front,'o','MarkerSize',10);
hold on;
plotHandle = plot3(back,bottom,left,'o','MarkerSize',10);
hold on;
plotHandle = plot3(origin,'X','MarkerSize',5);
hold on;
set(plotHandle,'back',back,'bottom',bottom,'front',front,'left',left,'right',right,'top',top);
%--------------------------------------------------------------------------
%Serial Port closed
fclose(serialObject);
delete(serialObject);
clear serialObject;
end

  0 Comments

Sign in to comment.

4 Answers

Answer by Ankit Desai on 31 Mar 2011

Hi,
You might want to look at the examples available on MATLAB Central File Exchange:
You might have to combine these two scripts and modify those to fit your needs.
Hope this helps.
-Ankit

  1 Comment

Thanks for the fast reply Ankit.
I have been using that second example that you linked in my code above but I'm struggling with a couple of things:
1. My while loop only requests the data when the top matrixes are empty, so I changed this to "while 1" to request data indefinately. This however crashes matlab.
Found a possible solution to this by having our FPGA send the data without the need for a request to be sent. Not ideal but it should work for now.
2. I'm a bit confused as to how the "set (H, 'function name', value...) command works. In both the examples provided the function name is "Ydata" or "Xdata". Can I use the set command in the way I have above? i.e.
(plotHandle,'back',back,'bottom',bottom,'front',front,'left',left,'right',right,'top',top);
Or will that not work?
Thanks.

Sign in to comment.


Answer by Walter Roberson
on 1 Apr 2011

set() is not using function names: set() is using property names, with the valid properties determined by the class of the handle or object being work on.
It appears that you might perhaps wish to set up XDataSource and so on, and use refreshdata().
Be aware that each plot3() call may return a vector of plot handles that reflect only the lines that that particular call added. When you use "hold on", the next plot3() call does not return the vector of all existing lines, just the ones added in that next call. Your code overwrites plothandle twice, so you are losing track of the earlier handles.
If plot3 does return a vector of handles, then XDataSource and so on will not work for that situation. It appears to me, though, that your code probably would not trigger returning multiple handles per call.

  0 Comments

Sign in to comment.


Answer by Khafka
on 4 Apr 2011

Managed to get the code working with a number of changes and simulation of the incoming data via generation of random numbers between 0 and 255. The code below works as intended but I want to add a few subplots to the figure. Could anyone show me where I can add the subplot command to my code without it breaking please?
%--------------------------------------------------------------------------
%Figure Handle
figureHandle = figure('NumberTitle', 'off',... %removes figurenumbers
'Name','Big Bertha Realtime Force Field Display',... %adds a title
'Color',[0 0 0]);
%--------------------------------------------------------------------------
%Axis Handle
axesHandle = axes('Parent',figureHandle,...
'YGrid','on',...
'YColor',[0.9725 0.9725 0.9725],...
'XGrid','on',...
'XColor',[0.9725 0.9725 0.9725],...
'ZGrid','on',...
'ZColor',[0.9725 0.9725 0.9725],...
'Color',[0.6 0.6 0.6]);
hold on;
%--------------------------------------------------------------------------
%Plot line initialised
Ultrasound = plot(nan,'o','MarkerSize',10);
%--------------------------------------------------------------------------
%Origin plotted - NOW REDUNDANT
plot ([0],[0], 'x');
%--------------------------------------------------------------------------
%Bertha Plotted
%[x,y,z] = ellipsoid(xc,yc,zc,xr,yr,zr,n) where...
%center (xc,yc,zc) and semi-axis lengths (xr,yr,zr)
[x, y, z] = ellipsoid(0,0,0,96,48,48,30);
surfl(x, y, z)
colormap bone
axis equal
daspect([1 1 1])
%--------------------------------------------------------------------------
%Arrays created
back = zeros(0,1); %For US data on the X Axis
bottom = zeros(0,1); %For US data on the Y Axis
front = zeros(0,1); %For US data on the Z Axis
left = zeros(0,1); %For US data on the X Axis
right = zeros(0,1); %For US data on the Y Axis
top = zeros(0,1); %For US data on the Z Axis
%--------------------------------------------------------------------------
%x,y,z limits
xlim([min(-255) max(255)]);
ylim([min(-255) max(255)]);
zlim([min(-255) max(255)]);
%--------------------------------------------------------------------------
%x,y,z,title Labels
xlabel({'X axis';'front back'},'Color',[1 1 0]);
ylabel({'Y axis';'left right'},'Color',[1 1 0]);
zlabel({'Z axis';'top bottom'},'Color',[1 1 0]);
title('Ultrasound Data','Color',[1 1 0]);
%--------------------------------------------------------------------------
%Indefinate loop...
while 1
back = randi([-255, 0],[1,1]); %For US data on the X Axis
bottom = randi([-255, 0],[1,1]); %For US data on the Y Axis
front = randi([0, 255],[1,1]); %For US data on the Z Axis
left = randi([-255, 0],[1,1]); %For US data on the X Axis
right = randi([0, 255],[1,1]); %For US data on the Y Axis
top = randi([0, 255],[1,1]); %For US data on the Z Axis
set(Ultrasound,...
'YData',[back,0,0,front,0,0],...%# Update the y data of the line
'Xdata',[0,left,0,0,right,0],...%# Update the x data of the line
'ZData',[0,0,top,0,0,bottom]); %# Update the z data of the line
drawnow
pause(0.1);
end

  0 Comments

Sign in to comment.


Answer by Khafka
on 5 Apr 2011

Nevermind :) I found how to subplot. Now I just need to figure out how to lay the subplots out how I want. If anyone wants to run this code themselves and let me know how I can improve it, please let me know.
clear all
clc
%--------------------------------------------------------------------------
%Figure Handle
figureHandle = figure('NumberTitle', 'off',... %removes figurenumbers
'Name','Big Bertha Realtime Force Field Display',... %adds a title
'Color',[0 0 0]);
%--------------------------------------------------------------------------
%Axis Handle
UltrasoundA = subplot(2,4,1);
set(UltrasoundA, 'YGrid','on');
set(UltrasoundA, 'YColor',[0.9725 0.9725 0.9725]);
set(UltrasoundA, 'XGrid','on');
set(UltrasoundA, 'XColor',[0.9725 0.9725 0.9725]);
set(UltrasoundA, 'ZGrid','on');
set(UltrasoundA, 'ZColor',[0.9725 0.9725 0.9725]);
set(UltrasoundA, 'Color',[0.6 0.6 0.6]);
hold on;
%--------------------------------------------------------------------------
%Plot line initialised
UltrasoundD = plot(nan,'o','MarkerSize',10);
%--------------------------------------------------------------------------
%Bertha Plotted
%[x,y,z] = ellipsoid(xc,yc,zc,xr,yr,zr,n) where...
%center (xc,yc,zc) and semi-axis lengths (xr,yr,zr)
[x, y, z] = ellipsoid(0,0,0,96,48,48,30);
surfl(x, y, z)
colormap bone
axis equal
daspect([1 1 1])
%--------------------------------------------------------------------------
%Arrays created
back = zeros(0,1); %For US data on the X Axis
bottom = zeros(0,1); %For US data on the Y Axis
front = zeros(0,1); %For US data on the Z Axis
left = zeros(0,1); %For US data on the X Axis
right = zeros(0,1); %For US data on the Y Axis
top = zeros(0,1); %For US data on the Z Axis
%--------------------------------------------------------------------------
%x,y,z limits
xlim([min(-255) max(255)]);
ylim([min(-255) max(255)]);
zlim([min(-255) max(255)]);
%--------------------------------------------------------------------------
%x,y,z,title Labels
xlabel({'X axis';'front back'},'Color',[1 1 0]);
ylabel({'Y axis';'left right'},'Color',[1 1 0]);
zlabel({'Z axis';'top bottom'},'Color',[1 1 0]);
title('Ultrasound Data','Color',[1 1 0]);
%--------------------------------------------------------------------------
%Front Data subplot
FrontA = subplot(2,4,2);
set(FrontA, 'YGrid','on');
set(FrontA, 'YColor',[0.9725 0.9725 0.9725]);
set(FrontA, 'XGrid','on');
set(FrontA, 'XColor',[0.9725 0.9725 0.9725]);
set(FrontA, 'Color',[0.6 0.6 0.6]);
hold on;
FrontD = plot(nan,'-o','MarkerSize',10);
ylim([min(0) max(255)]);
xlabel({'Time (secs)'},'Color',[1 1 0]);
ylabel({'Distance (inches)'},'Color',[1 1 0]);
title('Front Sensor','Color',[1 1 0]);
%--------------------------------------------------------------------------
%Back Data subplot
BackA = subplot(2,4,3);
set(BackA, 'YGrid','on');
set(BackA, 'YColor',[0.9725 0.9725 0.9725]);
set(BackA, 'XGrid','on');
set(BackA, 'XColor',[0.9725 0.9725 0.9725]);
set(BackA, 'Color',[0.6 0.6 0.6]);
hold on;
BackD = plot(nan,'-or','MarkerSize',10);
ylim([min(-255) max(0)]);
xlabel({'Time (secs)'},'Color',[1 1 0]);
ylabel({'Distance (inches)'},'Color',[1 1 0]);
title('Back Sensor','Color',[1 1 0]);
%--------------------------------------------------------------------------
%Left Data subplot
LeftA = subplot(2,4,4);
set(LeftA, 'YGrid','on');
set(LeftA, 'YColor',[0.9725 0.9725 0.9725]);
set(LeftA, 'XGrid','on');
set(LeftA, 'XColor',[0.9725 0.9725 0.9725]);
set(LeftA, 'Color',[0.6 0.6 0.6]);
hold on;
leftD = plot(nan,'-og','MarkerSize',10);
ylim([min(-255) max(0)]);
xlabel({'Time (secs)'},'Color',[1 1 0]);
ylabel({'Distance (inches)'},'Color',[1 1 0]);
title('Left Sensor','Color',[1 1 0]);
%--------------------------------------------------------------------------
%Indefinate loop...
n= 50;
time=zeros(1,n);
frontH=zeros(1,n);
backH=zeros(1,n);
leftH=zeros(1,n);
count=1;
while 1
back = randi([-255, 0],[1,1]); %For US data on the X Axis
bottom = randi([-255, 0],[1,1]); %For US data on the Y Axis
front = randi([0, 255],[1,1]); %For US data on the Z Axis
left = randi([-255, 0],[1,1]); %For US data on the X Axis
right = randi([0, 255],[1,1]); %For US data on the Y Axis
top = randi([0, 255],[1,1]); %For US data on the Z Axis
time(1:n)=[time(2:n), datenum(clock)];
%--------------------------------------------------------------------------
%Update main 3Dplot
set(UltrasoundD,...
'YData',[back,0,0,front,0,0],...%# Update the y data of the line
'Xdata',[0,left,0,0,right,0],...%# Update the x data of the line
'ZData',[0,0,top,0,0,bottom]); %# Update the z data of the line
drawnow
%--------------------------------------------------------------------------
%Update Front subplot
datetick(FrontA,'x','ss');
frontH(1:n) = [frontH(2:n), front];
set(FrontD,'YData',frontH,'XData',time);%# Update the y data of the line
drawnow
%--------------------------------------------------------------------------
%Update Back subplot
datetick(BackA,'x','ss');
backH(1:n) = [backH(2:n), back];
set(BackD,'YData',backH,'XData',time);%# Update the y data of the line
drawnow
%--------------------------------------------------------------------------
%Update Left subplot
datetick(LeftA,'x','ss');
leftH(1:n) = [leftH(2:n), left];
set(leftD,'YData',leftH,'XData',time);%# Update the y data of the line
drawnow
%--------------------------------------------------------------------------
%Pause,increase count
pause(0.1);
count=count+1;
end

  0 Comments

Sign in to comment.