chipKIT® Development Platform

Inspired by Arduino™

Max32 and control of servos with SoftPWMServo

Created Thu, 07 Aug 2014 16:58:40 +0000 by mdsousa


mdsousa

Thu, 07 Aug 2014 16:58:40 +0000

Hi

In trying to figure out the SoftPWMServo library, I'm trying to control one servo with my Max32. I am on Ubuntu 12.04 and have Mpide 0023-linux64-20140316. I am using a Tower Pro MG90S Micro Servo.

My code:

#include <SoftPWMServo.h> 

int pos = 0;         // variable to store the servo position, in microseconds
const int portAerilon = 30;  // Choose _any_ pin number on your board
 
void setup() 
{
   Serial.begin(9600);
   delay(5000); // wait for 5 seconds for serial to setup
   Serial.println("SoftServoTest up and running");
} 

void shutdown()
{
  Serial.println("SoftServoTest is done");
  while(true)
  {
    delay(1000);
  }
}

void loop() 
{
  SoftPWMServoPWMWrite(portAerilon, 1500); // set to middle - for MG90S Micro Servo
  Serial.println("Servo should be centering");
  delay(1000);
  Serial.print("portAerilon RawRead: ");
  Serial.println(SoftPWMServoRawRead(portAerilon));
  Serial.print("portAerilon ServoRead: ");
  Serial.println(SoftPWMServoServoRead(portAerilon));
  Serial.print("portAerilon PWMRead: ");
  Serial.println(SoftPWMServoPWMRead(portAerilon));

  SoftPWMServoPWMWrite(portAerilon, 1750); // 2ms, 90' (all way to starboard) for MG90S Micro Servo
  Serial.println("\nServo should be tracking to starboard");
  delay(1000);
  Serial.print("portAerilon RawRead: ");
  Serial.println(SoftPWMServoRawRead(portAerilon));
  Serial.print("portAerilon ServoRead: ");
  Serial.println(SoftPWMServoServoRead(portAerilon));
  Serial.print("portAerilon PWMRead: ");
  Serial.println(SoftPWMServoPWMRead(portAerilon));

  SoftPWMServoPWMWrite(portAerilon, 1250); // 1ms, -90' (all way to port)
  Serial.println("\nServo should be tracking to port");
  delay(1000);
  Serial.print("portAerilon RawRead: ");
  Serial.println(SoftPWMServoRawRead(portAerilon));
  Serial.print("portAerilon ServoRead: ");
  Serial.println(SoftPWMServoServoRead(portAerilon));
  Serial.print("portAerilon PWMRead: ");
  Serial.println(SoftPWMServoPWMRead(portAerilon));

  SoftPWMServoPWMWrite(portAerilon, 1500); // return to zero
  Serial.println("\nServo should centering");
  delay(1000);
  Serial.print("portAerilon RawRead: ");
  Serial.println(SoftPWMServoRawRead(portAerilon));
  Serial.print("portAerilon ServoRead: ");
  Serial.println(SoftPWMServoServoRead(portAerilon));
  Serial.print("portAerilon PWMRead: ");
  Serial.println(SoftPWMServoPWMRead(portAerilon));

  shutdown();
}

Here is the output from the Serial monitor when trying to control the servo:

SoftServoTest up and running
Servo should be centering
portAerilon RawRead: 69019
portAerilon ServoRead: 1725.47
portAerilon PWMRead: -37

Servo should be tracking to starboard
portAerilon RawRead: 67137
portAerilon ServoRead: 1678.43
portAerilon PWMRead: -43

Servo should be tracking to port
portAerilon RawRead: 70901
portAerilon ServoRead: 1772.53
portAerilon PWMRead: -31

Servo should centering
portAerilon RawRead: 69019
portAerilon ServoRead: 1725.47
portAerilon PWMRead: -37
SoftServoTest is done

I'm curious what the return return values map to? Also, when done, the servo sits there and makes quite a bit of noise and I'm wondering if that is normal?

Thanks...


EmbeddedMan

Thu, 07 Aug 2014 20:33:20 +0000

mdsousa,

Something is not working right for you. According to the documentation, the return value for RawRead should be in 40MHz ticks, the return value for ServoRead should be in microseconds (approx). I'm not sure that PWMRead is valid as you're using the pin as an RC servo, but it might be. I need to check that to.

I can look into this when I get home in awhile.

As far as your servo making noise, after you're done with moving the servo around, try setting it's pin to be an output and set it low. (This would help counter any noise if the pin is set to an input after you're done with it.)

*Brian


EmbeddedMan

Thu, 07 Aug 2014 20:44:05 +0000

Duh, I see the problem.

You're using SoftPWMServoPWMWrite() incorrectly. Here is the documentation for that function:

/*
 * Sets a particular pin to have a new PWM pulse width
 * and sets the pin to be a PWM pin.
 *
 * Pin: A valid pin number for the board you are using
 * Value: A value from 0 to 255 representing the %100 of time you want
 *   your pin to stay high.
 * 
 * Use this function to set a pin to be a PWM pin, and specify its
 * pulse width. Equivalent to the normal analogWrite() call.
 *
 * Returns: SOFTPWMSERVO_OK
 *
 */

You are passing in microseconds to the function. If you want to use microseconds, you should probably use the SoftPWMServoServoWrite() function instead.

When I update your code to use the ServoWrite() call, I get the following for output:

SoftServoTest up and running
Servo should be centering
portAerilon RawRead: 60000
portAerilon ServoRead: 1500.00
portAerilon PWMRead: -65

Servo should be tracking to starboard
portAerilon RawRead: 70000
portAerilon ServoRead: 1750.00
portAerilon PWMRead: -33

Servo should be tracking to port
portAerilon RawRead: 50000
portAerilon ServoRead: 1250.00
portAerilon PWMRead: -97

Servo should centering
portAerilon RawRead: 60000
portAerilon ServoRead: 1500.00
portAerilon PWMRead: -65
SoftServoTest is done

And that is what I expect.

*Brian


mdsousa

Thu, 07 Aug 2014 23:16:21 +0000

Thanks EmbeddedMan, that did the trick... :D