Undefined function 'writePosition' for input arguments of type 'double'.

Hi,guys. I used arduino support from mathworks and I face some problems when I tried to apply codes to instruct matlab to rotate angle. Below is part my code:
%convert the delay s into degrees ang
ang=round((s+128).*179/256);
%rotate angle ang
writePosition(s, ang);pause(0.01);c;
Once I run this code, I keep got error stated:
Undefined function 'writePosition' for input arguments of type 'double'.
Do you have any idea how to solve this error?Thanks for your response:)

댓글 수: 2

In your code what is s that you are using for ang?
Does this code work for you? It should continuously rotate the servo between 0 and 180 degrees. If the servo shakes its just trying to go too far past 0 or 180 degrees. This number can be between 0 and 1 and is slightly different for different motors. For my servo 0 degrees is about 0.06 and 180 degrees is about 0.98 and the servo will shake if I go pas that number
%Create an Arduino object
a = arduino('com3','uno','libraries','Servo');
%Attach a servo motor to pin 9
s = servo(a,9)
while(2>1)
%Move servo to 0 degrees
writePosition(s, 0.06)
pause(1)
%Move servo to 180 degrees
writePosition(s, 0.98)
pause(1)
end
Hi,Nick.Thanks for your response. Im really appreciate it. Actually, my project is an automatic rotating camera in conference room. I used 2 microphones to generate the sound source. Then, I applied delay to determine which mic produced sound first. So, the camera will rotate to the incoming sound source. Below is some codes :
delay2=fs/2-b3; %delay is half of sampling frequency minus b3(maximum value for c), in samples
s=delay2;
if s<-127 %round values to outside degree parameters to furthest degree value left or right (to maintain 180 degree range)
s=-127;
elseif s>127
s=127;
end
%convert the delay s into degrees ang
ang=round((s+128).*179/256);
writePosition(s, ang);
pause(0.01);c;
But, the problem is I keep getting error for writePosition(s,ang). Thanks for your response.

댓글을 달려면 로그인하십시오.

답변 (1개)

Guillaume
Guillaume 2017년 4월 13일
Clearly, s is supposed to be a variable referencing the object doing the rotation, in Nick's example a servomotor. It's certainly not supposed to be a numeric value.
A piece of advice: rather than using only one letter to name your variable, which don't mean anything to anybody, use full words that actually indicates what's in the variable. Rather than naming your delay s (or delay2, and why give it two names?), why not name it simply delay? (and rather than ang use angle or even better angledegree). It makes the code immediately clearer and it makes it less likely that you'd reuse variable names inadvertently.
arduinoref = arduino('com3','uno','libraries','Servo');
servoref = servo(a,9)
delay = samplingfrequency / 2 - SomethingBadlyNamedSoWeDontKnowWhatItIs
delay = max(min(delay, 127), -127); %restrict delay to [-127, 127]
angledegree = round((delay + 128) * 179/256);
writeposition(servoref, angledegree);

댓글 수: 6

