Servos on the Raptor

Quick question…

Is there anything unusual or special about using servos on the Raptor that I need to be aware of?

I’m using a DFRobot “Servo Expansion Module” on Socket 18 to access PWM channels 0, 1, and 2 to control a robot arm.

I initialize the 3 PWMs like this:

MyServoLeftRight = new PWM(Cpu.PWMChannel.PWM_1, 2175, 175, PWM.ScaleFactor.Microseconds, false);
MyServoUpDown = new PWM(Cpu.PWMChannel.PWM_0, 2175, 175, PWM.ScaleFactor.Microseconds, false);
MyServoOpenClose = new PWM(Cpu.PWMChannel.PWM_2, 2175, 175, PWM.ScaleFactor.Microseconds, false);

It seems that I can only use PWM_1 (MyServoLeftRight)

When I perform the following loop, servos connected to pin 8 (PWM_1) work:

 for (uint d = 2200; d >=1000; d -= 1)
{
                     MyServoLeftRight.Duration = d;
                     MyServoLeftRight.Period = 20000;
                     MyServoLeftRight.Start();
                     Thread.Sleep(1);
 }

But if I try the same thing for Pin 7 (using MyServoUpDown/PWM_0) or Pin 9 (MyServoOpenClose/PWM_2) nothing happens. In fact, it seems like sometimes when I use MyServoOpenClose/PWM_2 I get random jittery signals on PWM_1 (the wrong pin)

So far PWM_1 is the only one I seem to be able to get working.

Any Ideas? Am I overlooking something obvious?

I’m not sure that says the 3 pins on a P socket will be consecutive PWM channels, and there’s nothing that says the PWM channels match the PWM_x number on the schematic. So there’s a chance we’re not talking to the correct pins.

I don’t exactly know what the servo expansion module is doing hardware wise, but pins 7, 8, and 9 are meant to be PWM capable, as is pin 9 on socket 16 - are you able to test those all independently? Make sure you use the same servo though, because there can be enough difference in them to cause them to not behave the same. Another good measurement technique if you don’t have great lab gear is to set a 50% duty cycle up on a pin and measure it with a multimeter and see if you get ~1.65v

Perhaps there’s a way to use the Gadgeteer pin reference using the PWMOutputFactory class so you know that you’re talking to the correct pin.

Hmm. Am I reading the schemtic wrong? (below)

Do you think PWMChannel_0 might not be PWM_0. and PWMChannel_2 might not be PWM_2? I just assumed…

I am testing with the same servo.

I haven’t used the PWMOutputFactory class… I was just following the GHI tutorial at https://www.ghielectronics.com/docs/18/pwm -but I will definitely give that a try! Thanks.

@ mtylerjr -

Would this help?

https://www.ghielectronics.com/community/forum/topic?id=16168

Thanks willgeorge. I did see that thread.

It seems to indicate that I am going about things the correct way though.

I’ll keep investigating.

Well, I tried using PWMOutputFactory…

(Servo is represented as a breakout module in the designer, socket 18)

Gadgeteer.SocketInterfaces.PwmOutput p = 
Gadgeteer.SocketInterfaces.PwmOutputFactory.Create(Servo.Socket, Gadgeteer.Socket.Pin.Eight, false, null);

                  for (uint d = 800; d <= 2200; d += 50)
                  {
                      p.Set(20000, d, GT.SocketInterfaces.PwmScaleFactor.Microseconds);
                      Thread.Sleep(100);
                  }

With the servo connected to pin eight (Pwm_1), the above code works great.

If I create the PwmOutput using Gadgeteer.Socket.Pin.Seven, and connect to pin 7 (pwm_0)… nothing.
If I use Pin.Nine and connect to pin 9 (pwm_2)… nothing

If I used Socket 16, and use Pin.Nine (Pwm_3) the code works.

It looks like PWM_0 and PWM_2 on my raptor are just dead.

Does anything in the gadgeteer system sneakily take over PWM_0 and PWM_2 (or use PC18 or PC20 pins) without telling?

Are the even PWM channels different than the odd PWM channels? (I also tried inverting the signals just in case)

I might need to RMA this raptor. Big fat frowny face :frowning:

@ mtylerjr - I would first try using PWM in NETMF without anything else including Gadgeteer: https://www.ghielectronics.com/docs/18/pwm

Just make a port on PWM0, PWM1, and PWM2 and see what kind of output you get.

Thanks for the response, John

The tutorial at https://www.ghielectronics.com/docs/18/pwm is what I tried first (see earlier post where I included the schematic of socket 18)

It was because the even-numbered PWM ports didnt work using that that I switched to trying PWMOutputFactory.

I do notice one odd behavior - when I try to use PWM_2 I sometime get jittery signals on PWM_1.

It would appear to possibly be a short between the PWM pins - that’s the only thing I can think of that would cause that result…

I’ve got a Gadgeteer and Servos video coming up when I get some time to do the actual video. This is my project board thus far, 3 servos (2 regular, 1 continuous rotation) and for fun a couple of opto interrupters.

@ mtylerjr - I do not have a suggestion or a solution, but just to give you some hope I did a quick test on my Raptor using your original code and it does seem to work. You can see the results in the attached image.

Here is the code I used to test


