how to control stepper motor speed via USB port
이전 댓글 표시
i really need some help over here..i have connected and run my stepper motor but how come i cannot control the speed of my motor?..can someone give me some hints?
below are my coding:
function text_speed_m1_Callback(hObject, eventdata, handles)
sliderValue = get(handles.text_speed_m1,'String');
%convert from string to number if possible, otherwise returns empty
sliderValue = str2nm(sliderValue);
%if user inputs something is not a number, or if the input is less than 0
%or greater than 100, then the slider value defaults to 0
if (isempty(sliderValue) || sliderValue < 0 || sliderValue > 256)
set(handles.slider_speed_m1,'Value',0);
set(handles.text_speed_m1,'String','0');
else
set(handles.slider_speed_m1,'Value',sliderValue);
end
% --- Executes during object creation, after setting all properties.
function text_speed_m1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on slider movement.
function slider_speed_m1_Callback(hObject, eventdata, handles)
sliderValue = get(handles.slider_speed_m1,'Value');
%puts the slider value into the edit text component
set(handles.text_speed_m1,'String', num2str(sliderValue));
% Update handles structure
guidata(hObject, handles);
% --- Executes on button press in pushbutton_speed_m1.
function pushbutton_speed_m1_Callback(hObject, eventdata, handles)
obj1 = instrfind('Type','serial','Port','COM8','Tag','');
if isempty(obj1)
obj1 = serial('COM8');
else
fclose(obj1);
obj1 = obj1(1)
end
fopen(obj1);
sv2 = get(handles.text_speed_m1,'String');
fprintf(obj1,'%s','rs')
fprintf(obj1,int2str(get(hObject,'Value')));
please give me some hints on what i do wrong..really need help now..thanks
댓글 수: 1
Walter Roberson
2011년 3월 27일
Please reformat your code to be more readable. If you go in to the editor and select the code and press the '{} Code' button then it will be reformatted.
Please also check that the code output is what you wanted. For example one of your lines shows up as "if (isempty(sliderValue) sliderValue < 0 sliderValue > 256)" which is invalid syntax. I suspect that you had or-bar there but that your or-bar was interpreted by the forum as formatting instructions.
채택된 답변
추가 답변 (17개)
fremond khoo
2011년 3월 27일
댓글 수: 6
Walter Roberson
2011년 3월 27일
Ummm, so you don't have a COM8. Is it a USB based port? If so, then you have to have it connected _before_ you start Matlab.
I am not sure why you are restricting your instrfind to the case where the Tag is the empty string? If you are not using the Tag for some purpose then it just confuses the readers. If you _are_ using the Tag for some purpose, then a comment in the code would be appreciated.
fremond khoo
2011년 3월 27일
Walter Roberson
2011년 3월 27일
The obvious thing to try is to close matlab and start it up again, and then without executing anything else, command,
obj1 = instrfind('Type','serial','Port','COM8')
If it cannot find COM8 then you know it isn't a problem with the rest of your code.
fremond khoo
2011년 3월 27일
fremond khoo
2011년 3월 28일
Walter Roberson
2011년 3월 28일
Doesn't this case correspond to you closing the existing port and opening it again? Or did you remove that code?
fremond khoo
2011년 3월 29일
댓글 수: 3
Walter Roberson
2011년 3월 29일
That code seems highly unlikely to work, but here is the code you would need to change:
b = dec2bin(sv2,8);
c = reshape([a;b] .', 1, []);
I would be startled fwrite(obj1,c,'int16') produces the result you are hoping for. Please re-check to see whether your senior had a bin2dec() call after c was created. Please also recheck to see if your senior converted a 10 (linefeed) or 13 (carriage return)
Your senior's code seems to be created with the idea that you send 'S' followed by a _single_ character to indicate the speed, except that the code doesn't actually do that.
Are you aware that in your original code, you do not send any value derived from the slider after the 'S'? You carefully build "val" but do not sent it to the COM port.
Please cross-check exactly what format of numbers the motor control expects. I do not see anything in your code that would restrict val to being an integer. With the range of values you are restricting to, and the code your senior provides, I wonder whether what the motor control is expecting is 'S' followed by a single byte whose decimal equivalent is the number of 1/255 of full speed -- e.g., byte value 0 for stop, byte value 128 for half speed, byte value 255 for full speed. If so then your senior's code starts to hint at some sense (but would still not be correct in the form posted.)
fremond khoo
2011년 3월 31일
Walter Roberson
2011년 3월 31일
Is there a reference document that discusses the command format expected by the motor?
fremond khoo
2011년 3월 31일
댓글 수: 4
Walter Roberson
2011년 3월 31일
fwrite(obj1, [uint8('S') uint8(str2num(sv2))], '*uint8');
Or you might need 'uint8' instead of '*uint8'
Note that with this formula, the string sv2 that you get, the slider value, will be clamped to 0 if it is below 0 and will be clamped to 255 if it is above 255. You should arrange your slider to have a top value of 255.
fremond khoo
2011년 4월 1일
fremond khoo
2011년 4월 1일
Walter Roberson
2011년 4월 1일
It was through experience, Fremond. Without looking it up, I could see that CByte was obviously a "convert to byte" call, and the matlab equivalent of converting to byte is uint8()
fremond khoo
2011년 4월 2일
댓글 수: 5
Walter Roberson
2011년 4월 2일
It isn't obvious to me what "tracking" does for you, but according to that code, it takes as input a 16 bit integer (0 to 65535) and has no output.
tval16 = uint16(Tval);
tval16H = tval16 / 256;
tval16L = tval16 - tval16H * 256;
fwrite(s, [uint8('T') uint8(tval16H) uint8(tval16L)])
fremond khoo
2011년 4월 3일
Walter Roberson
2011년 4월 3일
No, after you have obtained t1,
tval16 = uint16(t1);
tval16H = tval16 / 256;
tval16L = tval16 - tval16H * 256;
fwrite(obj1, [uint8('T'), uint8(tval16H), uint8(tval16L)])
In particular uint8(t1) is _not_ right for extracting the top 16 bits from t1: uint8(t1) when t1 is more than 255 would result in the 8 bit value 255.
fremond khoo
2011년 4월 4일
Walter Roberson
2011년 4월 7일
In the above,
t1 = num2str(get(handles.text_track_m1,'String'));
should instead be
t1 = str2num(get(handles.text_track_m1,'String'));
or one of its equivalents. str2double() is better than str2num()
fremond khoo
2011년 4월 6일
댓글 수: 3
Walter Roberson
2011년 4월 6일
stepfactors = [1 2 5 10];
t1 = get(handles.WHATEVER, 'String');
[tf, idx] = strcmp(t1, {'None (1 / 1)', '1 / 2', '1 / 5', '1 / 10'});
if tf
stepfactor = stepfactors(idx);
fwrite(obj1, [uint8('M') uint8(stepfactor)];
else
%warn about the text not being what was expected
end
This code gets even easier if the text such as 'None (1 / 1)' are the entries for a listbox: in such a case, just get the 'Value' parameter from the handle, and as long as it is non-zero, it will be the index into the stepfactors array.
fremond khoo
2011년 4월 7일
Walter Roberson
2011년 4월 7일
Sorry, I misused strcmp. I should have written
tf = strcmp(t1, {'None (1 / 1)', '1 / 2', '1 / 5', '1 / 10'});
if any(tf)
stepfactor = stepfactors(idx);
fwrite(obj1, [uint8('M') uint8(stepfactor)];
else
%warn about the text not being what was expected
end
With a listbox, you would use this as the body of the callback:
stepfactors = [1 2 5 10];
idx = get(hObject,'Value');
if ~isempty(idx)
stepfactor = stepfactors(idx);
fwrite(obj1, [uint8('M') uint8(stepfactor)];
end
fremond khoo
2011년 4월 7일
댓글 수: 5
Walter Roberson
2011년 4월 7일
See above, I gave you the wrong information about strcmp.
Beyond that, though, remember that the String property of a listbox is all of the configured entries for the list, not the one that is currently selected. The index of the one that is currently selected can be retrieved by getting the Value property. If you happen to want the string that corresponded to that, you can get the String property and index that by the Value; a lot of the time, though, it is better to use just the value to make it easier to change the wording of the strings (e.g., if you wanted to translate to a different language.)
fremond khoo
2011년 4월 7일
Walter Roberson
2011년 4월 7일
I don't see any reason why you couldn't send Track commands to two different ports.
fremond khoo
2011년 4월 7일
fremond khoo
2011년 4월 7일
fremond khoo
2011년 4월 7일
댓글 수: 3
Walter Roberson
2011년 4월 7일
fwrite(obj1,uint8('E'));
t = fread(obj1,2,'uint8');
output = uint16(t(1)) * 256 + uint16(t(2));
A literal translation of the original code would require using char(output) instead of output as a 16 bit integer, but I suspect that the numeric form is what you want.
fremond khoo
2011년 4월 7일
Walter Roberson
2011년 4월 7일
The 2 means to read two items; each item will be of type uint8.
fremond khoo
2011년 4월 7일
댓글 수: 4
Walter Roberson
2011년 4월 7일
You missed the str2num() or str2double() around t2
t2 = str2double(get(handles.text_track_m2,'String'));
Anything that needs to be displayed as text to the user needs to be converted to a numeric value with str2double() or str2num() or sscanf() or textscan() before it can be used for computation.
fremond khoo
2011년 4월 8일
Walter Roberson
2011년 4월 8일
Insufficient information. No correspondence has been documented between angles and the values sent for the 'T' command.
fremond khoo
2011년 4월 8일
fremond khoo
2011년 4월 8일
댓글 수: 6
Walter Roberson
2011년 4월 8일
I don't see anything obviously wrong with that, but I continue to say that it is a distinct tactical error to keep opening and closing the com ports: that you should open the ports once and keep them open unless some error is encountered that forces a re-open.
fremond khoo
2011년 4월 9일
Walter Roberson
2011년 4월 9일
t(1) is a uint8, which is an unsigned 8 bit integer. Multiplying an integer by 256 has the same effect as shifting the binary representation of the integer left by 8 bits, like (highbyte << 8) in C. Adding the 8-bit integer t(2) to the multiplied number then effectively puts t(2) in as the low-order 8 bits of the 16 bit number. The uint16() calls are there because in MATLAB when you do arithmetic operations on an 8 bit number, you get an 8 bit number out as a result but we need a 16 bit number as the result.
fremond khoo
2011년 4월 10일
Walter Roberson
2011년 4월 10일
There are some suggestions about learning MATLAB in a previous Question, http://www.mathworks.com/matlabcentral/answers/1148-how-to-learn-matlab
It would be fairly difficult these days to get the same kind of experience that I got -- I've been programming for 35 years, from the days when I was the only person in my class who could afford to buy a computer that could fit as many as 99 instructions...
fremond khoo
2011년 4월 10일
fremond khoo
2011년 4월 11일
댓글 수: 8
Walter Roberson
2011년 4월 11일
For the other buttons, you should probably use find_and_open() as well.
fremond khoo
2011년 4월 11일
fremond khoo
2011년 4월 11일
Walter Roberson
2011년 4월 11일
I suspect that if you put disp() in to appropriate places in find_and_open() that you will discover that opening only once at the beginning is enough. Still, there is always the possibility of the port getting closed somehow, so it's worth testing a while first.
fremond khoo
2011년 4월 11일
Walter Roberson
2011년 4월 11일
I don't have any particular ideas. At that point, what does get(obj2) say about the object properties?
fremond khoo
2011년 4월 11일
Walter Roberson
2011년 4월 11일
Put that fprintf() statement in a try/catch block, and when the exception occurs, display the output of get(obj2) in order to see what the internal status of the object was.
fremond khoo
2011년 4월 12일
댓글 수: 5
Walter Roberson
2011년 4월 12일
That looks okay.
fremond khoo
2011년 4월 12일
Walter Roberson
2011년 4월 12일
obj2=find_and_open('COM9',9600)
try
fprintf(obj2,'%s\n','O');
catch
disp('It blew up real good!')
get(obj2) %no semi-colon
end
fremond khoo
2011년 4월 12일
Walter Roberson
2011년 4월 12일
Where you have the
t = fread(obj2, 2, 'uint8');
change that to
[t,count,msg] = fread(obj2, 2, 'uint8');
if count < 2
if ischar(msg)
fprintf(1,'request_m2 obj2 read returned only %d bytes, saying that %s\n', count, msg);
else
fprintf(1,'request_m2 obj2 read returned only %d bytes for an unknown reason);
end
return
end
fremond khoo
2011년 4월 12일
댓글 수: 1
Walter Roberson
2011년 4월 12일
Change the find_and_open function as follows and try again:
function obj=ODF_plot(port,wantbaud)
needed_open = true;
obj = instrfind('Type','serial','Port',port);
if isempty(obj);
fprintf(1,'find_and_open: note that instrfind did not find port %s\n', port);
obj = serial(port);
end
curspeed = get(obj,'BaudRate');
if curspeed ~= wantbaud
if strcmpi(get(obj,'Status'),'open');
fclose(obj);
needed_open = false;
fprintf(1,'find_and_open: note that port %s was already open but had the wrong speed, %d\n', port, curspeed)
end
set(obj,'BaudRate',wantbaud);
end
curmode = get(obj,'BytesAvailabelFcnMode');
if ~strcmpi(curmode, 'byte')
if strcmpi(get(obj,'Status'),'open');
fclose(obj);
needed_open = false;
fprintf(1,'find_and_open: note that port %s was already open but had the wrong mode, %s\n', port, curmode)
end
set(obj,'BytesAvailabelFcnMode', 'byte');
end
if ~strcmpi(get(obj,'Status'),'open');
fopen(obj);
if needed_open
fprintf(1,'find_and_open: needed to open port %s\n', port);
end
end
fremond khoo
2011년 4월 12일
댓글 수: 1
Walter Roberson
2011년 4월 12일
Sorry, where I wrote ODF_plot change that to find_and_open .
fremond khoo
2011년 4월 13일
댓글 수: 5
Walter Roberson
2011년 4월 13일
Typo, should have been BytesAvailableFcnMode
fremond khoo
2011년 4월 13일
Walter Roberson
2011년 4월 13일
No, t is a local variable, not a function, and the value in one routine would not affect the value in another.
Did you not make the parallel change to the one I indicated earlier?
=== begin quote ===
Where you have the
t = fread(obj2, 2, 'uint8');
change that to
[t,count,msg] = fread(obj2, 2, 'uint8');
if count < 2
if ischar(msg)
fprintf(1,'request_m2 obj2 read returned only %d bytes, saying that %s\n', count, msg);
else
fprintf(1,'request_m2 obj2 read returned only %d bytes for an unknown reason);
end
return
end
=== end quote ===
Do the same thing for request_m1_Callback except changing 2 to 1 for the object number and warning messages.
fremond khoo
2011년 4월 14일
fremond khoo
2011년 4월 15일
keycamel villegas
2011년 4월 16일
0 개 추천
hi fremond khoo..did you used a motor driver for your stepper motor?and may i know what are the connections?thank you!!.. im a newbie in matlab..and my thesis project involves the movement of a bipolar stepper motor. :)
keycamel villegas
2011년 4월 19일
0 개 추천
my project involves a bipolar stepper motor and im using L298 motor driver..would it be possible that your code above can be used in our project?
댓글 수: 2
fremond khoo
2011년 4월 19일
keycamel villegas
2011년 4월 19일
our professor said that our connection would be:
RS232 to serial to parallel converter(using 4 bit shift register) to l298 motor driver connected to bipolar stepper motor,,
would that be possible?or can you suggest other connection for our bipolar stepper motor because i have difficulty analyzing the connections of this components,,
by the way THANK YOU for your reply :)
keycamel villegas
2011년 4월 19일
0 개 추천
our professor said that our connection would be:
RS232 to serial to parallel converter(using 4 bit shift register) to l298 motor driver connected to bipolar stepper motor,,
would that be possible?or can you suggest other connection for our bipolar stepper motor because i have difficulty analyzing the connections of this components,,
by the way THANK YOU for your reply :)
댓글 수: 6
fremond khoo
2011년 4월 19일
keycamel villegas
2011년 4월 19일
RS232 is a usb to serial connector then it will be connected to a serial to parallel converter(using 4 bit shift register) and it will be connected to a L298 motor driver, connected to a bipolar stepper motor.
sorry for many questions im asking...it just that im a newbie in matlab..thanks for the effort answering my problems
Our goal is: Matlab controlling stepper motor
Walter Roberson
2011년 4월 19일
Please take this to a new Question, "keycamel": this one is already long enough to make it difficult to find useful information in.
fremond khoo
2011년 4월 20일
keycamel villegas
2011년 5월 6일
can i asked you a question? how uart of a microcontroller communicate with the uart of matlab?.thank you
Walter Roberson
2011년 5월 6일
The program running on the microcontroller uses system-specific methods to cause the microcontroller's UART to send the bytes out.
Please start a new question for these kinds of topics; this question is very long and difficult to follow.
커뮤니티
더 많은 답변 보기: Power Electronics Community
카테고리
도움말 센터 및 File Exchange에서 Image Preview and Device Configuration에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!