Page 1 of 1

Running two servos on 1061 board ("Advanced Servo")

Posted: Wed Aug 31, 2016 2:01 pm
by onnimikki
Hi,

I'm trying to run two servo motors on the 1061 Advanced Servo board. By using the demo code for MATLAB I can either get the first servo (using an index value of 0) or the second servo (using an index value of 1) to work okay.

The problem becomes when I try to run them both. I basically duplicated portions of the sample code from the Phidgets page (two versions of the servo setup, two versions of the servo execution and two versions of the disengagement of the servo). If I run this code the servo on Index 0 seems to do fine, but the servo on Index 1 doesn't move like it should.

However, if I comment out the code for servo 0, and run it, then servo 1 runs as expected. Likewise, when I comment out the code for servo 1, and run it, then servo 0 runs as expected.

If I could get some hints as to how I should run two servos at once, that would be helpful.

Below is the code that I'm using

Code: Select all

function TempServo

% Define the index for two different servos on the Adv. Servo Board.
motor0_index = 0;   % pan
motor1_index = 1;   % tilt

% Load the phidgets software library
loadphidget21;
 
% Create a software link to the library
handle_servo_brd = libpointer('int32Ptr');
calllib('phidget21', 'CPhidgetAdvancedServo_create', handle_servo_brd );
calllib('phidget21', 'CPhidget_open', handle_servo_brd , -1);

valPtr0 = libpointer('doublePtr', 0);  % for servo 0 (pan)
valPtr1 = libpointer('doublePtr', 0);  % for servo 1 (tilt)

% If a connection to the USB servo device can be established, run the servo
if calllib('phidget21', 'CPhidget_waitForAttachment', handle_servo_brd , 2500) == 0
    disp('Opened Advanced Servo')
   
    % Define a timer.
    t = timer('TimerFcn','disp(''moving servo...'')', 'StartDelay', 1.0);
   
    % Initialize the movement period & the position angle.
    n=0;
    posn0=0;  % for servo 0 (pan)
    posn1=0;  % for servo 1 (tilt)
   
    % Start the timer (MATLAB timer)
    start(t);
    wait(t);
   
    % ------------------------------------------
    % Set up Motor 0.
    % ------------------------------------------
    % Step 1
    calllib('phidget21', 'CPhidgetAdvancedServo_getVelocityMax', handle_servo_brd , motor0_index, valPtr0);
    maxVelocity0 = get(valPtr0, 'Value');
    % Step 2
    calllib('phidget21', 'CPhidgetAdvancedServo_getAccelerationMax', handle_servo_brd , motor0_index, valPtr0);
    maxAccel0 = get(valPtr0, 'Value');
    % STep 3
    calllib('phidget21', 'CPhidgetAdvancedServo_getPositionMax', handle_servo_brd , motor0_index, valPtr0);
    maxPosn0 = valPtr0.Value;
    % Step 4
    calllib('phidget21', 'CPhidgetAdvancedServo_setAcceleration', handle_servo_brd , motor0_index, maxAccel0);
    calllib('phidget21', 'CPhidgetAdvancedServo_setVelocityLimit', handle_servo_brd , motor0_index, maxVelocity0);
    % STep 5: engage Motor 0
    calllib('phidget21', 'CPhidgetAdvancedServo_setEngaged', handle_servo_brd , motor0_index, 1);

   
    % ------------------------------------------
    % Set up Motor 1.
    % ------------------------------------------
    % Step 1
    calllib('phidget21', 'CPhidgetAdvancedServo_getVelocityMax', handle_servo_brd , motor1_index, valPtr1);
    maxVelocity1 = get(valPtr1, 'Value');
    % Step 2
    calllib('phidget21', 'CPhidgetAdvancedServo_getAccelerationMax', handle_servo_brd , motor1_index, valPtr1);
    maxAccel1 = get(valPtr1, 'Value');
    % STep 3
    calllib('phidget21', 'CPhidgetAdvancedServo_getPositionMax', handle_servo_brd , motor1_index, valPtr1);
    maxPosn1 = valPtr1.Value;
    % Step 4
    calllib('phidget21', 'CPhidgetAdvancedServo_setAcceleration', handle_servo_brd , motor1_index, maxAccel1);
    calllib('phidget21', 'CPhidgetAdvancedServo_setVelocityLimit', handle_servo_brd , motor1_index, maxVelocity1);
    % STep 5: engage Motor 1
    calllib('phidget21', 'CPhidgetAdvancedServo_setEngaged', handle_servo_brd , motor1_index, 1);

    % ----------------------------------------------
    % Make Servo 0 (pan) move a few times   
    % ----------------------------------------------
    % This will move back-and-forth n/2 times. (5)
    while n<10
        start(t);
        wait(t);
        calllib('phidget21', 'CPhidgetAdvancedServo_setPosition', handle_servo_brd , motor0_index, posn0);
        n=n+1;
        if posn0 == 0
            posn0 = maxPosn0;
        else
            posn0 = 0;
        end
    end

     disp('Servo 0 is done.... do Servo 1');
   
     % ----------------------------------------------
    % Make Servo 1 (tilt) move a few times
    % -----------------------------------------------
    % This will move back-and-forth n/2 times. (3)
    while n<6
        start(t);
        wait(t);
        calllib('phidget21', 'CPhidgetAdvancedServo_setPosition', handle_servo_brd , motor1_index, posn1);
        n=n+1;
        if posn1 == 0
            posn1 = maxPosn1;
        else
            posn1 = 0;
        end
    end

    % ------------------------
    % Disengage servo 0
    % ------------------------
    % Move the servo 0 to the "home" position (0) and disengage it (engage state = 0)
    calllib('phidget21', 'CPhidgetAdvancedServo_setPosition', handle_servo_brd , motor0_index, 0);
    calllib('phidget21', 'CPhidgetAdvancedServo_setEngaged', handle_servo_brd , motor0_index, 0);
    % The servo is now disengaged.
   
    disp('Servo 0 is disengaged')

    % ----------------------------
    % Disengage servo 1
    % ----------------------------
    % Move the servo 1 to the "home" position (0) and disengage it (engage state = 0)
    calllib('phidget21', 'CPhidgetAdvancedServo_setPosition', handle_servo_brd , motor1_index, 0);
    calllib('phidget21', 'CPhidgetAdvancedServo_setEngaged', handle_servo_brd , motor1_index, 0);
    % The servo is now disengaged.
    disp('Servo 1 is disengaged');