using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace RaptorPWMTest
{
    public class Program
    {
        public static void Main()
        {
            var MyServoLeftRight = new PWM(Cpu.PWMChannel.PWM_1, 2175, 175, PWM.ScaleFactor.Microseconds, false);
            var MyServoUpDown = new PWM(Cpu.PWMChannel.PWM_0, 2175, 175, PWM.ScaleFactor.Microseconds, false);
            var MyServoOpenClose = new PWM(Cpu.PWMChannel.PWM_2, 2175, 175, PWM.ScaleFactor.Microseconds, false);

            MyServoLeftRight.Start();
            MyServoUpDown.Start();
            MyServoOpenClose.Start();

            Debug.Print(
                Resources.GetString(Resources.StringResources.String1));

            while (true)
            {
            }
        }

    }
}

Just a quick question, are you sure your instances are not going out of scope and are therefore being GC’d? There was not enough code in your first sample to confirm either way so I thought it might just be worth asking.

Yes… I am making sure nothing is going out of scope.

I have also tried initializing all 3 and driving them all identically in a loop but only PWM_1 works (with any of my servos) PWM_0 and PWM_2 refuse to do anything.

Ive tried using the raptor’s 5v, and external 5V power. Ive tried different cables. Ive tried using extender modules and checking the pins for voltage. pins 7 and 9 never receive any signals. and pin 8 gets signalss occasionally when the raptor tries to drive pwm_2 (pin 9) - so I am pretty convinced now it is a short.

I thought I would post a few photos of my rover-in-progress. It is partially disassembled while I try various things to test the servos…

The dual-motor-controller-module setup using the hub works great… I can steer in any direction driving 4 motors with mecanum wheels. I have an xbee in there under the raptor board along with a music module (donated to me by Sprigo) connected to a velo360 speaker. The servos should control the arm, but I have run into this problem. I am going to try and use my pololu servo driver to get around the raptor’s issues until I can replace the raptor. I have an N18 on there too.

I’m controlling the rover with one of these (with another xbee installed)

2 Likes

@ mtylerjr - Nice project. I like the look of the rover.

a short between the PWM pins would give you exactly the same behaviour of the servo on those two pins. I’m not that convinced that this is your issue, but the good news is a quick continuity test should help you prove/disprove that, I assume you have access to a multimeter? That would be a quick way to confirm.

Servos are not trivial to run, they’re all a little different so require tweaks to make sure you don’t get yourself in trouble. I’d actually go for a simple test harness app - something like set the servo to a mid-way position, wait for several seconds, set it to a left position, wait for several seconds, set it to a right position, wait, and repeat. You could do that out of phase on your three servo lines so if you had multiple servos you’d see a difference on them (or you could just simplify it and test one pin per deployment).

Okay I ran this code:

                    MyServoUpDown = new PWM(Cpu.PWMChannel.PWM_0, 20000, 1750, PWM.ScaleFactor.Microseconds, false);
                    MyServoLeftRight = new PWM(Cpu.PWMChannel.PWM_1,20000, 1750, PWM.ScaleFactor.Microseconds, false);
                    MyServoOpenClose = new PWM(Cpu.PWMChannel.PWM_2, 20000, 1750, PWM.ScaleFactor.Microseconds, false);

                    for (uint d = 1000; d <= 2200; d += 1)
                    {
                        MyServoUpDown.Duration = d;
                        MyServoUpDown.Period = 20000;
                        MyServoUpDown.Start();

                        Thread.Sleep(1);
                        MyServoLeftRight.Duration = d;
                        MyServoLeftRight.Period = 20000;
                        MyServoLeftRight.Start();

                        Thread.Sleep(1);
                        MyServoOpenClose.Duration = d;
                        MyServoOpenClose.Period = 20000;
                        MyServoOpenClose.Start();

                        Thread.Sleep(1);
                    }

Using a multimeter I watched the voltage on the signal line on pins 7 8 and 9

Pin 7 - voltage oscillated from about -5 mV to 5mV fairly randomly usually under 1 mv… essentially 0v. did not change behavior during the test.

Pin 8 - ramped up from a very low voltage to about 2.3v during the test

Pin 9 - acted the same as pin 7.

If I connected servos, pin 7 caused the servo to turn nicely from one end to the other. The same servo connected to the other pins does nothing obviously

I did not see any physical shorts between the pins though.

It just looks like the pins are dead. Maybe the socket is just poorly attached… I have requested an RMA

Does make any difference?

MyServoUpDown = new PWM(Cpu.PWMChannel.PWM_0, 20000, 1750, PWM.ScaleFactor.Microseconds, false);
                    MyServoLeftRight = new PWM(Cpu.PWMChannel.PWM_1,20000, 1750, PWM.ScaleFactor.Microseconds, false);
                    MyServoOpenClose = new PWM(Cpu.PWMChannel.PWM_2, 20000, 1750, PWM.ScaleFactor.Microseconds, false);

MyServoUpDown.Start();
MyServoLeftRight.Start();
MyServoOpenClose.Start();

                    for (uint d = 1000; d <= 2200; d += 10)
                    {
                        MyServoUpDown.Duration = d;
                        MyServoLeftRight.Duration = d;
                        MyServoOpenClose.Duration = d;
                        Thread.Sleep(10);
                    }

Tech support gave me a very simple test to try, creating a netmf console app and toggling those pwm pins, with an led7r module connected.

3 LEDs should have pulsed but only one pulsed - so the verdict seems to be a hardware issue.

Thanks for all your help and suggestions though.