Code of Matlab APP

We modified a code of a colorspectroscopy which was programmed in an UPC TFG in order to measure absorbance and not transmitance. 
classdef APP_Spectrophotometer2 < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
SpectrumviewerUIFigure matlab.ui.Figure
FileMenu matlab.ui.container.Menu
OpenMenu matlab.ui.container.Menu
SaveMenu matlab.ui.container.Menu
SaveAsMenu matlab.ui.container.Menu
ExitMenu matlab.ui.container.Menu
HelpMenu matlab.ui.container.Menu
IcantdeleteasamplefromthetableMenu matlab.ui.container.Menu
IhaveremovedasampleandinexcelitisstillthereMenu matlab.ui.container.Menu
ImusinganewArduinoanditdoesntworkMenu matlab.ui.container.Menu
ThekeyboardshortcutsdontworkMenu matlab.ui.container.Menu
GridLayout matlab.ui.container.GridLayout
LeftPanel matlab.ui.container.Panel
SerialPortConnectionPanel matlab.ui.container.Panel
SerialPortDropDown matlab.ui.control.DropDown
SerialPortDropDownLabel matlab.ui.control.Label
DisconnectButton matlab.ui.control.Button
ConnectButton matlab.ui.control.Button
SpectrumtablePanel matlab.ui.container.Panel
UITable matlab.ui.control.Table
StatusPanel matlab.ui.container.Panel
TextArea matlab.ui.control.TextArea
TextAreaLabel matlab.ui.control.Label
SelectaspectrumtorepresentLabel matlab.ui.control.Label
LogoTelecos matlab.ui.control.Image
LogoUPC matlab.ui.control.Image
SpectrumdescriptionPanel matlab.ui.container.Panel
ADDButton matlab.ui.control.Button
DELETEButton matlab.ui.control.Button
NameEditField matlab.ui.control.EditField
NameEditFieldLabel matlab.ui.control.Label
RightPanel matlab.ui.container.Panel
SensorcontrolPanel matlab.ui.container.Panel
GreenButton matlab.ui.control.Button
BlueButton matlab.ui.control.Button
IntegrationblocksEditField matlab.ui.control.NumericEditField
IntegrationblocksEditFieldLabel matlab.ui.control.Label
StopButton matlab.ui.control.StateButton
CheckBox matlab.ui.control.CheckBox
tempsEditField matlab.ui.control.NumericEditField
tempsEditFieldLabel matlab.ui.control.Label
NmostresEditField matlab.ui.control.NumericEditField
NmostresEditFieldLabel matlab.ui.control.Label
Maximumwavelength matlab.ui.control.DropDown
MaxwavelengthnmLabel matlab.ui.control.Label
Minimumwavelength matlab.ui.control.DropDown
MinwavelengthnmLabel matlab.ui.control.Label
RedButton matlab.ui.control.Button
MeasureButton matlab.ui.control.Button
WhiteButton matlab.ui.control.Button
BlackButton matlab.ui.control.Button
Panel matlab.ui.container.Panel
SPECTROPHOTOMETERLabel matlab.ui.control.Label
UIAxes matlab.ui.control.UIAxes
end
% Properties that correspond to apps with auto-reflow
properties (Access = private)
onePanelWidth = 576;
end
 
properties (Access = private)
%ardu; % Struc de l’Arduino
selectedfile; % Direcció + nom de l’excel
sheets; % Noms de les pàgines de l’excel
matrixSpectrum = []; % Els espectres (matriu numèrica, nmxN)
matrixTransmittance = []; % Les transmitàncies obtingudes a partir de l’espectre i el blanc (matriu numèrica, nmxN)
table = {}; % Matriu de cel·les que guarda de info de la taula
black = []; % Mesura del offset/negre
white = []; % Mesura de la situació inicial/blanc
newSpectrum = []; % El nou/últim espectre obtingut
newResult = []; % La nova/última transmitàcia obtinguda
axisNM = []; % Les longituds d’ona totals que mesurem
nameListSelected; % Conté l’últim nom que s’ha seleccionat a la taula
indexCelSelected; % Conté l’última posició de la cel·la que s’ha seleccionat a la taula
toSaveFile; % Conté les dades que es guarden a l’excel (s’actualitza quan polsem Save o SaveAs)
numPlots; % Número de gràfiques que s’estàn mostrant
lenPlot = {}; % Cel·la que conté els noms que es mostren a la llegenda
minX; % Mínima longitud d’ona que es representa
maxX; % Màxima longitud d’ona que es representa
control; % Indica si s’ha polsat la tecla «control» (true or false)
device; %Dispositiu el qual esta connectat al Serial Port
contador=0;
 
m; % Vegades que s’ha polsat el botó mesurar
end
 
% table{_,_} -> Ja s’introdueix com a cel·la
% table(_,_) -> S’ha d’introduïr com a cel·la
% table = {} -> Esborra tota la taula (0x0)
% table(3,:) = [] -> Esborra la fila 3 de la taula (N-1,M)
 
methods (Access = private)
 
function cellMatrix = matrix2cell_1x1(~,matrix)
[row,col] = size(matrix);
cellMatrix = {}; % Esborrem el resultat anterior
cellMatrix{row,col} = []; % Per evitar que vagi creixent a mesura que avança el codi
for i = 1:row
for j = 1:col
cellMatrix{i,j} = matrix(i,j);
end
end
end
 
function setWavelengthItems(app) % També definim 2 coses per la gràfica
app.axisNM = linspace(323.991,1220.745,256);
xlim(app.UIAxes, [300 1300]); % Els min i màx que mostra la gràfica a l’inici, després pot variar
 
[~,col] = size(app.axisNM);
items{col} = []; % Per evitar que vagi creixent a mesura que avança el codi
for i = 1:col
items{i} = char(string(app.axisNM(i))); % Si no utilitzem string, la transformació és fa en codi ASCII
end
app.Minimumwavelength.Items = items;
app.Minimumwavelength.Value = items(1);
app.minX = str2double(items(1));
app.Maximumwavelength.Items = items;
app.Maximumwavelength.Value = items(col);
app.maxX = str2double(items(col));
end
 
 
function refreshplot(app)
app.lenPlot = {};
ii = 1;
for i = 1:size(app.matrixTransmittance,1)
if isequal(app.table{i,1},1) % Està seleccionada per representarnsmittance
plot(app.UIAxes,app.axisNM,app.matrixTransmittance(i,:));
app.lenPlot{ii} = char(app.table{i,2});
ii = ii + 1;
hold(app.UIAxes,’on’);
end
end
if isequal(ii,1) % Si no hi ha res a representar
plot(app.UIAxes, nan);
legend(app.UIAxes,’off’);
else
drawnow;
legend(app.UIAxes, app.lenPlot,’Box’,»on»);
hold(app.UIAxes,’off’);
end
end
 
 
function saveToExcel(app)
saved = 0;
try
% Construim el fitxer tal i com el volem guardar a l’excel
app.toSaveFile = [app.table(:,2) matrix2cell_1x1(app,app.matrixTransmittance)]’;
 
