function varargout = serialcommgui(varargin) % SERIALCOMMGUI M-file for serialcommgui.fig % SERIALCOMMGUI, by itself, creates a new SERIALCOMMGUI or raises the existing % singleton*. % % H = SERIALCOMMGUI returns the handle to a new SERIALCOMMGUI or the handle to % the existing singleton*. % % SERIALCOMMGUI('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in SERIALCOMMGUI.M with the given input arguments. % % SERIALCOMMGUI('Property','Value',...) creates a new SERIALCOMMGUI or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before serialcommgui_OpeningFunction gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to serialcommgui_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Copyright 2002-2003 The MathWorks, Inc. % Edit the above text to modify the response to help serialcommgui % Last Modified by GUIDE v2.5 04-Dec-2004 13:14:01 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @serialcommgui_OpeningFcn, ... 'gui_OutputFcn', @serialcommgui_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before serialcommgui is made visible. function serialcommgui_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to serialcommgui (see VARARGIN) % Choose default command line output for serialcommgui handles.output = hObject; handles.num_points = 2500; handles.max_time = 15; handles.use_time_not_points = 1; handles.cancel_data_acq = 0; handles.shownondata = 0; % Update handles structure guidata(hObject, handles); set(handles.timeradio, 'Value', 1); set(handles.numpointsbox, 'Enable', 'Off'); % Set up the axis axes(handles.axes1); xlabel('time (seconds)'); ylabel('data'); global cancel_data_acq; cancel_data_acq = 0; clear cancel_data_acq; % UIWAIT makes serialcommgui wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = serialcommgui_OutputFcn(hObject, eventdata, handles) % 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; function numpointsbox_Callback(hObject, eventdata, handles) % hObject handle to numpointsbox (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of numpointsbox as text % str2double(get(hObject,'String')) returns contents of numpointsbox as a double val = str2num(get(hObject, 'String')); if (length(val) == 1) && (val > 0) && (val <= 1e6) handles.num_points = str2num(get(hObject, 'String')); guidata(hObject, handles); else set(hObject, 'String', num2str(handles.num_points)); end % --- Executes during object creation, after setting all properties. function numpointsbox_CreateFcn(hObject, eventdata, handles) % hObject handle to numpointsbox (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end % --- Executes on button press in getdatabutton. function getdatabutton_Callback(hObject, eventdata, handles) % hObject handle to getdatabutton (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) set(handles.getdatabutton, 'Enable', 'off'); % Disable get data button. set(handles.stopbutton, 'Enable', 'on'); % Enable stop button. set(handles.timeradio, 'Enable', 'inactive'); % Disable time radio set(handles.pointsradio, 'Enable', 'inactive'); % Disable time radio if strcmp(get(handles.maxtimebox, 'Enable'), 'on') % Disable time/points boxes set(handles.maxtimebox, 'Enable', 'inactive'); else set(handles.numpointsbox, 'Enable', 'inactive'); end set(handles.popaxisbutton, 'Enable', 'off'); % Disable pop up axis button set(handles.ndpointscheckbox, 'Enable', 'off'); % Disable non-data points checkbox % Clear the axis axes(handles.axes1); cla; global cancel_data_acq; % Destroy any open serial port objects on COM1 s = instrfind('Port', 'COM1'); if length(s) ~= 0 fclose(s); delete(s); end % A trial serial read to determine whether serial I/O is functioning. % If not, 'fread(s)' will time out and data will have length 0. s = serial('COM1', 'BaudRate', 57600, 'InputBufferSize', 1); fopen(s); data = fread(s); fclose(s); delete(s); clear s; if length(data) ~= 0 % If there was data in the buffer (reads are functioning)... % Create the serial port object. With a buffer size of 512, at a data rate % of 239 bps, it takes about 2 seconds to fill the buffer. s = serial('COM1', 'BaudRate', 57600, 'InputBufferSize', 512); fopen(s); data = []; badtime = []; % vector listing times where data was 255 (for debugging) set(handles.messagewindow, 'String', 'Getting data...'); % Variable initialization. elaptime = 0; time = []; timelimit = handles.max_time; pointslimit = handles.num_points; percent_complete = 0; tic; while (handles.use_time_not_points && (toc < timelimit)) || ... (~handles.use_time_not_points && (length(data) < pointslimit)), % Pause to allow for interrupts, etc. We won't miss data doing % this, because the data buffer gets filled in the background. pause(0.5); if cancel_data_acq cancel_data_acq = 0; break; end new_data_index = length(data) + 1; data = [data fread(s)']; elaptime = toc; if handles.use_time_not_points if floor((elaptime / timelimit)*10) > percent_complete percent_complete = floor((elaptime / timelimit)*10); set(handles.messagewindow, 'String', ... [num2str(min(100, percent_complete*10)) '% complete - ' ... num2str(max(0,floor((timelimit - elaptime)*10))/10) ' seconds remaining...']); end else if floor((length(data) / pointslimit)*10) > percent_complete percent_complete = floor((length(data) / pointslimit)*10); set(handles.messagewindow, 'String', ... [num2str(min(percent_complete*10)) '% complete - ' ... num2str(max(0,pointslimit - length(data))) ' data points remaining...']); end end if length(time) == 0 newtime = linspace(0, elaptime, 513); else newtime = linspace(time(length(time)), elaptime, 513); end time = [time newtime(2:length(newtime))]; % Clear all values of 255 from data count = new_data_index; % Leading 255's: if new_data_index == 1 while data(1) == 255, badtime = [badtime time(1)]; data = data(2:length(data)); time = time(2:length(time)); end count = count + 1; end % Middle 255's: while count < length(time), if data(count) == 255 badtime = [badtime time(count)]; data = [data(1:count-1) data(count+1:length(data))]; time = [time(1:count-1) time(count+1:length(time))]; else count = count + 1; end end % Trailing 255 if data(length(data)) == 255 badtime = [badtime time(length(time))]; data = data(1:length(data)-1); time = time(1:length(time)-1); end % Plot the data on the GUI's axes. plot(time, data); end % If we have received data (i.e., if data acquisition hasn't been immediately % cancelled)... if length(time) > 1 % If the data isn't ALL invalid... if ~(all(data == 255)) % Truncate the vectors to the appropriate time if time limit was used. if handles.use_time_not_points count = 1; while (time(count) <= timelimit) && (count < length(time)), count = count + 1; end data = data(1:count); time = time(1:count); else % Truncate the vectors to the appropriate number of points if % points limit was used. data = data(1:min(pointslimit, length(data))); time = time(1:min(pointslimit, length(time))); end % Make the bad data well-formed count = 1; while count < length(badtime), if badtime(count) > time(length(time)) badtime = badtime(1:count - 1); break; else count = count + 1; end end baddata = []; btcount = 1; while badtime(btcount) <= time(1), baddata = [baddata data(1)]; btcount = btcount + 1; end count = 1; while count <= length(time) if time(count) >= badtime(btcount) baddata = [baddata data(count - 1)]; btcount = btcount + 1; if btcount > length(badtime) break end else count = count + 1; end end while btcount <= length(badtime) baddata(btcount) = data(length(data)); btcount = btcount + 1; end clear btcount count; % Save time and data to the current workspace, so the user can mess % with them. assignin('base', 'baddata', baddata); assignin('base', 'badtime', badtime); assignin('base', 'mouse_data', data); assignin('base', 'mouse_time', time); set(handles.messagewindow, 'String', ... 'Data vectors created in current workspace.'); % Plot the data on the GUI's axes. plot(time, data); hold on; if handles.shownondata plot(badtime, baddata, 'r.'); end else % If the data IS all invalid... set(handles.messagewindow, 'String', ... 'No valid data received.'); end end fclose(s); delete(s); clear s; % If we didn't receive any data when clearing the input buffer and testing % for I/O timout, then print an error. else set(handles.messagewindow, 'String', 'Problem with serial I/O...'); end set(handles.stopbutton, 'Enable', 'off'); % Disable stop button (reads are over). pause(5); % Wait for 5 seconds so the user can read the message. set(handles.messagewindow, 'String', ... 'Welcome to the Mouse-Implanted RFID Data Acquisition Tool!'); set(handles.getdatabutton, 'Enable', 'on'); % Re-enable get data button. set(handles.timeradio, 'Enable', 'on'); % Re-enable time radio set(handles.pointsradio, 'Enable', 'on'); % Re-enable time radio if strcmp(get(handles.maxtimebox, 'Enable'), 'off') % Re-enable time/points boxes set(handles.numpointsbox, 'Enable', 'on'); else set(handles.maxtimebox, 'Enable', 'on'); end set(handles.popaxisbutton, 'Enable', 'on'); % Re-enable pop up axis button set(handles.ndpointscheckbox, 'Enable', 'on'); % Re-enable non-data points checkbox function maxtimebox_Callback(hObject, eventdata, handles) % hObject handle to maxtimebox (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of maxtimebox as text % str2double(get(hObject,'String')) returns contents of maxtimebox as a double val = str2num(get(hObject, 'String')); if (length(val) == 1) & (val > 0) & (val <= 6000) handles.max_time = str2num(get(hObject, 'String')); guidata(hObject, handles); else set(hObject, 'String', num2str(handles.max_time)); end % --- Executes during object creation, after setting all properties. function maxtimebox_CreateFcn(hObject, eventdata, handles) % hObject handle to maxtimebox (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end % --- Executes on button press in timeradio. function timeradio_Callback(hObject, eventdata, handles) % hObject handle to timeradio (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of timeradio % --- Executes on button press in pointsradio. function pointsradio_Callback(hObject, eventdata, handles) % hObject handle to pointsradio (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of pointsradio function messagewindow_Callback(hObject, eventdata, handles) % hObject handle to messagewindow (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of messagewindow as text % str2double(get(hObject,'String')) returns contents of messagewindow as a double % --- Executes during object creation, after setting all properties. function messagewindow_CreateFcn(hObject, eventdata, handles) % hObject handle to messagewindow (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc set(hObject,'BackgroundColor','white'); else set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor')); end function radiopanel_SelectionChangeFcn(hObject, eventdata, handles) % hObject handle to radiopanel (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) if strcmp(get(hObject, 'Tag'), 'pointsradio') set(handles.numpointsbox, 'Enable', 'On'); set(handles.maxtimebox, 'Enable', 'Off'); handles.use_time_not_points = 0; guidata(hObject, handles); else set(handles.numpointsbox, 'Enable', 'Off'); set(handles.maxtimebox, 'Enable', 'On'); handles.use_time_not_points = 1; guidata(hObject, handles); end function radiopanel_CreateFcn(hObject, eventdata, handles) % hObject handle to radiopanel (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % --- Executes on button press in stopbutton. function stopbutton_Callback(hObject, eventdata, handles) % hObject handle to stopbutton (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) global cancel_data_acq; cancel_data_acq = 1; set(handles.messagewindow, 'String', 'Cancelling...'); % --- Executes on button press in popaxisbutton. function popaxisbutton_Callback(hObject, eventdata, handles) % hObject handle to popaxisbutton (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Pop up an external axis figure; time = evalin('base', 'mouse_time'); data = evalin('base', 'mouse_data'); badtime = evalin('base', 'badtime'); baddata = evalin('base', 'baddata'); plot(time, data); xlabel('time (seconds)'); ylabel('data'); title('Mouse Data'); hold on; if handles.shownondata plot(badtime, baddata, 'r.'); end % --- Executes on button press in ndpointscheckbox. function ndpointscheckbox_Callback(hObject, eventdata, handles) % hObject handle to ndpointscheckbox (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of ndpointscheckbox handles.shownondata = get(hObject, 'Value'); % Update handles structure guidata(hObject, handles);