iterate through multiple serial ports, one after another (not simultaneously)

5 次查看(过去 30 天)
I have a program that utilizes incoming serial data to do a strcmp with data stored in excel. the string initially comes in looking like this:
Reader(n): 'String'
my code is set up to find the n, and then compare the serial string to the string stored in the Nth column of an excel spreadsheet. A bool value of 1 from this operation will change the Nth panel in a GUI to green, while a bool value of 0 will change the Nth panel to red.
At the moment, my code only iterates from n = 1:2. these are the n values coming in from COM3. I want to use 3 more COM ports, each one carrying n = 3:4, n = 5:6, and n = 7:8. However, I am unsure of how to initialize the ports to be read one after another, no simultaneously. this is my main function:
delete(instrfind('Port', 'COM3')); % removes possibility for 'Port not available' error
tag = serial('COM3'); %initializes the port to be used
fopen(tag); %opens th eport
BOX = char(zeros(2,14)); % matrix to be populated with incoming serial data
TrueValueData = 'C:\RfidChipTrueValues.xlsx';
% location of stored master tags
[~,~,TrueValMat] = xlsread(TrueValueData); % reads our excel file into the proper format
% Creates matrix filled with the correct values
% indexed by box, which is the first row
% all proceeding rows are the master value
for i=1:inf
for n = 1:2
if i>10 % positive reading
readData = fscanf(tag);
if length(readData)>12
BOX(str2double(readData(8)),1:14)= readData(11:24);
if strcmp(TrueValMat{2,n}, BOX(n,:)) %cannot sub-index to CELL types normally, must use this method
set(handles.uipanels(n), 'BackgroundColor', 'g');
else
set(handles.uipanels(n), 'BackgroundColor', 'r');
end
drawnow % allows GUI to update the appearance whenever the loop completes.
if strcmp(TrueValMat{2,1}, BOX(1,:))...
&& strcmp(TrueValMat{2,2}, BOX(2,:)) == 1
set(handles.pushbutton5, 'enable', 'on');
end
end
end
end
end
the GUI at this point works well, with only minor things to be ironed out in the future. the colors change correctly, etc.
This is all for only a single com port. how do I make this work with 3 additional ports?
I know about bytesavailablefcn, but I have no clues how to use it, even after hours spent reading about it, watching videos, etc. obviously I am open to using anything that works, but it will have to really be explained to me.
Thanks so much

采纳的回答

Walter Roberson
Walter Roberson 2019-10-3
portlist = {'COM3', 'COM4', 'COM7', 'COM12'};
nport = length(portlist);
tags = cell{1, nport};
cleanups = cell{1, nport};
for portidx = 1 : nport
delete(instrfind('Port', portlist{portidx})); % removes possibility for 'Port not available' error
tags{portidx} = serial(portlist{portidx}); %initializes the port to be used
fopen(tag); %opens th eport
cleanups{portidx} = onCleanup(@() fclose(portlist{portidx}));
end
BOX = char(zeros(2,14)); % matrix to be populated with incoming serial data
TrueValueData = 'C:\RfidChipTrueValues.xlsx';
% location of stored master tags
[~,~,TrueValMat] = xlsread(TrueValueData); % reads our excel file into the proper format
% Creates matrix filled with the correct values
% indexed by box, which is the first row
% all proceeding rows are the master value
for i=1:inf
for portidx = 1 : nport
nbase = portidx * 2 - 1;
for n = nbase:nbase+1
if i>10 % positive reading
readData = fscanf(tags{portidx});;
if length(readData)>12
BOX(str2double(readData(8)),1:14)= readData(11:24);
if strcmp(TrueValMat{2,n}, BOX(n,:)) %cannot sub-index to CELL types normally, must use this method
set(handles.uipanels(n), 'BackgroundColor', 'g');
else
set(handles.uipanels(n), 'BackgroundColor', 'r');
end
drawnow % allows GUI to update the appearance whenever the loop completes.
if strcmp(TrueValMat{2,1}, BOX(1,:))...
&& strcmp(TrueValMat{2,2}, BOX(2,:)) == 1
set(handles.pushbutton5, 'enable', 'on');
end
end
end
end
end
end
If you want something different to be done for the different ports, then you can test the portidx value.
  8 个评论