% Afegim la informació dels NM i de l’offset:
auxNM = [{‘Longitud d»ona’} matrix2cell_1x1(app,app.axisNM)]’; % El doble ‘ l’agafa com un, però s’ha de posar així
auxBlack = [{‘Black’} matrix2cell_1x1(app,app.black)]’;
app.toSaveFile = [auxNM auxBlack app.toSaveFile]; % Afegim les 2 primeres columnes
 
% Ho guardem tot a la pàgina de transmitàncies de l’excel indicat:
% xlswrite() provocava errors i no estava recomenada per Mathworks
writecell(app.toSaveFile,app.selectedfile,’Sheet’,’Transmittance’);
saved = saved + 1;
 
% Repetim el proces, però amb els NM, la situació inicial i els espectres mesurats, per la pàgina 1 de l’excel indicat:
app.toSaveFile = {}; % Esborrem l’anterior
app.toSaveFile = [app.table(:,2) matrix2cell_1x1(app,app.matrixSpectrum)]’; % S’identifiquen amb el mateix nom a les 2 pàgines
auxWhite = [{‘White’} matrix2cell_1x1(app,app.white)]’;
app.toSaveFile = [auxNM auxWhite app.toSaveFile]; % Afegim les 2 primeres columnes
 
% Ho guardem tot a la pàgina d’espectres de l’excel indicat:
writecell(app.toSaveFile,app.selectedfile,’Sheet’,’Spectrum’);
saved = saved + 1;
 
catch Error
if strcmp(Error.identifier,’MATLAB:table:write:FileOpenInAnotherProcess’)
app.TextArea.Value = [Error.message; app.TextArea.Value];
elseif strcmp(Error.identifier,’MATLAB:badsubscript’)
app.TextArea.Value = [‘There is nothing to export’; app.TextArea.Value];
end
end
 
if isequal(saved,2)
app.TextArea.Value = [‘Saved’; app.TextArea.Value];
else
app.TextArea.Value = [‘Error to saved’; app.TextArea.Value];
end
end
 
 
function results = readData(app)
flush(app.device);
aux = readline(app.device);
aux = readline(app.device);
aux_vec = str2double(regexp(aux,’\d+’,’match’));
results=aux_vec;
 
 
end
end
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
app.TextArea.Value = ‘Welcome’;
auxString=»;
 
setWavelengthItems(app);
app.black = linspace(0,0,256); % Està predefinit el negre a 0
 
 
end
% Changes arrangement of the app based on UIFigure width
function updateAppLayout(app, event)
currentFigureWidth = app.SpectrumviewerUIFigure.Position(3);
if(currentFigureWidth <= app.onePanelWidth)
% Change to a 2×1 grid
app.GridLayout.RowHeight = {572, 572};
app.GridLayout.ColumnWidth = {‘1x’};
app.RightPanel.Layout.Row = 2;
app.RightPanel.Layout.Column = 1;
else
% Change to a 1×2 grid
app.GridLayout.RowHeight = {‘1x’};
app.GridLayout.ColumnWidth = {362, ‘1x’};
app.RightPanel.Layout.Row = 1;
app.RightPanel.Layout.Column = 2;
end
end
% Button pushed function: ADDButton
function ADDButtonPushed(app, event)
% S’afegeix la nova mesura a la taula (NO GUARDA A L’EXCEL)
 
valor=app.CheckBox.Value;
 
