MATLAB Answers

unexpected MATLAB expression in app designer, using app designer in general

5 views (last 30 days)
I wrote a code that compares a code coming in from a serial reader to a known set of codes. This is the code:
delete(instrfind('Port', 'COM3'));
tag = serial('COM3'); %check which port is used
fopen(tag);
%readData = fscanf(tag); %initialize
%writeData = uint16(500); % 0x01F4
%fwrite(tag, writeData, 'uint16') %write data
BOX = char(zeros(2,14));
i=1;
c=0;
TrueValueData = 'C:\Location_of_known_codes.xlsx';
[~,~,TrueValMat] = xlsread(TrueValueData); % Creates matrix filled with the correct values,
% indexed by box, which is the first row
% all proceeding rows are the master values
for i=1:9223372036854775807
if i>10 %first couple reads are filled with unicode nonsense, this skips that stage
readData = fscanf(tag);
if length(readData)>12
BOX(str2num(readData(8)),1:14)= readData(11:24); % these numbers just give us what we want;
% tags come in initially with some gobbledy-gook
end
%
% if(length(readData)>10) %if chip has been read
%
% ReadChips
if strcmp(TrueValMat{2,1}, BOX(1,:))
disp('hurray1')%set(handles.uipanel3, 'Backgroundcolor', 'g');
else
disp('not hurray1') %set(handles.uipanel3, 'Backgroundcolor', 'r');
end
if strcmp(TrueValMat{2,2}, BOX(2,:))
disp('hurray2') %set(handles.uipanel2, 'Backgroundcolor', 'g');
else
disp('not hurray2') %set(handles.uipanel2, 'Backgroundcolor', 'r');
end
end
end
This code works as I want it to, much of the comments are leftovers from the code I initially found online. I want to turn this into a GUI, where instead of printing out 'hurray1' or 'not hurray1', it changes the color of a button in the GUI (as seen in the comments on line 31-41). Note that the above code does exactly what I want it to.
To this end, I used app designer, and played around until i came up with this code:
classdef GuiScanner_1 < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
GUITESTLabel matlab.ui.control.Label
READER1Button matlab.ui.control.StateButton
READER2Button matlab.ui.control.StateButton
end
delete(instrfindall);
clear
clc
tag = serial('COM3'); %check which port is used
fopen(tag);
%readData = fscanf(tag); %initialize
%writeData = uint16(500); % 0x01F4
%fwrite(tag, writeData, 'uint16') %write data
BOX = char(zeros(2,14));
i=1;
c=0;
TrueValueData = 'C:\Location_of_known_codes.xlsx';
[~,~,TrueValMat] = xlsread(TrueValueData); % Creates matrix filled with the correct values,
% indexed by box, which is the first row
% all proceeding rows are the master values
for i=1:9223372036854775807
if i>10 %first couple reads are filled with unicode nonsense, this skips that stage
readData = fscanf(tag);
if length(readData)>12
BOX(str2num(readData(8)),1:14)= readData(11:24); % these numbers just give us what we want;
% tags come in initially with some gobbledy-gook
end
methods (Access = private)
% Value changed function: READER1Button
function READER1ButtonValueChanged(app, event)
value = app.READER1Button.Value;
if strcmp(TrueValMat{2,1}, BOX(1,:))
app.READER1Button.BackgroundColor = [0 1 0];
else
app.READER1Button.BackgroundColor = [1 0 0];
end
end
% Value changed function: READER2Button
function READER2ButtonValueChanged(app, event)
value = app.READER2Button.Value;
if strcmp(TrueValMat{2,2}, BOX(2,:))
app.READER2Button.BackgroundColor = [0 1 0];
else
app.READER2Button.BackgroundColor = [1 0 0];
end
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure
app.UIFigure = uifigure;
app.UIFigure.Position = [100 100 640 480];
app.UIFigure.Name = 'UI Figure';
% Create GUITESTLabel
app.GUITESTLabel = uilabel(app.UIFigure);
app.GUITESTLabel.Position = [305 234 59 15];
app.GUITESTLabel.Text = 'GUI TEST';
% Create READER1Button
app.READER1Button = uibutton(app.UIFigure, 'state');
app.READER1Button.ValueChangedFcn = createCallbackFcn(app, @READER1ButtonValueChanged, true);
app.READER1Button.Text = 'READER 1';
app.READER1Button.BackgroundColor = [1 1 0];
app.READER1Button.Position = [285 439 100 22];
% Create READER2Button
app.READER2Button = uibutton(app.UIFigure, 'state');
app.READER2Button.ValueChangedFcn = createCallbackFcn(app, @READER2ButtonValueChanged, true);
app.READER2Button.Text = 'READER 2';
app.READER2Button.BackgroundColor = [1 1 0];
app.READER2Button.Position = [285 24 100 22];
end
end
methods (Access = public)
% Construct app
function app = GuiScanner_1
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
I have no idea if I even placed any of my code in the correct places at all. I keep getting an 'Unexpected MATLAB code' error on line 11, and I can't find what that means.
Another issue is that I want the color of the buttons to stay yellow, until something has actually been scanned, and not immediately turn red. I assume that would need a loop to keep the color yellow when BOX is still a matrix of only zeros. Again, I dont know whereor how to put that into th eGUI code.
Any help is much appreciated.

  0 Comments

