Wixel pwm to control servo

I am using a wixel to control a Futaba S3114 servo. I have the following code, based on the test_servos app, “working” but not as I would expect. It does move the servo from side to side through about 90 degrees.

However, there are 2 problems:

  1. when I change the 2nd call to servoSetTarget(5, 1000) - or use any other target value - the servo still moves the same 90 degrees. I would expect it to not move at all with both calls to servoSetTarget set at 1000.

  2. I wanted to use pins[1] or (P0_3) to trigger a cycle of the back and forth movement but when I short P0_3 to ground nothing happens. Experimenting a little I found that shorting pin P0_1 to ground caused a back and forth cycle of the servo.

What did I do wrong?

Thanks,

Burke

/** test_servos app:
 *
 * This app tests the servo library by using it to transmit servo pulses on
 * all six available pins: P0_2, P0_3, P0_4, P1_2, P1_1, and P1_0.
 *
 * This is mainly intended for people who are changing the servo library.  If
 * you just want to use the library to control a servo from a Wixel, see the
 * example_servo_sequence app.
 */

#include <cc2511_map.h>
#include <servo.h>
#include <wixel.h>
#include <usb.h>
#include <usb_com.h>

// Here we define what pins we will be using for servos.  Our choice is:
// Servo 0 = P0_2
// Servo 1 = P0_3
// Servo 2 = P0_4
// Servo 3 = P1_2
// Servo 4 = P1_1
// Servo 5 = P1_0
uint8 CODE pins[] = {2, 3, 4, 12, 11, 10};
uint8 bStrikeMagnet = 0;
uint32 ulStartTime = 0;

void myServosInit()
{
    // Start the servo library.
    servosStart((uint8 XDATA *)pins, sizeof(pins));

    // Set the speed of servo

    servoSetSpeed(5, 0);      // Not actually necessary because default speed is 0 (no speed limit).
}

void updateServos()
{
     if ((getMs() - ulStartTime) < 1000)
     {
          servoSetTarget(5, 1000);

          LED_YELLOW(0);
     }
     else if ((getMs() - ulStartTime) >= 1000 && (getMs() - ulStartTime) < 2000)
     {

          servoSetTarget(5, 1000);

          LED_YELLOW(1);
     }
     else
     {
          bStrikeMagnet = 0;
     }
}

// Takes care of receiving commands from the USB virtual COM port.
void receiveCommands()
{
    if (usbComRxAvailable() == 0){ return; }
    switch(usbComRxReceiveByte())
    {
    case 's':  // Start/Stop
        if (servosStarted())
        {
            servosStop();
        }
        else
        {
            servosStart(0, 0);
        }
        break;
    }
}


void main()
{
    systemInit();
    usbInit();
    myServosInit();

    while(1)
    {
        boardService();
        usbComService();
        usbShowStatusWithGreenLed();
        // if button is pushed then cycle servo back and forth once
    	if (!isPinHigh(1))
    	{
    		bStrikeMagnet = 1;
    		ulStartTime = getMs();
    	}
        updateServos();
        receiveCommands();

        // The red LED will be on if any of the servos are moving.
        LED_RED(servosMoving());
    }
}

Hello, Burke.

I think there is some confusion about how pins on the Wixel work. Your code specifies pin P0_3 as a servo output because you put 3 in pins[] array. Therefore, P0_3 will be an output and you should not attempt to use it as an input at the same time. When you tried to read P0_3, you used the following code:

isPinHigh(1)

That code was actually reading P0_1, not P0_3, so the behavior you describe in point 2 is expected. The Wixel’s GPIO library provides the isPinHigh function and it knows nothing about the servo library or your servo pin assignments, so you shouldn’t expect it to associate 1 to P0_3. The pin number 1 is associated to P0_1. You can see the documentation of the GPIO library and isPinHigh here:

pololu.github.io/wixel-sdk/gpio_8h.html

I am not sure why you would see the servo moving 90 degrees when all the calls to servoSetTarget specify the same target (1000). It’s possible that you just forgot to save and/or recompile your code, so you might want to try again. If that doesn’t help, could you try simplifying your code as much as possible? For example, what if you remove the second call to servoSetTarget altogether? What if you remove the first call?

–David