else  % If the USB connection failed, then tell the user.
    disp('Could not open advanced servo')
end
% Close out the handle to the servo board.
calllib('phidget21', 'CPhidget_close', handle_servo_brd );
calllib('phidget21', 'CPhidget_delete', handle_servo_brd );



In case it matters, I'm running MATLAB on a Linux virtual machine, hosted on Windows 10.

thanks!

James

Re: Running two servos on 1061 board ("Advanced Servo")

Posted: Wed Aug 31, 2016 2:59 pm
by mparadis
When you say the servo doesn't move like it should, do you mean it's moving, but not at the position/speed you intended, or that it's not moving at all?

Re: Running two servos on 1061 board ("Advanced Servo")

Posted: Wed Aug 31, 2016 7:18 pm
by onnimikki
mparadis wrote:When you say the servo doesn't move like it should, do you mean it's moving, but not at the position/speed you intended, or that it's not moving at all?


Hi,

that's the strange thing. I'm expecting to see the Servo 0 move a few times, stop, then have Servo 1 move a few times. Instead, I see Servo 1 move once, then Servo 0 moves a few times (like it should), then Servo 1 moves slightly. It's weird.

James

Re: Running two servos on 1061 board ("Advanced Servo")

Posted: Fri Sep 02, 2016 7:23 am
by mparadis
I don't see anything wrong as far as the Phidgets code is concerned. The problem is either in the way MATLAB handles sequencing or in the way the servos are powered. You could rule out the latter by writing a similar program in C or java. Is there some command in MATLAB that forces the program to finish executing instructions before continuing? I know the loop should theoretically enforce this, but there's no other explanation for why the servos are moving out of turn.

Re: Running two servos on 1061 board ("Advanced Servo")

Posted: Fri Sep 02, 2016 7:48 am
by onnimikki
mparadis wrote:I don't see anything wrong as far as the Phidgets code is concerned. The problem is either in the way MATLAB handles sequencing or in the way the servos are powered. You could rule out the latter by writing a similar program in C or java. Is there some command in MATLAB that forces the program to finish executing instructions before continuing? I know the loop should theoretically enforce this, but there's no other explanation for why the servos are moving out of turn.


I'll try writing something outside of Matlab (maybe python since I've been writing code for the RFID module with Python), will try it on a different machine to see if it's a virtual machine hosting problem. I'm also trying out the 8/8/8 I/O board in MATLAB, switching between I/O channels... that's working so far... will see if there is a slight difference between the way I'm handling the code in both cases.

thanks!

James

Re: Running two servos on 1061 board ("Advanced Servo")

Posted: Fri Sep 02, 2016 8:43 am
by Patrick
Looks like you're not resetting n to 0, so the second while loop never runs.

-Patrick

Re: Running two servos on 1061 board ("Advanced Servo")

Posted: Wed Sep 07, 2016 9:07 am
by onnimikki
Patrick wrote:Looks like you're not resetting n to 0, so the second while loop never runs.

-Patrick


doh. Amateur mistake. Thanks! Tested and it works properly.

James