Sign in to comment.

Accepted Answer

Steven Lord
Steven Lord on 10 Sep 2019
classdef GuiScanner_1 < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
GUITESTLabel matlab.ui.control.Label
READER1Button matlab.ui.control.StateButton
READER2Button matlab.ui.control.StateButton
end
delete(instrfindall);
clear
clc
The line of code where you delete the objects returned by instrfindall is not inside any method of the class GuiScanner_1. Rather than copying your code into the class definition file, I would create a button or something else that when activated you want to run your code, and write a callback for that component in your app to call the script you've written. Why make a copy of the script in your app, which could get out of sync with your original script file as you fix bugs or add new features to one but not the other?
By the way, I would eliminate these lines from your script.
delete(instrfindall);
clear
clc
clear eliminates all the variables in the workspace in which it's called. If this script gets called from a component's callback function that's more limited in scope, but you're still going to eliminate some of the useful variables the app passes into the callback by default. Usually it should be run interactively, at the MATLAB Command Prompt, when you've made a conscious decision that you want to clear the workspace.
clc is another tool with wide ranging effects. Again, I recommend using this interactively rather than in a script or function. Using it in an app (which a user likely would not expect to interact at all with the Command Window) is likely to lead to at least mild user confusion or annoyance.
delete(instrfindall) suggests to me that someone created an instrument object and forgot or chose not to delete that instrument object once they were finished. As this documentation page states "A good programming practice is to make sure that you leave your program environment in a clean state that does not interfere with any other program code." If what you're cleaning up is the object you created with:
tag = serial('COM3');
I would create an onCleanup to close and delete the serial object when the callback function that runs your script finishes its execution.

  3 Comments

Walter Roberson
Walter Roberson on 10 Sep 2019
Due to code crashes and quitting from debugging, it is not uncommon for there to be left-over instrument objects to be deleted. I would, however, not use instrfindall by itself: I would restrict the search to the particular kind of object you will be working with, so that you do not interfere with any other kind of object that might be in use in other parts of the code.
avram alter
avram alter on 10 Sep 2019
I have done what you said in regard to removing clear and clc. I dont know how to write a function that will clean up by closing and deleting the serial object.
I took into account what walter roberson said, and change delete(instrafindall) to delete(instrafind('Port', 'COM3'))
In regard to witing a component that will call to my script, I dont really know how to do that either. I know I am not giving you much to work with, but my knowledge is limited, and the answers I find on google are of little help.
I don't even know if I should be changing the color of buttons, versus some other ui component. I initially tried to use a panel, but the only callbacks available where to change the size, not the color.
I was thrown into this project with little knowledge of matlab. I have defintiely enjoyed the process, and matlab can be a lot of fun, but there are definite gaps in my knowledge that I don't really have the time to fill. I'm sure its a pain in the ass, but know that any help is really appreciated.
Walter Roberson
Walter Roberson on 10 Sep 2019
uipanel() can be used for both traditional figures and uifigure (App Designer).
If you are using a callback to change ui color in response to data coming over the serial port, then it would be the serial port callback that you would be using, not a callback for a ui control. So what you need is a handle to the ui object you are changing the color of, and you set its properties appropriately.
For uipanel you would set ForegroundColor property (or perhaps BackgroundColor)
For uibutton there is a BackgroundColor property, as is the case for uitextarea
For uiimage you would set the ImageSource property to an RGB array

Sign in to comment.

More Answers (0)

Sign in to answer this question.

Products


Release

R2017a