Hi,Guillaume. Thanks a lot for your response. Actually I did not give full codes. As for
delay2=fs/2-b3
Actually b3 is maximum values for cross correlation. Also thanks for your suggestion for naming the variable to a well-known name. I tried to correct my code following your instructions but the error for writeposition keep appeared. Below is the full code of my project:
%Sound Source Localization using Cross Correlation
%2016/2017
%Details:
%1.Able to detect live audio signals come from two microphones
%2.Using perceived delay of incoming audio signals between pair of
%microphone to detect the direction of incoming sound source localization
%Matlab will process the signal of incoming sound and then give command to
%servo motor using arduino to rotate the camera towards perceived source.
%Equipments:
%Arduino UNO
%5V rotational servo motor (HS422) 180 degree range
%webcam attached to servomotor
%two omnidirectional microphones
%Notes:
%Interface to Arduino to works with motorsrv and Add AFMotor.cpp and
%AFMotor.h to path: .....Arduino\libraries\Servo
if ~isempty(instrfind)
fclose(instrfind);
delete(instrfind);
end
%connect to the board
a=arduino('COM3');
%define pin#4 as output and attach motor to it
a.configureDigitalPin(4,'output');
%Attach servo#2 to Pin#4
servo_motor = servo(a,2);
%Reset Servo to Center
writePosition(a,servo_motor);
%define audio settings
%sampling frequency
fs=48000;
%resolution(bits)
nbits=16;
%no. of channels
ch=2;
%each 'extraction" length in sec
t=0.5;
%signal power threshold
th=1200;
%window threshold size
win=200;
%define the audio object
recObj=audiorecorder(fs,nbits,ch); %begin recording
get(recObj) %collect/display values as they are recorded
disp '***BEGINNING ACQUISITION***' %status message
for k=1:2000
%acquire the audio signal
recordblocking(recObj,t); %record w/o on the fly
control until recording is stopped
%store data in double-precision array
x=getaudiodata(recObj,'int16'); %signed integers mapped to
set parameters (anything outside will be "rounded")
%find absolute value of incoming signal
xa=abs(x);
%extract L and R channels
L=double(x(:,1));
R=double(x(:,2));
%query for maximum values during sampling "window"
[ k max(L) max(R)];
%set power threshold
if max(L)>th && max(R)>th
if xa(k:k+win)<win %set rise time threshold
%Plot the waveform (grid on,tight to L/R)
subplot(211),plot(L,'r'),grid on
axis([0 length(L) -2^15 2^15])
subplot(212),plot(R,'g'),grid on
axis([0 length(R) -2^15 2^15])
disp '***DATA COLLECTED***' %status message
%cross-correlation between vectors(automatically adjusts
for
%length differences),returns a "lag vector"
[c,lags]=xcorr(L,R);
%fs/time of max values
[a1,b1]=max(L);
[a2,b2]=max(R);
[a3,b3]=max(c); %define c's maximum values as a3,b3
delay=fs/2-b3; %delay is half of sampling frequency minus b3(maximum value for c), in samples
delay = max(min(delay, 127), -127); %restrict delay to [-127, 127]
%convert the delay s into degrees ang
angledegree = round((delay + 128) * 179/256);
writePosition(servo_motor, angledegree);
pause(0.01);c;
end
end
end
delete(a)
Unfortunately, the error on writeposition keep appeared. Thanks a lot for your help.
*I did not intend to give the full codes. But I really have no idea on how to solve this error. It keeps appeared the same error on writeposition.
Does the servo rotate when you manually input numbers in the command line? writePosition(servo_motor, 0) writePosition(servo_motor,1)
yup. theres no problem with servo motor. It able to rotate when I manually put values in it.
Looking at your code quickly I see two issues. The first is
%Attach servo#2 to Pin#4
servo_motor = servo(a,2);
%Reset Servo to Center
writePosition(a,servo_motor);
Here you are not giving an angle, you are passing an arduino object then a servo object.
%Reset servo to the middle
writePosition(servo_motor,0.5)
The other issues is that near the bottom it looks like you are restricting your angle degree from 1-178 degrees. The writePosition in Matlab requires an argument between 0 and 1. This means that 0 degrees = 0, 90 degrees = 0.5 and 180 = 1. So that will need to get modified to be between 0 and 1
delay = max(min(delay, 127), -127);
angledegree = round((delay + 128) * 179/256);
writePosition(servo_motor, angledegree);
Hi,Nick. Thanks a lot for the answer. You gave a good explanation that i can easily understand. Once I edited my code, I get result
a =
arduino with properties:
Port: 'COM3'
Board: 'Uno'
AvailableAnalogPins: [0, 1, 2, 3, 4, 5]
AvailableDigitalPins: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Libraries: {'I2C', 'SPI', 'Servo'}
SampleRate: 48000
BitsPerSample: 16
NumberOfChannels: 2
DeviceID: -1
CurrentSample: 1
TotalSamples: 0
Running: 'off'
StartFcn: []
StopFcn: []
TimerFcn: []
TimerPeriod: 0.0500
Tag: ''
UserData: []
Type: 'audiorecorder'
*BEGINNING ACQUISITION***
ans =
1 17885 17886
*DATA COLLECTED***
delay =
0
angle =
90
Error using SS (line 113) Invalid position value. The value must be in the range 0 and 1.
As what I can understand,this system cannot calculate the delay, therefore there's error at line 113 for writeposition(servo_motor,angledegree). As stated
ans =
1 17885 17886
It only detect 'a' part of my microphone, in this case I stated a1,b1 & a2,b2 for my both microphone. Did you have any idea on how can i resolve this problem? Just for additional information, I applied cross correlation algorithm.
P/s: As you stated, I need to gave argument 0,0.5,1 . But I cannot since the value is calculated by delay and angledegree.
can you just map the angle you are getting to a value between 0 and 1? I'm not sure if matlab has a built-in function to do this but it would be easy enough to write. This is from Arduino here at the bottom of the page
in_min = 0
in_max = 180
out_min = 0
out_max = 1
new_angle = (angle-in_min) * (out_max - out_min)/(in_max-in_min) + out_min
writePosition(servo_motor, new_angle);

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Audio I/O and Waveform Generation에 대해 자세히 알아보기

질문:

2017년 4월 12일

댓글:

2017년 4월 21일

Community Treasure Hunt

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

Start Hunting!

Translated by