Just to clarify my background, I’m a software architect by trade so coding is my gig, but I have just now started dancing with hardware. So GPIO, PWM, and the other things these micro controllers can do are all new to me. I’m diving in deep so that I can figure out what all is possible.
I recently picked up the FEZ Panda II so that I could begin testing with servos and ESCs. Hopefully this progresses quickly into an actual project, whether it be drones, robots, or a simple ball thrower for my border collies.
So… In regards to using a PWM to control a servo. I hooked up a HiTec HS-55 servo to PWM1 on the FEZ Panda II. Most of the posts I have found state that 1500 is neutral, 1250 is -45 and 1750 is +45. After running some sample codes I found this not to be true for this particular servo at least.
-90 = 600
-45 = 1050
0 = 1500
+45 = 1950
+90 = 2400
Below is my code which runs successfully. It basically sets the servo to 0 degrees, then flips between -45 and 45. The next step cycles from -75 to +75.
static void TestServo()
{
uint low = 600;
uint high = 2400;
uint[] highTime = null;
try
{
led.Write(true);
servo.Set(true);
highTime = new uint[5];
highTime[0] = TestServo_CalcScale(low, high, 0);
highTime[1] = TestServo_CalcScale(low, high, -45);
highTime[2] = TestServo_CalcScale(low, high, 45);
highTime[3] = TestServo_CalcScale(low, high, -45);
highTime[4] = TestServo_CalcScale(low, high, 45);
delay = 2000;
for( int index = 0; index <= highTime.Length - 1; index++)
{
SetPulse(servo, 20000, highTime[index]);
}
delay = 100;
for (short degree = -75; degree <= 75; degree++)
{
SetPulse(servo, 20000, TestServo_CalcScale(low, high, degree));
}
SetPulse(servo, 20000, TestServo_CalcScale(low, high, 0));
}
catch (Exception ex)
{
Debug.Print("Exception[" + ex.ToString() + "]");
}
finally
{
servo.Set(false);
}
}
static uint TestServo_CalcScale(uint low, uint high, short degree)
{
uint high_zero = 0;
uint rtObject = 0;
uint perdegree = 0;
try
{
high_zero = low + ( ( high - low ) / 2 );
perdegree = (( high - low ) / 2 ) / 90;
rtObject = high_zero + (uint)( perdegree * degree);
}
catch( Exception ex)
{
Debug.Print("Exception[" + ex.ToString() + "]");
}
finally
{
}
return rtObject;
}
static void SetPulse(PWM pwm, uint period_nanosecond, uint highTime_nanosecond)
{
try
{
Debug.Print("SetPulse: " + period_nanosecond.ToString() + ": " + highTime_nanosecond.ToString());
pwm.SetPulse(period_nanosecond * 1000, highTime_nanosecond * 1000);
led.Write(!led.Read());
Thread.Sleep(delay);
}
catch (Exception ex)
{
Debug.Print("Exception[" + ex.ToString() + "]");
}
finally
{
}
}
Now for the questions.
-
Do the upper/lower values differe from servo to servo? Or should these be safe values for all servos I might use in the future. I ask because I saw so many posts stating 1250, 1500, 1750 for the values to set -45, 0, +45 degrees.
-
This servo seems to handle -90 pretty well but once I get past +85 the servos goes into a tailspin and which I assume is the continuous 360degree rotation. Is this expected from all servos?