if valor
newRow = size(app.table,1) + 1;
auxString= sprintf(‘Mostra %d’,app.contador);
app.table{newRow,2} = auxString; % Afegim el nom a la columna 2
app.contador=app.contador +1;
app.table{newRow,1} = true; % Afegim el true a la columna 1
app.matrixTransmittance = [app.matrixTransmittance; app.newResult]; % Afegim les dades obtingues a la matriu
app.matrixSpectrum = [app.matrixSpectrum; app.newSpectrum]; % Afegim les dades obtingues a la matriu
app.UITable.Data = app.table; % Actualitzem la taula de l’app
app.NameEditField.Value = »; % Esborrem el nom del camp on s’ha introduït
app.TextArea.Value = [‘Added’; app.TextArea.Value];
elseif isempty(app.NameEditField.Value)
app.TextArea.Value = [‘Error! You must enter a Name’; app.TextArea.Value];
elseif isempty(app.newResult)
app.TextArea.Value = [‘Error! You have not taken any measure’; app.TextArea.Value];
end
 
 
if ~isempty(app.NameEditField.Value) && ~isempty(app.newResult) % Si s’ha introduit un nom i hi ha una mesura feta
newRow = size(app.table,1) + 1;
app.table{newRow,2} = app.NameEditField.Value; % Afegim el nom a la columna 2
app.table{newRow,1} = true; % Afegim el true a la columna 1
app.matrixTransmittance = [app.matrixTransmittance; app.newResult]; % Afegim les dades obtingues a la matriu
app.matrixSpectrum = [app.matrixSpectrum; app.newSpectrum]; % Afegim les dades obtingues a la matriu
app.UITable.Data = app.table; % Actualitzem la taula de l’app
app.NameEditField.Value = »; % Esborrem el nom del camp on s’ha introduït
app.TextArea.Value = [‘Added’; app.TextArea.Value];
elseif isempty(app.NameEditField.Value)
app.TextArea.Value = [‘Error! You must enter a Name’; app.TextArea.Value];
elseif isempty(app.newResult)
app.TextArea.Value = [‘Error! You have not taken any measure’; app.TextArea.Value];
end
app.refreshplot; % Actualitzem la gràfica amb el nou nom de la mostra
end
% Button pushed function: DELETEButton
function DELETEButtonPushed(app, event)
if ~isempty(app.nameListSelected) && isequal(app.NameEditField.Value,string(app.nameListSelected)) % Si s’ha seleccionat un nom de la taula
% S’ha de verificar que en el camp ‘Nom’ hi hagi alguna cosa escrita, pq si polsavem un i s’esborrava el nom, l’eliminava igualment al polsar DELETE
app.table(app.indexCelSelected(1),:) = []; % Elimina tota la fila seleccionada
app.UITable.Data = app.table; % Actualitzem la taula de l’app
app.matrixTransmittance(app.indexCelSelected(1),:) = []; % Elimina tota la fila seleccionada corresponent al que estem esborrant
app.matrixSpectrum(app.indexCelSelected(1),:) = []; % Elimina tota la fila seleccionada corresponent al que estem esborrant
app.NameEditField.Value = »; % Esborrem el nom del camp un cop s’ha eliminat
app.nameListSelected = {};
app.TextArea.Value = [‘Deleted’; app.TextArea.Value];
else
app.TextArea.Value = [‘Error! You must select a spectrum’; app.TextArea.Value];
end
app.refreshplot;
end
% Cell edit callback: UITable
function UITableCellEdit(app, event)
app.indexCelSelected = event.Indices;
% Canviem l’estat de la check box:
app.table{app.indexCelSelected(1),app.indexCelSelected(2)} = event.NewData;
cla(app.UIAxes);
refreshplot(app);
end
% Cell selection callback: UITable
function UITableCellSelection(app, event)
app.indexCelSelected = event.Indices; % indexCelSelected retorna un vector [fila,columna]
if app.indexCelSelected(2) == 2 % Només reacciona a la columna dels noms
% El nom s’ha de guardar a part, pq només s’haurà de poder eliminar si existeix, i per existir s’ha de seleccionar.
app.nameListSelected = app.UITable.Data{app.indexCelSelected(1),app.indexCelSelected(2)};
app.NameEditField.Value = string(app.nameListSelected); % Mostra el nom de l’espectre seleccionat
end
end
% Menu selected function: OpenMenu
function OpenMenuSelected(app, event)
% S’obrirà una finestra per importar un fitxer .xlsx (retorna el nom i l’adreça)
[file,path] = uigetfile(‘*.xlsx’);
% Esborrem les dades de l’ultima imporació
% La matriu no fa falta, perquè se substitueix
% Les taules de cel·les en canvi es maneten les cel·les que no es modiquen amb la nova importació
importedTable = {};
txt = {}; % No se si fa falta, però és per garantir que s’esborra el que hi havia abans
if isequal(file,0)
app.TextArea.Value = [‘User clicked Cancel’; app.TextArea.Value];
else
% Identifiquem les característiques de l’excel obert:
app.selectedfile = fullfile(path,file); % Crea la direcció completa del fitxer
app.sheets = sheetnames(app.selectedfile); % Identifica els noms de les pàgines de l’excel, format columna
 
ok = 0;
for iSheet = 1:size(app.sheets,1)
if isequal(app.sheets(iSheet),’Transmittance’)
% Primer obtenim les mesures i els noms de les transmitàncies, l’eix X i l’offset:
[num, txt] = xlsread(app.selectedfile,’Transmittance’); % Importem les dades de la 2a pàgina de l’excel
num = transpose(num); % Format columna
txt = transpose(txt); % Format columna
app.axisNM = num(1,:); % Identifiquem l’eix X, que es troba a la primera columna de l’excel (primera fila de num)
app.black = num(2,:); % Identifiquem l’offset, que es troba a la segona columna de l’excel (segona fila de num), pot ser NaN, després ja tenim en comtpe que pot no existir
nImports = size(txt,1) – 2; % Número de mesures importades. Li restem 2 (1a columna són els nm i 2a l’offset).
app.matrixTransmittance = [app.matrixTransmittance; num(3:end,:)]; % Afegeix els nous valors als que ja teniem
 
% We build the new table with the new transmittances:
importedTable(1:nImports,1) = {false}; % Posa la 1a columna (el número d’elements importats) a false
importedTable(1:nImports,2) = txt(3:end,:); % Posa a la 2a columna tots els noms importats
app.table = [app.table; importedTable]; % Afegim el que s’ha importat a la part inferior
app.UITable.Data = app.table; % Actualitzem la taula de l’app
ok = ok + 1;
 
elseif isequal(app.sheets(iSheet),’Spectrum’)
% Finalment també obtenim els espectres i el blanc:
num = xlsread(app.selectedfile,’Spectrum’); % Importem les dades de la 1a pàgina de l’excel
num = transpose(num); % Format columna
app.white = num(2,:); % Identifiquem la situació inicial, que es troba a la segona columna de l’excel (segona fila de num)
app.matrixSpectrum = [app.matrixSpectrum; num(3:end,:)]; % Afegeix els valors del document obert als que teniem amb el mateix ordre que les transmitancies
ok = ok + 1;
 
