RUNNİNG MOTORS ISSUES İN GUİDE

İ have a problem it seems that no one is maybe getting what i am saying.
İ am trying to run some motors when they entered a particular and stop from running when it is out of that region.
To try to understand the issue, ı have designed a new GUİ wıth just 2 push buttons . RUN and STOP. Guess what , they are working as expected. But when i am trying to ımplement the same code ın my main guı it is not working at all. İ am not having any error in the command window btw. My motors just vibrate and stop vibrating randomly.
The motors are connected to driving motors and driving motors are connected to an arduino uno
The line corresponding to the issue is at the very end of the code.
writeline(handles.arduinoObj, '4&MOTOR_1_2&0!'); This line means vibrating
writeline(handles.arduinoObj, '0&MOTOR_1_2&0!'); This line means No vibration
All thıs is done in GUİDE.
İ wıll post the main code here and i will reply with the Test code.
function varargout = franck_guide(varargin)
% FRANCK_GUIDE MATLAB code for franck_guide.fig
% FRANCK_GUIDE, by itself, creates a new FRANCK_GUIDE or raises the existing
% singleton*.
%
% H = FRANCK_GUIDE returns the handle to a new FRANCK_GUIDE or the handle to
% the existing singleton*.
%
% FRANCK_GUIDE('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in FRANCK_GUIDE.M with the given input arguments.
%
% FRANCK_GUIDE('Property','Value',...) creates a new FRANCK_GUIDE or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before franck_guide_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to franck_guide_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
% Edit the above text to modify the response to help franck_guide
% Last Modified by GUIDE v2.5 22-Feb-2022 13:54:14
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @franck_guide_OpeningFcn, ...
'gui_OutputFcn', @franck_guide_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 franck_guide is made visible.
function franck_guide_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 franck_guide (see VARARGIN)
% Choose default command line output for franck_guide
handles.output = hObject;
% Plot patch on uiaxes
%hold on
% Read experiment data from a CSV file
load_folder = "C:\Users\student\Desktop\FRANCK\thesis\excel_data\";
load_name = "excel_data.xlsx";
load_addr = load_folder + load_name;
handles.T = readtable(load_addr,'NumHeaderLines',1);
handles.exp_counter = 1;
handles.v_thickness_1 = handles.T.Var1;
handles.v_thickness_2 = handles.T.Var2;
handles.h_thickness_1 = handles.T.Var3;
handles.h_thickness_2 = handles.T.Var4;
handles.amplitude_array = handles.T.Var5;
handles.v_or_h_array = handles.T.Var6;
handles.v_thick1 = handles.v_thickness_1(handles.exp_counter);
handles.v_thick2 = handles.v_thickness_2(handles.exp_counter);
handles.h_thick1 = handles.h_thickness_1(handles.exp_counter);
handles.h_thick2 = handles.h_thickness_2(handles.exp_counter);
handles.v_or_h = handles.v_or_h_array(handles.exp_counter);
handles.region1 = [];
% Create the Arduino serial object
handles.arduinoObj = serialport('COM3', 9600);
configureTerminator(handles.arduinoObj,'CR/LF');
%flush(handles.arduinoObj);
%
for i=1:8
handles.message = readline(handles.arduinoObj);
disp(handles.message)
end
create_patch(handles);
% Update handles structure
%guidata(hObject, handles);
% UIWAIT makes Hapticfinal wait for user response (see UIRESUME)
% uiwait(handles.finger);
function create_patch(handles)
if ishandle(handles.region1)
delete(handles.region1);
end
v_or_h = handles.v_or_h_array(handles.exp_counter);
if v_or_h == 0 % Vertical line
v_thick1 = handles.v_thickness_1(handles.exp_counter);
v_thick2 = handles.v_thickness_2(handles.exp_counter);
handles.region1 = patch( ...
'Parent',handles.axes1, ...
'XData',[v_thick1 v_thick2 v_thick2 v_thick1], ...
'YData',[-10 -10 10 10], ...
'FaceColor','red');
set(handles.axes1,'XLim',[-5 0],'YLim',[-10 10]);
else % Horizontal line
h_thick1 = handles.h_thickness_1(handles.exp_counter);
h_thick2 = handles.h_thickness_2(handles.exp_counter);
handles.region1 = patch( ...
'Parent',handles.axes1, ...
'XData',[-10 10 10 -10], ...
'YData',[h_thick1 h_thick1 h_thick2 h_thick2], ...
'FaceColor','red');
set(handles.axes1,'XLim',[0 5],'XLim',[-10 10]);
end
set(handles.axes1,'XGrid','on','YGrid','on');
axis(handles.axes1,'equal');
% Update handles structure
guidata(handles.finger,handles);
% call the button motion fcn to update the new patch's color:
finger_WindowButtonMotionFcn(handles.finger);
% UIWAIT makes franck_guide wait for user response (see UIRESUME)
% uiwait(handles.finger);
% --- Outputs from this function are returned to the command line.
function varargout = franck_guide_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;
% --- Executes on button press in Start_button.
function Start_button_Callback(hObject, eventdata, handles)
% hObject handle to Start_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.fileID = fopen('exp.txt','w');
handles.t = timer('ExecutionMode', 'fixedRate', ...
'Period', 0.5, ...
'TasksToExecute', Inf, ...
'TimerFcn', {@timerCallback, handles.fileID});
start(handles.t);
set(handles.Start_button,'Enable','off'); % -> Disable the button
guidata(hObject,handles);% -----> do this to save the updated handles object
function timerCallback(~,~,fileID)
fprintf(fileID,'(X, Y, time) = (%g, %g, %s)\n', get(0, 'PointerLocation'), datetime('now'));
fprintf('calling timer callback\n');
% --- Executes on button press in Next_button.
function Next_button_Callback(hObject, eventdata, handles)
% hObject handle to Next_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles = guidata(hObject);
f = msgbox('Operation Completed,3 seconds please.','NEXT');
% Read experiment data from a CSV file
% region1 = patch(axes1,[-10 10 10 -10],[-5 -5 -4.4 -4.4],'r','FaceAlpha',1,...
%'LineWidth',0.01,'LineStyle','-','tag','region1');
handles.exp_counter = handles.exp_counter + 1;
if handles.exp_counter > numel(handles.v_thickness_1)
return
end
% delete the old patch and create a new one:
create_patch(handles);
% --- Executes on button press in Yes_button.
function Yes_button_Callback(hObject, eventdata, handles)
% hObject handle to Yes_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
answer = questdlg('ARE YOU SURE?','Confirm close',...
'OK',@(src,event)mycallback(handles,src,event));
clear
clc
fileID= fopen('exp.txt2','a');
YES = "I FEEL IT";
fprintf (fileID, "%s\n",YES);
fclose(fileID);
% --- Executes on button press in Stop_button.
function Stop_button_Callback(hObject, eventdata, handles)
% hObject handle to Stop_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles = guidata(hObject);
stop(handles.t) %whenever we want to stop.
fclose(handles.fileID);
set(handles.Start_button,'Enable','on'); % -> Enable the button
guidata(hObject,handles);
% --- Executes on button press in No_button.
function No_button_Callback(hObject, eventdata, handles)
% hObject handle to No_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
answer1= questdlg('ARE YOU SURE?','Confirm Close',...
'OK',@(src,event)mycallback(handles,src,event));
clear
clc
fileID= fopen('exp.txt2','a');
NO = "I DON'T FEEL IT";
fprintf (fileID, "%s\n",NO);
fclose(fileID);
% --- Executes on mouse motion over figure - except title and menu.
function finger_WindowButtonMotionFcn(hObject, eventdata, handles)
% hObject handle to finger (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles = guidata(hObject);
pos = get(hObject, 'currentpoint'); % get mouse location on figure
global x;
global y;
x = pos(1);
y = pos(2); % assign locations to x and y
set(handles.xloc, 'string', ['x loc:' num2str(x)]); % update text for x loc
set(handles.yloc, 'string', ['y loc:' num2str(y)]); % update text for y loc
% Determine if mouse is within the region
p_x = get(handles.region1,'XData');
p_x = p_x([1 2]);
p_y = get(handles.region1,'YData');
p_y = p_y([1 3]);
ax_xl = get(handles.axes1,'XLim');
ax_yl = get(handles.axes1,'YLim');
ax_units = get(handles.axes1,'Units');
if ~strcmp(ax_units,'pixels')
set(handles.axes1,'Units','pixels')
end
ax_pos = get(handles.axes1,'Position'); % axes1 position in pixels
if ~strcmp(ax_units,'pixels')
set(handles.axes1,'Units',ax_units);
end
% convert the patch XData and YData from axes coordinates to figure coordinates in pixels
p_x = (p_x-ax_xl(1))/(ax_xl(2)-ax_xl(1))*ax_pos(3)+ax_pos(1);
p_y = (p_y-ax_yl(1))/(ax_yl(2)-ax_yl(1))*ax_pos(4)+ax_pos(2);
if x >= p_x(1) && x <= p_x(2) && y >= p_y(1) && y <= p_y(2)
set(handles.region1,'FaceColor','g');
%run the motors
writeline(handles.arduinoObj, '4&MOTOR_1_2&0!');
drawnow;
else
set(handles.region1,'FaceColor','r');
writeline(handles.arduinoObj, '0&MOTOR_1_2&0!');
drawnow;
end
% Create the Arduino serial object
%handles.arduinoObj = serialport("COM3", 9600);
%configureTerminator(handles.arduinoObj,"CR/LF");
%flush(handles.arduinoObj);
%
%%for i=1:8
%handles.message = readline(handles.arduinoObj);
%disp(handles.message)
%end

30 Comments

This is the test code that it perfectly working.
function varargout = TEST(varargin)
% TEST MATLAB code for TEST.fig
% TEST, by itself, creates a new TEST or raises the existing
% singleton*.
%
% H = TEST returns the handle to a new TEST or the handle to
% the existing singleton*.
%
% TEST('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in TEST.M with the given input arguments.
%
% TEST('Property','Value',...) creates a new TEST or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before TEST_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to TEST_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
% Edit the above text to modify the response to help TEST
% Last Modified by GUIDE v2.5 16-Mar-2022 16:32:55
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @TEST_OpeningFcn, ...
'gui_OutputFcn', @TEST_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 TEST is made visible.
function TEST_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 TEST (see VARARGIN)
% Choose default command line output for TEST
handles.output = hObject;
% Create the Arduino serial object
handles.arduinoObj = serialport('COM3', 9600);
configureTerminator(handles.arduinoObj,'CR/LF');
%flush(handles.arduinoObj);
%
for i=1:8
handles.message = readline(handles.arduinoObj);
disp(handles.message);
end
guidata(hObject,handles);
% UIWAIT makes TEST wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = TEST_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;
% --- Executes on button press in RUN.
function RUN_Callback(hObject, eventdata, handles)
% hObject handle to RUN (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
writeline(handles.arduinoObj, '4&MOTOR_1_2&0!');
% --- Executes on button press in STOP.
function STOP_Callback(hObject, eventdata, handles)
% hObject handle to STOP (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
writeline(handles.arduinoObj, '0&MOTOR_1_2&0!');
@Franck paulin Ludovig pehn Mayo - it may not be possible to get the code to do what you want it to do given the mouse speed as it moves in to and out of the region of interest. You may need to do some tests to see what is happening if you move the mouse slowly which may result in fewer events being sent to the finger_WindowButtonMotionFcn function. At least that is what I thought at first glance of your code...but I only see this function being called from the create_patch function. Perhaps you have assigned it as a callback from within GUIDE?
I think that before you try getting the motors to start and stop, you need to confirm that the code is working as expected and is recognizing when the mouse pointer moves in and out of the patch. For example, if you take your code
if x >= p_x(1) && x <= p_x(2) && y >= p_y(1) && y <= p_y(2)
set(handles.region1,'FaceColor','g');
%run the motors
writeline(handles.arduinoObj, '4&MOTOR_1_2&0!');
drawnow;
else
set(handles.region1,'FaceColor','r');
writeline(handles.arduinoObj, '0&MOTOR_1_2&0!');
drawnow;
end
and replace with
if x >= p_x(1) && x <= p_x(2) && y >= p_y(1) && y <= p_y(2)
set(handles.region1,'FaceColor','g');
fprintf('Trying to run the motors!\n');
else
fprintf('Trying to stop the motors!\n');
end
do you see the correct messages in the console window? If you move the mouse faster (in and out of the area of interest) what happens?
I don't know how long it takes for the Aurduino motors to start and stop. It may be that these actions take longer than you would like and so it might be receiving a command to start before it has completed the task to stop. I don't know.
Is there a way for you to determine the state of the motors i.e. running or stopped or transitioning? What you could do is when your code determines that it should (for example) start the motor, then you disconnect the finger_WindowButtonMotionFcn callback from the figure so that it can't respond to any more motion events. When the state of the Arduino finally changes, then you reconnect the callbac. Just a thought. :shrug
Can you explain what is different between this and your other question?
1)İ have replaced with what you have suggested and it is working perfectly at a certain speed. There is a threshold. İF i am going very fast, the Gui will not see it. İ am going at an acceptable speed and everything is printed in the command window as expected.
2) The only way for me to determine when the motors stop or are running where through color indicators. That is why basically, i have a color indicator that shows me when the cursor is in the region (turns green) and when it is out out of the region (red) and is working at a certain speed threshold. İ have that into consideration. Transitonning not really, i do not have no indicator. BUt concerning the test, the push buttons works instantly.
@Rik Here , there is a test code i have added. i am the lab, tyrying to figure out things. İ want to know why that code is working and the other one is not working. So i may just delete the previous one since this one is more informative.
@Franck paulin Ludovig pehn Mayo - I meant could you query the Arduino to determine whether its motor is running or not? I'm not familiar enough with this to know. I'm not surprised that the push button callbacks work since you just push the button once and there is just the one corresponding event whereas there are multiple events when you move the mouse and so long as you are moving the mouse within the region, your code will always try to start the motors. Maybe you need to ignore all events that try to start (or stop) if you have already tried to start (or stop)?
if x >= p_x(1) && x <= p_x(2) && y >= p_y(1) && y <= p_y(2)
if (strcmpi(get(handles.region1,'FaceColor'), 'g') == 0)
set(handles.region1,'FaceColor','g');
%run the motors
writeline(handles.arduinoObj, '4&MOTOR_1_2&0!');
drawnow;
end
else
if (strcmpi(get(handles.region1,'FaceColor'), 'r') == 0)
set(handles.region1,'FaceColor','r');
writeline(handles.arduinoObj, '0&MOTOR_1_2&0!');
drawnow;
end
end
So in the above, if the region1 'FaceColor' has already been set to 'g', then we know that we don't need to start the motor because it is already running. If the mouse position is outside of the region and the region is already 'r', then we know we don't need to stop the motor as the code has already made that request.
1) Yes, i can easily do that and i have done it and it is working perfectly and instantly. İ just have to paste those command lines in the arduino serial monitor command . They are working accordindly.
2)The cursor is not in the region at the beginning so it should not vibrate. The region in question is just a band area that varies by clickıng on a Next button (width from 1 cm to 5cm).The problem seems to be a GUİ issue.
The problem i thought i may have face in the beginning is that when the mouse goes from the region to out of the region , the motors would have kept vibtating maybe for a while and then stop ... But it is not even the case, the motors are just vibrating and stop vibrating randomly.
@Franck paulin Ludovig pehn Mayo - if you move the mouse slowly in and out of the region, what is the behaviour? i.e. if you move into the region and wait 3-5 seconds before leaving the region, does the motor stop? If so, then you may need to add some sort of waiting period between when the motors start and when they can be stopped. I realize that you may not want to do this, but you may be expecting the software to do someting more than it can do. I think comparing the start/stop buttons with start/stop mouse position is not viable.
@Geoff Hayes yes, i have tried it and it is not working. out of 100 times , it worked maybe just 4 times. The motors are just behaving randomly. And i am even spending like 5 to 10 s inside the region, but no logical response.
I was doing this before in appdesigner but appdesigner was just limited for my project. The problem i was facing with appdesigner concerning this issue, was just the waiting time. I needed to spend at least 1 to 2 seconds inside before leaving the area and at certain speed.
@Franck paulin Ludovig pehn Mayo - without having the same setup as yourself (Arduino, etc.) it is kind of hard to understand why the motor isn't stopping when the call to writeline(handles.arduinoObj, '0&MOTOR_1_2&0!'); is made.
I wonder if instead of using the window position callback, you should just create a timer that polls (every second) for the current mouse position. You would then use that position to determine whether you should start or stop the motors (if needed). This would reduce the number of calls to the WindowButtonMotionFcn (I'm not sure how many time a second this function is called.)
@Geoff Hayes I see i am not familiar with the timer function . What could be an example related to my topic
I saw this
t = timer( ...
'TimerFcn', @(~,~)timertestfunction(x,y), ...
'StartDelay', 5, ...
'ExecutionMode', 'fixedRate', 'Period', 5, ...
'TasksToExecute', 2, 'BusyMode', 'drop', ...
'Name', 'timetestfunction', 'Tag', 'timetestfunction');
@Franck paulin Ludovig pehn Mayo you could try something like the attached GUI which has two buttons to start and stop the timer. The timer initialization looks like
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.t = timer('ExecutionMode', 'fixedRate', ...
'Period', 1.0, ...
'TasksToExecute', Inf, ...
'TimerFcn', {@timerCallback, handles.figure1});
start(handles.t);
guidata(hObject,handles); % <---- do this to save the updated handles object
Note how once the timer t is assigned to the handles structure and that this updated structure is saved with guidata. This is so that other callbacks (like STOP) will have access to the timer and be able to stop it. In the TimerFcn, we pass the handle to the figure/GUI as an input parameter to the timer callback so that it has access to the GUI controls. The timer callback looks like
function timerCallback(hObject, eventdata, hFigure)
% get the handles structure of the GUI
handles = guidata(hFigure);
% get the current mouse position
mousePos = get(0,'PointerLocation');
mouseX = mousePos(1);
mouseY = mousePos(2);
% get the position of the GUI (note how units have been set to pixels)
guiPosition = get(handles.figure1, 'Position');
% check to see if mouse position is within GUI or outside
if mouseX >= guiPosition(1) && mouseX <= (guiPosition(1) + guiPosition(3)) ...
&& mouseY >= guiPosition(2) && mouseY <= (guiPosition(2) + guiPosition(4))
% translate mouse position relative to GUI
mouseXGui = mouseX - guiPosition(1);
mouseYGui = mouseY - guiPosition(2);
fprintf('Mouse position is within GUI at (%f,%f).\n', mouseXGui, mouseYGui);
% sample code that changes colour of GUI start button
startButtonPosition = get(handles.pushbutton1, 'Position');
if mouseXGui >= startButtonPosition(1) && mouseXGui <= (startButtonPosition(1) + startButtonPosition(3)) && ...
mouseYGui >= startButtonPosition(2) && mouseYGui <= (startButtonPosition(2) + startButtonPosition(4))
set(handles.pushbutton1, 'BackgroundColor', 'g');
else
set(handles.pushbutton1, 'BackgroundColor', 'r');
end
else
fprintf('Mouse position is outside of GUI\n');
end
It determines the position of the mouse which is relative to the screen (and not the GUI), It then checks to see if the mouse position is within the GUI. If so, the code then converts this position to one that is relative to the GUI so that you can check for position within an axes or whatever (you will probably need to do some other translating of positon). I included some sample code that changes the colour of the start button depending upon position of mouse. This is for example purposes only and is not relevant to your problem.
Note also that I needed to ensure the units of the GUI and start button were in pixels. I set this in the opening function of the GUI
% <---- Set the figure units to be pixels
set(handles.figure1, 'Units', 'pixels')
set(handles.pushbutton1, 'Units', 'pixels')
@Geoff Hayes hello, i have tried to follow your suggestion but i found that it cannot help me . Because It is an experiment where we are going to blindfold some subjects . The aim is to check if the subject reacts when his/ her finger goes into the area.
when the finger is inside the area, the ring (the finger is attached to a ring with embedded motors) should vibrate. All the experiment is done spontaneously.
If it is indeed a polling rate issue, you could limit that yourself as well:
function callback(hObject,eventdata,handles)
if handles.LimitRateFlag,return,end
handles.LimitRateFlag=true;guidata(hObject,handles)
%rest of your code goes here
handles.LimitRateFlag=false;guidata(hObject,handles)
end
I needed something like this in my WindowLevel function. This way you limit the number of calls your GUI has to process.
@Rik Where should i put it...I am working on guide. Should i initialize sth ?
do i have to write that part in the openingfcn ?
@Franck paulin Ludovig pehn Mayo does the timer suggestion work? I realize that it may not be apporpriate for your experiment but if it does work, and the motors start and stop as expected, then it might give us an idea of what the problem is...
@Geoff Hayes yes , the time function is working perfectly. I am very curious to know what is the issue with my code.
The code I showed should be in your callback function. And yes, you should indeed initialize the flag in the opening function.
@Rik I have tried the code but it is not working. Either , i am using it wrong or it is not suitable. Below is how i used it. I am not getting any error from the control window.However, the region does not longer turns green when the mouse is within the region.
I did not initialize it in the openingfcn since i dont really know more about the function.I know what it does but i dont know how to use. It seems like there no info about it in matlab
function callback(hObject,eventdata,handles)
if handles.LimitRateFlag,return,end
handles.LimitRateFlag=true;
p_x = get(handles.region1,'XData');
p_x = p_x([1 2]);
p_y = get(handles.region1,'YData');
p_y = p_y([1 3]);
ax_xl = get(handles.axes1,'XLim');
ax_yl = get(handles.axes1,'YLim');
ax_units = get(handles.axes1,'Units');
if ~strcmp(ax_units,'pixels')
set(handles.axes1,'Units','pixels')
end
ax_pos = get(handles.axes1,'Position'); % axes1 position in pixels
if ~strcmp(ax_units,'pixels')
set(handles.axes1,'Units',ax_units);
end
% convert the patch XData and YData from axes coordinates to figure coordinates in pixels
p_x = (p_x-ax_xl(1))/(ax_xl(2)-ax_xl(1))*ax_pos(3)+ax_pos(1);
p_y = (p_y-ax_yl(1))/(ax_yl(2)-ax_yl(1))*ax_pos(4)+ax_pos(2);
persistent timein;
if isempty(timein)
timein = datetime('now');
end
if x >= p_x(1) && x <= p_x(2) && y >= p_y(1) && y <= p_y(2)
set(handles.region1,'FaceColor','g');
writeline(handles.arduinoObj, "4&MOTOR_1_2_3_4&0!");
else
set(handles.region1,'FaceColor','r');
writeline(handles.arduinoObj, "0&MOTOR_1_2_3_4&0!");
end
handles.LimitRateFlag=false;
Why are you editing the code I suggested if you don't understand it? Those calls to guidata are vital to this idea working.
Also, can you confirm you didn't edit the actual motion callback function, but inserted this instead? Because you should have received an error about handles.LimitRateFlag not existing.
%put this in your startup function
handles.LimitRateFlag=false;
@Rik unfortunatley, it is not working.
You forgot to tell us what 'it' is, and what constitutes 'not working'.
@Rik the issue i am having now is that even the region does not longer turn green whenever the cursor is inside the region. I am not having any error inside the command window.
Did you undo your deletions from the code I suggested? Did you either edit the callback property in GUIDE to point to callback, or did you put the code I suggested in the motion callback function? Without the addition in the startup function, the LimitRateFlag field doesn't exist. The fact that you didn't see any errors means that the code was not called at all.
@Rik yes, i undid what you suggested me.
2)I put the code you suggested in the windowbuttonmotion callback and i initialize as you suggested to me in the opening function but still no error in the command window. İt has just stopped the specific region from turning green.
Also, after i deleted your code . The region is not even turning green. İ am very confused. I have closed the script and open it agaın nothing. İ did it in two dıfferent computers but same problem. This is crazy. İt does not make sense. How is it possıble that after i deleted your code it does not go back to the previous status:It looks like there is a permanent break between the GUI interface and my code.
Then maybe this is a good time to ditch GUIDE and build the GUI from the ground up. That way you have full control. You can still use GUIDE to sketch out your GUI to get the values of the Position property of your objects.
For general advice and examples for how to create a GUI (and avoid using GUIDE), have look at this thread.
@Rik İ have downloaded the script again from my friend´s email (İ sent him to help me out) it is working now. İ think it has been overwritten.
İ cannot afford to start from scratch again because i did it already. İ was using appdesigner and i was done until i found that appdesigner is limited . İ chatted with matlab workers and it seems like there is no solution yet thats why i am using guide by default. İ was more familiar with appdesigner than guide. İ actually it is the first time i am using guide.
I'm suggesting to use neither AppDesigner nor GUIDE. I have posted advice in the previous comment already. Click that link and read the advice on that page.
Your GUI should only be an interface. It should gather inputs and send that off to other functions. Posting essentially the same question several times is not going to help.
What you need to do:
Create a tiny example. Just a figure with one region. Create this with code only (no fig file). Do not implement the Arduino controls yet, first make sure it responds to your cursor correctly.
Once that works, we can implement a rate limiter.
Once that works, you can implement the calls to your Arduino.
You can also do this with key presses instead of mouse controls, the concept is the same: first make a tiny example. The code to create your GUI should only be a handful of lines.
@Rik I do appreciate your input a lot but unfurtunately i cannot followw that line .Starting all over again a third time, will play against me. I do not have that much time. The gui i am Trying to do have many pushbuttons and also with time i have to add other things depending on how the experiment goes. I am not that too good with matlab . I have tried my best to learn how to use appdesigner and at the end it did not work as i wanted then i went into guide that is giving some small issues while i have completed already 95 of the job.
Since it is a lil hard to answer the previous question that is why i have changed the strategy by using keyboard key in order to run and stop the motors. I can run and stop the motors whenever i want in a test gui (guide). I just want to implement that in my Gui.
You will be able to recycle many of the parts you have already written. It is not the same as going from AppDesigner to GUIDE.
The point is to start with something small where you can see what works and what doesn't. When you're sure one part works, you can add the next part. You don't have to write those parts from scratch, you can copy them from what you currently have.
Re-writing something that doesn't work can be a worthwhile time investment. You can continue spending days on debugging GUIDE, or you can build up your program part by part, where you know what each part does. I strongly encourage you to read the link I gave you. I suspect GUIDE is holding you back. I know it did for me.

Sign in to comment.

Answers (1)

Franck paulin Ludovig pehn Mayo
Moved: Sabin on 11 Jan 2023
@Rik i have solved the issue. The problem was that the communication between arduino and matlab was flooded. To solve it, i have added a ''status_check'' before the cursor enters the area and after it does

Categories

Find more on Update figure-Based Apps in Help Center and File Exchange

Moved:

on 11 Jan 2023

Community Treasure Hunt

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

Start Hunting!