Walter Roberson
Walter Roberson 2021-5-3
I do not explain code "line by line". When someone asks me to explain code "line by line", that means that I have to write a textbook on programming principles, and then a second textbook about programming in MATLAB, as I have to assume that everything about the code is unknown to them.
The first code loops through a fixed set of port names. It checks to see whether the port is already in use, and if so it tells MATLAB to get rid of the existing connection. Then it creates a serial port interface to the port. Finally, it creates an onCleanup object that closes the port when the cleanups variable is destroyed, such as if the user does a clear all or if the user returns from the function that opens the ports without saving the cleanup objects somewhere.
The second code loops forever reading from each port in turn. The first port uses n = 1:2, the second port uses n = 3:4, and so on. So port #K uses n = (2*K-1):(2*K)

请先登录,再进行评论。

更多回答(1 个)

avram alter
avram alter 2019-10-29
readers 1 and 2 (both on com3) work perfectly now. however, when a tag is held up to the third reader (on Com4), I get this error:
Index exceeds the number of array elements (2).
Error in WorkingGUI3>WorkingGUI3_OutputFcn (line 103)
set(handles.uipanels(n), 'BackgroundColor', 'r');
Error in gui_mainfcn (line 264)
feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
Error in WorkingGUI3 (line 42)
gui_mainfcn(gui_State, varargin{:});
this is the code I have now:
% --- Outputs from this function are returned to the command line.
function varargout = WorkingGUI3_OutputFcn(hObject, eventdata, handles)
% delete(instrfind('Port', 'COM3')); % removes possibility for 'Port not available' error
% tag = serial('COM3'); %initializes the port to be used
% fopen(tag); %opens th eport
portlist = {'COM3', 'COM4'};
nport = length(portlist);
tags = cell(1, nport);
cleanups = cell(1, nport);
for portidx = 1 : nport
delete(instrfind('Port', portlist{portidx})); % removes possibility for 'Port not available' error
tags{portidx} = serial(portlist{portidx}); %initializes the port to be used
fopen(tags{portidx}); %opens th eport
cleanups{portidx} = onCleanup(@() fclose(portlist{portidx}));
end
BOX = char(zeros(3,14)); % matrix to be populated with incoming serial data
TrueValueData = 'C:\Users\Administrator\Dropbox (esberlab)\esberlab Team Folder\Matlab\RFID chip reader\RfidChipData\RfidChipTrueValues.xlsx';
% location of stored master tags
[~,~,TrueValMat] = xlsread(TrueValueData); % reads our excel file into the proper format
% Creates matrix filled with the correct values
% indexed by box, which is the first row
% all proceeding rows are the master value
for i=1:inf
pause(0.01)
% for n = 1:2
for portidx = 1 : nport
nbase = portidx * 2 - 1;
for n = nbase:nbase+1
if i>10 % positive reading
% readData = fscanf(tag);
readData = fscanf(tags{portidx});
if length(readData)>12
BOX(str2double(readData(8)),1:14)= readData(11:24);
if strcmp(TrueValMat{2,n}, BOX(n,:)) %cannot sub-index to CELL types normally, must use this method
set(handles.uipanels(n), 'BackgroundColor', 'g');
else
set(handles.uipanels(n), 'BackgroundColor', 'r');
end
drawnow % allows GUI to update the appearance whenever the loop completes.
if strcmp(TrueValMat{2,1}, BOX(1,:))...
&& strcmp(TrueValMat{2,2}, BOX(2,:)) == 1
set(handles.pushbutton5, 'enable', 'on');
end
end
end
end
end
end
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
  5 个评论
Walter Roberson
Walter Roberson 2019-10-29
编辑:Walter Roberson 2019-10-29
Note that you do not need the "== 1" part.
if strcmp(TrueValMat{2,1}, BOX(1,:)) ...
&& strcmp(TrueValMat{2,2}, BOX(2,:)) ...
&& strcmp(TrueValMat{3,1}, BOX(3, :))
set(handles.pushbutton5, 'enable', 'on');
end

请先登录,再进行评论。

产品


版本

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by