else
app.TextArea.Value = [‘Excel page #’, num2str(iSheet),’ not identified correctly’; app.TextArea.Value];
end
end
 
if isequal(ok,2) % S’han llegit correctament les 2 pàgines
app.TextArea.Value = [‘User has open: ‘, file; app.TextArea.Value];
else
app.TextArea.Value = [‘Error, data not obtained correctly’; app.TextArea.Value];
end
end
end
% Menu selected function: SaveMenu
function SaveMenuSelected(app, event)
% Guardarà la mesura en el excel establert anteriorment, sinó obligarà a crear un fitxer nou.
app.toSaveFile = {}; % Esborrem l’anterior
if isempty(app.selectedfile) % Si no hi ha cap fitxer seleccionat, equival a fer SaveAs
app.SaveAsMenuSelected;
else
app.saveToExcel;
end
end
% Menu selected function: SaveAsMenu
function SaveAsMenuSelected(app, event)
% Guardarà la mesura en un nou fitxer:
[file,path] = uiputfile(‘*.xlsx’); % Identifiquem el fitxer
app.toSaveFile = {}; % Esborrem l’anterior
 
if isequal(file,0)
app.TextArea.Value = [‘User clicked Cancel’; app.TextArea.Value];
else
app.selectedfile = fullfile(path,file); % Crea la direcció completa del fitxer
app.saveToExcel;
end
end
% Menu selected function: ExitMenu
function ExitMenuSelected(app, event)
delete(app)
end
% Button pushed function: BlackButton
function BlackButtonPushed(app, event)
%app.black = app.readData;
auxMean=app.NmostresEditField.Value; %Guardem valor de la quantitat de mostres que volem fer mitja
auxMatrix=zeros(auxMean,256); %Creem una matriu de zeros
if auxMean>1
while auxMean>0 %Guardem els valors mesurats en la matriu
auxVector = app.readData;
auxMatrix(auxMean,:)=auxVector;
auxMean=auxMean-1;
end
app.black = mean(auxMatrix); %Promitgem els valors de la matriu
else
app.black=app.readData;
end
 
 
 
plot(app.UIAxes,app.axisNM,app.black);
legend(app.UIAxes,’Black’);
end
% Button pushed function: WhiteButton
function WhiteButtonPushed(app, event)
%app.white = app.readData-app.black;
 
 
auxMean=app.NmostresEditField.Value; %Guardem valor de la quantitat de mostres que volem fer mitja
auxMatrix=zeros(auxMean,256); %Creem una matriu de zeros
if auxMean>1
while auxMean>0 %Guardem els valors mesurats en la matriu
auxVector = app.readData-app.black;
auxMatrix(auxMean,:)=auxVector;
auxMean=auxMean-1;
end
app.white = mean(auxMatrix); %Promitgem els valors de la matriu
else
app.white=app.readData-app.black;
end
plot(app.UIAxes,app.axisNM,app.white);
legend(app.UIAxes,’White’);
end
% Callback function: CheckBox, MeasureButton, StopButton,
% …and 1 other component
function MeasureButtonPushed(app, event)
auxMean=app.NmostresEditField.Value; %Guardem valor de la quantitat de mostres que volem fer mitja
auxMatrix=zeros(auxMean,256); %Creem una matriu de zeros
if auxMean>1
while auxMean>0 %Guardem els valors mesurats en la matriu
auxVector = app.readData-app.black;
auxMatrix(auxMean,:)=auxVector;
auxMean=auxMean-1;
end
app.newSpectrum = mean(auxMatrix); %Promitgem els valors de la matriu
else
app.newSpectrum=app.readData-app.black;
end
 
 
val=app.CheckBox.Value;
if val %Si tenim activada la check box
while app.StopButton.Value==0
plot(app.UIAxes,app.axisNM,app.newSpectrum);
legend(app.UIAxes,’Measure’);
RedButtonPushed(app, true);
Blue12(app, true);
Green12(app, true);
pause(app.tempsEditField.Value);
auxMean=app.NmostresEditField.Value;
auxMatrix=zeros(auxMean,256);
 
 
 
if auxMean>1
while auxMean>0
auxVector = app.readData-app.black;
auxMatrix(auxMean,:)=auxVector;
auxMean=auxMean-1;
end
app.newSpectrum = mean(auxMatrix);
auxMean=app.NmostresEditField.Value;
app.ResultButtonauxMatrix=zeros(auxMean,256);
else
app.newSpectrum=app.readData-app.black;
end
end
 
else
plot(app.UIAxes,app.axisNM,app.newSpectrum);
legend(app.UIAxes,’Measure’);
end
 
end
% Button pushed function: RedButton
function RedButtonPushed(app, event)
val=app.CheckBox.Value;
if isempty(app.white)
app.TextArea.Value = [‘You did not measure the initial situation (White)’; app.TextArea.Value];
elseif isempty(app.newSpectrum)
app.TextArea.Value = [‘You have not performed the spectrum measurement (Measure)’; app.TextArea.Value];
else
 
%app.newResult = (app.newSpectrum./app.white)*100;
app.newResult = 100-(app.newSpectrum./app.white)*100;
%plot(app.UIAxes,app.axisNM,app.newResult);
% Plot the entire spectrum in blue
plot(app.UIAxes, app.axisNM, app.newResult, ‘b’);
hold(app.UIAxes, ‘on’);
 
% Highlight the specific range in red (replace 400 and 700 with your desired range)
highlight_range = [625, 740];
fill(app.UIAxes, [highlight_range(1), highlight_range(2), highlight_range(2), highlight_range(1)], [0, 0, 100, 100], ‘r’, ‘FaceAlpha’, 0.3);
 
hold(app.UIAxes, ‘off’);
legend(app.UIAxes,’Absorbance’);
end
if val
ADDButtonPushed(app,true);
end
end
% Button pushed function: ResultButton
function BlueButtonPushed(app, event)
val=app.CheckBox.Value;
if isempty(app.white)
app.TextArea.Value = [‘You did not measure the initial situation (White)’; app.TextArea.Value];
elseif isempty(app.newSpectrum)
app.TextArea.Value = [‘You have not performed the spectrum measurement (Measure)’; app.TextArea.Value];
else
 
%app.newResult = (app.newSpectrum./app.white)*100;
app.newResult = 100-(app.newSpectrum./app.white)*100;
%plot(app.UIAxes,app.axisNM,app.newResult);
% Plot the entire spectrum in blue
plot(app.UIAxes, app.axisNM, app.newResult, ‘b’);
hold(app.UIAxes, ‘on’);
 
% Highlight the specific range in red (replace 400 and 700 with your desired range)
highlight_range = [440, 500];
fill(app.UIAxes, [highlight_range(1), highlight_range(2), highlight_range(2), highlight_range(1)], [0, 0, 100, 100], ‘b’, ‘FaceAlpha’, 0.3);
 
hold(app.UIAxes, ‘off’);
legend(app.UIAxes,’Absorbance’);
end
if val
ADDButtonPushed(app,true);
end
end
% Button pushed function: ResultButton
function GreenButtonPushed(app, event)
val=app.CheckBox.Value;
if isempty(app.white)
app.TextArea.Value = [‘You did not measure the initial situation (White)’; app.TextArea.Value];
elseif isempty(app.newSpectrum)
app.TextArea.Value = [‘You have not performed the spectrum measurement (Measure)’; app.TextArea.Value];
else
 
%app.newResult = (app.newSpectrum./app.white)*100;
app.newResult = 100-(app.newSpectrum./app.white)*100;
%plot(app.UIAxes,app.axisNM,app.newResult);
% Plot the entire spectrum in blue
plot(app.UIAxes, app.axisNM, app.newResult, ‘b’);
hold(app.UIAxes, ‘on’);
 
% Highlight the specific range in red (replace 400 and 700 with your desired range)
highlight_range = [500 , 565];
fill(app.UIAxes, [highlight_range(1), highlight_range(2), highlight_range(2), highlight_range(1)], [0, 0, 100, 100], ‘g’, ‘FaceAlpha’, 0.3);
 
hold(app.UIAxes, ‘off’);
legend(app.UIAxes,’Absorbance’);
end
if val
ADDButtonPushed(app,true);
end
end
% Value changed function: Minimumwavelength
function MinimumwavelengthValueChanged(app, event)
auxMin = str2double(app.Minimumwavelength.Value); % El item (char) s’ha de convertir a numero
if auxMin < app.maxX % El mínim no pot ser superior ni igual al màxim
app.minX = auxMin; % Actualitzem el valor si és vàlid
xlim(app.UIAxes, [app.minX app.maxX]); % Actualitzem els límits de la gràfica que vol veure l’usuari
else
app.Minimumwavelength.Value = char(string(app.minX)); % No li deixem canviar el valor, que és més gran que el màxim
app.TextArea.Value = [‘The minimum cannot exceed the maximum’; app.TextArea.Value];
end
end
% Value changed function: Maximumwavelength
function MaximumwavelengthValueChanged(app, event)
auxMax = str2double(app.Maximumwavelength.Value); % El item (char) s’ha de convertir a numero
if auxMax > app.minX % El màxim no pot ser inferior ni igual al mínim
app.maxX = auxMax; % Actualitzem el valor si és vàlid
xlim(app.UIAxes, [app.minX app.maxX]); % Actualitzem els límits de la gràfica que vol veure l’usuari
else % No li deixem canviar el valor, que és més petit que el mínim:
app.Maximumwavelength.Value = char(string(app.maxX)); % Fem la conversió
app.TextArea.Value = [‘The maximum cannot be less than the minimum’; app.TextArea.Value];
end
end
% Callback function: ConnectButton, SerialPortDropDown
function ConnectButtonPushed(app, event)
 
try
 
app.SerialPortDropDown.Items=serialportlist(); %Llista tots els port serie disponibles
auxSerial = app.SerialPortDropDown.Value; %valor seleccionat de la llista
app.device = serialport(auxSerial,9600); %conexio amb el port serio
%
catch Error
if strcmp(Error.identifier,’MATLAB:hwsdk:general:boardNotDetected’)
app.TextArea.Value = [Error.message; app.TextArea.Value];
end
 
end
end
% Button pushed function: DisconnectButton
function DisconnectButtonPushed(app, event)
if isequal(app.ArduinoStatus.Text, ‘Connected’) % Si està connectat, deconnectem
app.ardu.a = {}; % La funció clear no funcionava, i quan tornavem a fer «Connect» saltava un error
app.ArduinoStatus.Text = ‘Disconnected’;
app.ArduinoStatus.FontColor = ‘blue’;
app.TextArea.Value = [‘Arduino disconnected’; app.TextArea.Value];
end
end
% Menu selected function: IcantdeleteasamplefromthetableMenu
function IcantdeleteasamplefromthetableMenuSelected(app, event)
msgbox(‘It´s a Matlab bug. Surely the sample you want to delete is now in the same position as the previous one. To fix this, click in the cell on the left (not in the tic area) and then select the cell you want to delete again.’);
end
% Menu selected function:
% IhaveremovedasampleandinexcelitisstillthereMenu
function IhaveremovedasampleandinexcelitisstillthereMenuSelected(app, event)
msgbox(‘This is a problem because fewer samples have now been saved than before. Please delete it manually in excel and do not leave any columns in between without information.’);
end
% Menu selected function: ThekeyboardshortcutsdontworkMenu
function ThekeyboardshortcutsdontworkMenuSelected(app, event)
msgbox(‘Probably in the previous action you pressed a button or edited a field (it is marked in blue). Please click anywhere in the app and be able to use keyboard shortcuts again.’);
end
% Key release function: SpectrumviewerUIFigure
function KeyRelease(app, event)
key = event.Key;
if isequal(key,’control’)
app.control = true;
elseif app.control % Si s’havia polsat
switch key
case ‘o’
app.OpenMenuSelected;
app.control = false;
case ‘s’
app.SaveMenuSelected;
app.control = false;
case ‘c’
app.ConnectButtonPushed;
app.control = false;
case ‘d’
app.DisconnectButtonPushed;
app.control = false;
case ‘b’
app.BlackButtonPushed;
app.control = false;
case ‘w’
app.WhiteButtonPushed;
app.control = false;
case ‘m’
app.MeasureButtonPushed;
app.control = false;
case ‘r’
app.RedButtonPushed;
app.Green12;
app.Blue12;
app.control = false;
 
otherwise
app.control = false;
end
elseif isequal(key,’return’)
app.ADDButtonPushed;
elseif isequal(key,’escape’)
app.ExitMenuSelected;
end
end
% Value changed function: IntegrationblocksEditField
function IntegrationblocksEditFieldValueChanged(app, event)
value = app.IntegrationblocksEditField.Value;
write(app.device,value,»uint16″);
 
 
end
% Button down function: UIAxes
function UIAxesButtonDown(app, event)
 
end
% Button pushed function: BlueButton
function Blue12(app, event)
val=app.CheckBox.Value;
if isempty(app.white)
app.TextArea.Value = [‘You did not measure the initial situation (White)’; app.TextArea.Value];
elseif isempty(app.newSpectrum)
app.TextArea.Value = [‘You have not performed the spectrum measurement (Measure)’; app.TextArea.Value];
else
 
%app.newResult = (app.newSpectrum./app.white)*100;
app.newResult = 100-(app.newSpectrum./app.white)*100;
%plot(app.UIAxes,app.axisNM,app.newResult);
% Plot the entire spectrum in blue
plot(app.UIAxes, app.axisNM, app.newResult, ‘b’);
hold(app.UIAxes, ‘on’);
 
% Highlight the specific range in red (replace 400 and 700 with your desired range)
highlight_range = [440, 500];
fill(app.UIAxes, [highlight_range(1), highlight_range(2), highlight_range(2), highlight_range(1)], [0, 0, 100, 100], ‘b’, ‘FaceAlpha’, 0.3);
 
hold(app.UIAxes, ‘off’);
legend(app.UIAxes,’Absorbance’);
end
if val
ADDButtonPushed(app,true);
end
end
% Button pushed function: GreenButton
function Green12(app, event)
val=app.CheckBox.Value;
if isempty(app.white)
app.TextArea.Value = [‘You did not measure the initial situation (White)’; app.TextArea.Value];
elseif isempty(app.newSpectrum)
app.TextArea.Value = [‘You have not performed the spectrum measurement (Measure)’; app.TextArea.Value];
else
 
%app.newResult = (app.newSpectrum./app.white)*100;
app.newResult = 100-(app.newSpectrum./app.white)*100;
%plot(app.UIAxes,app.axisNM,app.newResult);
% Plot the entire spectrum in blue
plot(app.UIAxes, app.axisNM, app.newResult, ‘b’);
hold(app.UIAxes, ‘on’);
 
% Highlight the specific range in red (replace 400 and 700 with your desired range)
highlight_range = [500 , 565];
fill(app.UIAxes, [highlight_range(1), highlight_range(2), highlight_range(2), highlight_range(1)], [0, 0, 100, 100], ‘g’, ‘FaceAlpha’, 0.3);
 
hold(app.UIAxes, ‘off’);
legend(app.UIAxes,’Absorbance’);
end
if val
ADDButtonPushed(app,true);
end
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Get the file path for locating images
pathToMLAPP = fileparts(mfilename(‘fullpath’));
% Create SpectrumviewerUIFigure and hide until all components are created
app.SpectrumviewerUIFigure = uifigure(‘Visible’, ‘off’);
app.SpectrumviewerUIFigure.AutoResizeChildren = ‘off’;
app.SpectrumviewerUIFigure.Position = [100 100 1152 572];
app.SpectrumviewerUIFigure.Name = ‘Spectrum viewer’;
app.SpectrumviewerUIFigure.SizeChangedFcn = createCallbackFcn(app, @updateAppLayout, true);
app.SpectrumviewerUIFigure.KeyReleaseFcn = createCallbackFcn(app, @KeyRelease, true);
% Create FileMenu
app.FileMenu = uimenu(app.SpectrumviewerUIFigure);
app.FileMenu.Text = ‘File’;
% Create OpenMenu
app.OpenMenu = uimenu(app.FileMenu);
app.OpenMenu.MenuSelectedFcn = createCallbackFcn(app, @OpenMenuSelected, true);
app.OpenMenu.Separator = ‘on’;
app.OpenMenu.Text = ‘Open’;
% Create SaveMenu
app.SaveMenu = uimenu(app.FileMenu);
app.SaveMenu.MenuSelectedFcn = createCallbackFcn(app, @SaveMenuSelected, true);
app.SaveMenu.Separator = ‘on’;
app.SaveMenu.Text = ‘Save’;
% Create SaveAsMenu
app.SaveAsMenu = uimenu(app.FileMenu);
app.SaveAsMenu.MenuSelectedFcn = createCallbackFcn(app, @SaveAsMenuSelected, true);
app.SaveAsMenu.Separator = ‘on’;
app.SaveAsMenu.Text = ‘Save As’;
% Create ExitMenu
app.ExitMenu = uimenu(app.FileMenu);
app.ExitMenu.MenuSelectedFcn = createCallbackFcn(app, @ExitMenuSelected, true);
app.ExitMenu.Separator = ‘on’;
app.ExitMenu.Text = ‘Exit’;
% Create HelpMenu
app.HelpMenu = uimenu(app.SpectrumviewerUIFigure);
app.HelpMenu.Text = ‘Help’;
% Create IcantdeleteasamplefromthetableMenu
app.IcantdeleteasamplefromthetableMenu = uimenu(app.HelpMenu);
app.IcantdeleteasamplefromthetableMenu.MenuSelectedFcn = createCallbackFcn(app, @IcantdeleteasamplefromthetableMenuSelected, true);
app.IcantdeleteasamplefromthetableMenu.Text = ‘I can»t delete a sample from the table’;
% Create IhaveremovedasampleandinexcelitisstillthereMenu
app.IhaveremovedasampleandinexcelitisstillthereMenu = uimenu(app.HelpMenu);
app.IhaveremovedasampleandinexcelitisstillthereMenu.MenuSelectedFcn = createCallbackFcn(app, @IhaveremovedasampleandinexcelitisstillthereMenuSelected, true);
app.IhaveremovedasampleandinexcelitisstillthereMenu.Text = ‘I have removed a sample and in excel it is still there’;
% Create ImusinganewArduinoanditdoesntworkMenu
app.ImusinganewArduinoanditdoesntworkMenu = uimenu(app.HelpMenu);
app.ImusinganewArduinoanditdoesntworkMenu.Text = ‘I»m using a new Arduino and it doesn»t work’;
% Create ThekeyboardshortcutsdontworkMenu
app.ThekeyboardshortcutsdontworkMenu = uimenu(app.HelpMenu);
app.ThekeyboardshortcutsdontworkMenu.MenuSelectedFcn = createCallbackFcn(app, @ThekeyboardshortcutsdontworkMenuSelected, true);
app.ThekeyboardshortcutsdontworkMenu.Text = ‘The keyboard shortcuts don»t work’;
% Create GridLayout
app.GridLayout = uigridlayout(app.SpectrumviewerUIFigure);
app.GridLayout.ColumnWidth = {362, ‘1x’};
app.GridLayout.RowHeight = {‘1x’};
app.GridLayout.ColumnSpacing = 0;
app.GridLayout.RowSpacing = 0;
app.GridLayout.Padding = [0 0 0 0];
app.GridLayout.Scrollable = ‘on’;
% Create LeftPanel
app.LeftPanel = uipanel(app.GridLayout);
app.LeftPanel.Layout.Row = 1;
app.LeftPanel.Layout.Column = 1;
% Create SpectrumdescriptionPanel
app.SpectrumdescriptionPanel = uipanel(app.LeftPanel);
app.SpectrumdescriptionPanel.Title = ‘Spectrum description’;
app.SpectrumdescriptionPanel.Position = [24 303 315 88];
% Create NameEditFieldLabel
app.NameEditFieldLabel = uilabel(app.SpectrumdescriptionPanel);
app.NameEditFieldLabel.HorizontalAlignment = ‘right’;
app.NameEditFieldLabel.Position = [20 33 38 22];
app.NameEditFieldLabel.Text = ‘Name’;
% Create NameEditField
app.NameEditField = uieditfield(app.SpectrumdescriptionPanel, ‘text’);
app.NameEditField.Position = [73 33 223 22];
% Create DELETEButton
app.DELETEButton = uibutton(app.SpectrumdescriptionPanel, ‘push’);
app.DELETEButton.ButtonPushedFcn = createCallbackFcn(app, @DELETEButtonPushed, true);
app.DELETEButton.VerticalAlignment = ‘top’;
app.DELETEButton.Position = [182 3 76 20];
app.DELETEButton.Text = ‘DELETE’;
% Create ADDButton
app.ADDButton = uibutton(app.SpectrumdescriptionPanel, ‘push’);
app.ADDButton.ButtonPushedFcn = createCallbackFcn(app, @ADDButtonPushed, true);
app.ADDButton.Position = [92 2 83 20];
app.ADDButton.Text = ‘ADD’;
% Create LogoUPC
app.LogoUPC = uiimage(app.LeftPanel);
app.LogoUPC.Position = [144 6 186 91];
app.LogoUPC.ImageSource = fullfile(pathToMLAPP, ‘upc_.png’);
% Create LogoTelecos
app.LogoTelecos = uiimage(app.LeftPanel);
app.LogoTelecos.Position = [58 6 96 89];
app.LogoTelecos.ImageSource = fullfile(pathToMLAPP, ‘descarga (2).png’);
% Create SelectaspectrumtorepresentLabel
app.SelectaspectrumtorepresentLabel = uilabel(app.LeftPanel);
app.SelectaspectrumtorepresentLabel.HorizontalAlignment = ‘center’;
app.SelectaspectrumtorepresentLabel.FontSize = 20;
app.SelectaspectrumtorepresentLabel.FontWeight = ‘bold’;
app.SelectaspectrumtorepresentLabel.Position = [25 518 314 24];
app.SelectaspectrumtorepresentLabel.Text = ‘Select a spectrum to represent’;
% Create StatusPanel
app.StatusPanel = uipanel(app.LeftPanel);
app.StatusPanel.Title = ‘Status’;
app.StatusPanel.Position = [21 105 318 98];
% Create TextAreaLabel
app.TextAreaLabel = uilabel(app.StatusPanel);
app.TextAreaLabel.HorizontalAlignment = ‘right’;
app.TextAreaLabel.Position = [62 28 25 22];
app.TextAreaLabel.Text = »;
% Create TextArea
app.TextArea = uitextarea(app.StatusPanel);
app.TextArea.Position = [9 7 297 64];
% Create SpectrumtablePanel
app.SpectrumtablePanel = uipanel(app.LeftPanel);
app.SpectrumtablePanel.Title = ‘Spectrum table’;
app.SpectrumtablePanel.Position = [24 390 315 129];
% Create UITable
app.UITable = uitable(app.SpectrumtablePanel);
app.UITable.ColumnName = {‘Plot’; ‘Name’};
app.UITable.RowName = {};
app.UITable.ColumnEditable = [true false];
app.UITable.CellEditCallback = createCallbackFcn(app, @UITableCellEdit, true);
app.UITable.CellSelectionCallback = createCallbackFcn(app, @UITableCellSelection, true);
app.UITable.Position = [3 9 303 96];
% Create SerialPortConnectionPanel
app.SerialPortConnectionPanel = uipanel(app.LeftPanel);
app.SerialPortConnectionPanel.Title = ‘Serial Port Connection’;
app.SerialPortConnectionPanel.Position = [23 202 316 102];
% Create ConnectButton
app.ConnectButton = uibutton(app.SerialPortConnectionPanel, ‘push’);
app.ConnectButton.ButtonPushedFcn = createCallbackFcn(app, @ConnectButtonPushed, true);
app.ConnectButton.Position = [13 12 100 22];
app.ConnectButton.Text = ‘Connect’;
% Create DisconnectButton
app.DisconnectButton = uibutton(app.SerialPortConnectionPanel, ‘push’);
app.DisconnectButton.ButtonPushedFcn = createCallbackFcn(app, @DisconnectButtonPushed, true);
app.DisconnectButton.Position = [122 12 100 22];
app.DisconnectButton.Text = ‘Disconnect’;
% Create SerialPortDropDownLabel
app.SerialPortDropDownLabel = uilabel(app.SerialPortConnectionPanel);
app.SerialPortDropDownLabel.HorizontalAlignment = ‘right’;
app.SerialPortDropDownLabel.Position = [32 43 62 22];
app.SerialPortDropDownLabel.Text = ‘Serial Port’;
% Create SerialPortDropDown
app.SerialPortDropDown = uidropdown(app.SerialPortConnectionPanel);
app.SerialPortDropDown.Items = {‘Option1’, ‘Option2’};
app.SerialPortDropDown.ValueChangedFcn = createCallbackFcn(app, @ConnectButtonPushed, true);
app.SerialPortDropDown.Position = [109 43 100 22];
app.SerialPortDropDown.Value = ‘Option1’;
% Create RightPanel
app.RightPanel = uipanel(app.GridLayout);
app.RightPanel.Layout.Row = 1;
app.RightPanel.Layout.Column = 2;
% Create Panel
app.Panel = uipanel(app.RightPanel);
app.Panel.Position = [6 116 778 450];
% Create UIAxes
app.UIAxes = uiaxes(app.Panel);
xlabel(app.UIAxes, ‘Wavelength [nm]’)
ylabel(app.UIAxes, ‘Spectrum [Counts]’)
app.UIAxes.XTickLabelRotation = 0;
app.UIAxes.YTickLabelRotation = 0;
app.UIAxes.ZTickLabelRotation = 0;
app.UIAxes.XGrid = ‘on’;
app.UIAxes.XMinorGrid = ‘on’;
app.UIAxes.ButtonDownFcn = createCallbackFcn(app, @UIAxesButtonDown, true);
app.UIAxes.Position = [12 21 751 344];
% Create SPECTROPHOTOMETERLabel
app.SPECTROPHOTOMETERLabel = uilabel(app.Panel);
app.SPECTROPHOTOMETERLabel.HorizontalAlignment = ‘center’;
app.SPECTROPHOTOMETERLabel.FontName = ‘Arial’;
app.SPECTROPHOTOMETERLabel.FontSize = 40;
app.SPECTROPHOTOMETERLabel.FontWeight = ‘bold’;
app.SPECTROPHOTOMETERLabel.Position = [144 378 489 48];
app.SPECTROPHOTOMETERLabel.Text = ‘SPECTROPHOTOMETER’;
% Create SensorcontrolPanel
app.SensorcontrolPanel = uipanel(app.RightPanel);
app.SensorcontrolPanel.Title = ‘Sensor control’;
app.SensorcontrolPanel.Position = [6 6 778 104];
% Create BlackButton
app.BlackButton = uibutton(app.SensorcontrolPanel, ‘push’);
app.BlackButton.ButtonPushedFcn = createCallbackFcn(app, @BlackButtonPushed, true);
app.BlackButton.Position = [218 45 100 22];
app.BlackButton.Text = ‘Black’;
% Create WhiteButton
app.WhiteButton = uibutton(app.SensorcontrolPanel, ‘push’);
app.WhiteButton.ButtonPushedFcn = createCallbackFcn(app, @WhiteButtonPushed, true);
app.WhiteButton.Position = [338 45 100 22];
app.WhiteButton.Text = ‘White’;
% Create MeasureButton
app.MeasureButton = uibutton(app.SensorcontrolPanel, ‘push’);
app.MeasureButton.ButtonPushedFcn = createCallbackFcn(app, @MeasureButtonPushed, true);
app.MeasureButton.Position = [218 14 100 22];
app.MeasureButton.Text = ‘Measure’;
% Create RedButton
app.RedButton = uibutton(app.SensorcontrolPanel, ‘push’);
app.RedButton.ButtonPushedFcn = createCallbackFcn(app, @RedButtonPushed, true);
app.RedButton.Position = [338 13 59 23];
app.RedButton.Text = ‘Red’;
% Create MinwavelengthnmLabel
app.MinwavelengthnmLabel = uilabel(app.SensorcontrolPanel);
app.MinwavelengthnmLabel.HorizontalAlignment = ‘right’;
app.MinwavelengthnmLabel.Position = [-4 45 124 22];
app.MinwavelengthnmLabel.Text = ‘Min. wavelength (nm)’;
% Create Minimumwavelength
app.Minimumwavelength = uidropdown(app.SensorcontrolPanel);
app.Minimumwavelength.Items = {};
app.Minimumwavelength.ValueChangedFcn = createCallbackFcn(app, @MinimumwavelengthValueChanged, true);
app.Minimumwavelength.Position = [135 45 61 22];
app.Minimumwavelength.Value = {};
% Create MaxwavelengthnmLabel
app.MaxwavelengthnmLabel = uilabel(app.SensorcontrolPanel);
app.MaxwavelengthnmLabel.HorizontalAlignment = ‘right’;
app.MaxwavelengthnmLabel.Position = [-4 14 124 22];
app.MaxwavelengthnmLabel.Text = ‘Max. wavelength (nm)’;
% Create Maximumwavelength
app.Maximumwavelength = uidropdown(app.SensorcontrolPanel);
app.Maximumwavelength.Items = {};
app.Maximumwavelength.ValueChangedFcn = createCallbackFcn(app, @MaximumwavelengthValueChanged, true);
app.Maximumwavelength.Position = [135 14 58 22];
app.Maximumwavelength.Value = {};
% Create NmostresEditFieldLabel
app.NmostresEditFieldLabel = uilabel(app.SensorcontrolPanel);
app.NmostresEditFieldLabel.HorizontalAlignment = ‘right’;
app.NmostresEditFieldLabel.Position = [597 45 65 22];
app.NmostresEditFieldLabel.Text = ‘Nº mostres’;
% Create NmostresEditField
app.NmostresEditField = uieditfield(app.SensorcontrolPanel, ‘numeric’);
app.NmostresEditField.Position = [677 45 100 22];
% Create tempsEditFieldLabel
app.tempsEditFieldLabel = uilabel(app.SensorcontrolPanel);
app.tempsEditFieldLabel.HorizontalAlignment = ‘right’;
app.tempsEditFieldLabel.Position = [571 14 38 22];
app.tempsEditFieldLabel.Text = ‘temps’;
% Create tempsEditField
app.tempsEditField = uieditfield(app.SensorcontrolPanel, ‘numeric’);
app.tempsEditField.ValueChangedFcn = createCallbackFcn(app, @MeasureButtonPushed, true);
app.tempsEditField.Position = [624 14 100 22];
% Create CheckBox
app.CheckBox = uicheckbox(app.SensorcontrolPanel);
app.CheckBox.ValueChangedFcn = createCallbackFcn(app, @MeasureButtonPushed, true);
app.CheckBox.Text = »;
app.CheckBox.Position = [546 14 25 22];
% Create StopButton
app.StopButton = uibutton(app.SensorcontrolPanel, ‘state’);
app.StopButton.ValueChangedFcn = createCallbackFcn(app, @MeasureButtonPushed, true);
app.StopButton.Text = ‘Stop’;
app.StopButton.Position = [732 14 46 22];
% Create IntegrationblocksEditFieldLabel
app.IntegrationblocksEditFieldLabel = uilabel(app.SensorcontrolPanel);
app.IntegrationblocksEditFieldLabel.HorizontalAlignment = ‘right’;
app.IntegrationblocksEditFieldLabel.Position = [442 45 100 22];
app.IntegrationblocksEditFieldLabel.Text = ‘Integration blocks’;
% Create IntegrationblocksEditField
app.IntegrationblocksEditField = uieditfield(app.SensorcontrolPanel, ‘numeric’);
app.IntegrationblocksEditField.ValueChangedFcn = createCallbackFcn(app, @IntegrationblocksEditFieldValueChanged, true);
app.IntegrationblocksEditField.Position = [541 45 57 22];
% Create BlueButton
app.BlueButton = uibutton(app.SensorcontrolPanel, ‘push’);
app.BlueButton.ButtonPushedFcn = createCallbackFcn(app, @Blue12, true);
app.BlueButton.Position = [405 13 52 23];
app.BlueButton.Text = ‘Blue’;
% Create GreenButton
app.GreenButton = uibutton(app.SensorcontrolPanel, ‘push’);
app.GreenButton.ButtonPushedFcn = createCallbackFcn(app, @Green12, true);
app.GreenButton.Position = [466 13 52 23];
app.GreenButton.Text = ‘Green’;
% Show the figure after all components are created
app.SpectrumviewerUIFigure.Visible = ‘on’;
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = APP_Spectrophotometer2
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.SpectrumviewerUIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.SpectrumviewerUIFigure)
end
end
end
A notable feature of the sampling kits is the filter design. Each filter comes equipped with a cover on top. This design is not merely for protection; it plays a vital role in the sample collection process. The cover allows for easy and efficient placement and removal of samples on the filter. This feature is crucial for maintaining the purity and integrity of the samples during both the collection and analysis phases. In summary, the Air Quality Sample Collection Process is a well-orchestrated and critical component in environmental monitoring. It involves specialized rooms, a precise collection methodology, the use of a mobile cart for safe sample transfer, and sophisticated filter technology. Each step, from pre-sampling to post-sampling, is designed to ensure the accuracy and reliability of the air quality data gathered, which is essential for meaningful analysis and environmental decision-making