Main Site Documentation

Servo Problem (probably actually a problem with me)


#1

I am trying to wire up and control a servo.

My servo is a standard Hitec HS-303 which is like this:
http://www.servodatabase.com/servo/hitec/hs-303

As you can see from the specs it matches the timings shown in Michael Dodaro’s example (http://mikedodaro.net/2011/12/22/using-a-servo-with-a-net-gadgeteer-camera-device/)

However when I run my code the servo always just goes to one of it’s maximum extents and just stays there. If i disconnect the signal pin from pin 8 on my extender to the servo, the servo just sits there, so somehow my signal is wrong.

My code is much simpler than Mike’s, I just get the joystick position and generate my percentage from that, as such:

At the top of my code i have the same constants as Mike:


        GT.Interfaces.PWMOutput servo;
        static uint high = 2100000;
        static uint low = 900000;
        static uint delta = high - low;

I initialize the servo the same way:


servo = extender.SetupPWMOutput(GT.Socket.Pin.Eight);

and I set it the same way, in a timer loop…only difference being i get my percent from the joystick (which traces out fine to the display)


Joystick.Position pos = joystick.GetJoystickPostion();

uint percent = (uint)System.Math.Round(pos.X * 100);

uint pulse = low + (delta * percent / 100);
servo.SetPulse(20000000, pulse);

Any advice on how I can troubleshoot this? I am a newb and don’t have any fancy shit like oscilloscopes.

thanks


#2

I have not played with servos on Fez, but there’s one thing you can guarantee - the timing for any servo is not an absolute ! You might need to try adjusting the low/high values and see if that changes the behaviour.

First suggestion I have is NOT to use a pot value to calculate things, well not in absolute terms. I’d try to get some mid-point value to work and hold stable before you try any fancy schmancy adjustments. Then, and only then, have the value change to turn 45deg left and right based on some event (button press, or then you can read the value from the pot and if it’s above some threshold then move to the right, below a different threshold go to the left, and in the middle stay centred).


#3

@ Rossman

Have a look at this project…I used it to connect a servo via the Extender module, and used a potentiometer for moving the servo:

http://code.tinyclr.com/project/405/servo-control-with-the-gadgeteer-extender-module/

You might need to adjust the high and low limits for your servo, and as Brett suggested, it’s a good idea to tweak a static value to find the middle and ends of the range for your servo before introducing other elements like the pot or joystick.

One other thing to be aware of is whether the code you’re using is in milliseconds or microseconds. Mix those up and you might well see the symptoms you’re seeing.

Good luck!


#4

Hi guys,

thanks for your quick responses.

i will try some static values and see if i can get anything other than the “going all the way to one extent” as a result.

is it possible that wrong input voltage to my servo can cause this (i am powering with seperate power supply which is pretty ghetto)?

thanks,
mark


#5

@ Rossman

Not sure, but I don’t think the voltage would cause what you’re seeing, though if it’s too far outside what the servo is rated for, you might damage the servo.

To clarify, are you talking about voltage to the signal pin (usually either 3.3v or 5v, depending on the mCU, but Gadgeteer should deliver 3.3) or to the positive lead (i.e. your source voltage)? I’m guessing the latter since you mention a separate power supply.


#6

So two things to remember when powering: tie the GNDs together, and don’t tie the + wires together !

You really need the shared GND, otherwise the signal/pulse line could “look” like it’s out of spec and that could lead to what you’re seeing. Lets hope it’s that simple :slight_smile:

It’s unlikely that you can do too much to damage a servo with a dirty power supply, they usually handle lots of noise in a plane or whatever.

You definetely want to find the mid-point first. Adjust that value so the servo arms are centred - in fact, the best trial and error method to figure out how your servo behaves is to provide one value in your code and adjust that up/down until you establish what keeps it centred and then what keeps it to a left deflection and then a right deflection.


#7

Thanks again for the responses guys!

@ devhammer: Yeah, I have a seperate power supply for the gnd/+6vdc into the servo, just some crappy wall wart i saved from god-knows-what back in the day.

I have the ground pin on the extender module tied to that ground (the servo ground). I have pin 8 wired to the signal pin of the servo.

I have the extender in Socket 11 off the Spider.

It’s a pretty simple circuit really. I soldered a 1x10 header to the extender so i could plug it into my breadboard - the solder job is not the best but no shorts between pins. Is it a possible bad solder join? I tried both pins 9 and 8 for signal as I am not very confident in my soldering skills, and at the moment have one of the crappiest soldering irons ever (non-adjustable that just plugs to mains power - ugh).

Is there something else other than a servo I can plug in to test this PWM shit out?

I have tried a lot of different numbers in that SetPulse call and never get anything other than the servo going all the way to the one extent. Frustrating :-/


#8

The hitec servo page says:

Pulse Cycle: 20 ms
Pulse Width: 900-2100 µs

So to me that means my SetPulse call should be like:

// 20 milliseconds in nanoseconds == 20,000,000
// middle of servo “width” per above is 1500 µs
// since setpulse takes both arguments as nanoseconds…

servo.SetPulse(20 * 1000000, 1500 ); /// to get the middle, no?

however all the other examples have the pulse width as much larger values (which I have also tried and have no different results with).

sigh


#9

If you have a piezo buzzer, you can use that to test PWM. You can also use PWM to dim an LED.


#10

Ok, I will get a piezo and some leds and try to get to the bottom of this.

I really want to control some ESC’s which I understand also use PWM which is why I started messing around with this servo (ESC’s are on order, won’t ship till after Chinese New Year) - just to be able to get a handle on the PWM stuff. Already seems more daunting than I expected!


#11

This may help you get started with the ESCs.


#12

Thanks for the link regarding ESC’s!

I am excited for when my get here, to play with them. But, feel I must solve this servo/PWM issue before I can really get anywhere with that stuff!

Cheers!


#13

Have you tried to start a new project and just drop in devhammer’s sample code that is known to work? If your schematic differs from his then try his also. Also, try a different PWM pin. There were some issues with pin mappings early on with Hydra that are supposed to have been fixed but I haven’t gone back and test them all again myself.


#14

(Have i told you I hate working with sub-second intervals! how many nanosecs in a second? ::slight_smile: )

Isn’t this the maths you need?

            uint period = 20;  // in msec
            uint midusec = 1500;  // in usec
            myPWM.SetPulse(period * 100 * 1000, midusec * 1000);

where midusec is the approx middle.position from the datasheet.

(and yeah, you’re doing the right thing here, if you can control this servo you can control the ESC)


#15

OMG Brett, that worked!

Thanks so much for your help guys, I knew it was probably something I was doing, and am ecstatic to find out it was a simple conversion / math issue (and not, say, my super lame soldering skills).

Thanks again!


#16

O.M.G.

Now put it to 900 not 1500 and see it go all the way one way. Then try 950 and hope it comes off the stop.

Then go 2100 and see it go the other way; 2050 and again it should come off the stop.

Then connect up that potentiometer again :slight_smile:


#17

Yeah, am doing this now!

It’s weird, if the pulse gets too high the servo throws hard to that same extent again, and a strange exception is thrown, something about a system hardware exception. Lowering the pulse does not help, at that point i have to shut it down/reboot it :frowning: But still - so much closer!

It doesn’t happen when i get to the lower bound, only the higher bound. Through trial and error, seems like my servo range is 800 - 1900 or so


#18

Strange, I wouldn’t have thought errors would have been caused if you got out of reasonable bounds for what your servo can handle. The one thing it could be is that the servo binds or has some other failsafe that causes it to stick there (although I’d hate to think that would be the case, in a real situation where the servo is used that would not be a good look, stuck with full rudder left or something !)

Actually now I think about it, a number of 2000 should not work; why, I hear you ask? Well that’s because that’s how long we’ve set the overall period for, and the usec high-time is meant to at least allow some interval at low to generate a pulse, otherwise all we’ve done it send a digital “1”. You could perhaps try using 25msec as the period (251001000) and see if you can then get reliably to set values approaching 2100? (another test would be to try setting 1999 and then 900 and see if it turns full deflection left/right, and then set it back to 1999; if that works, then the issue is definetely the 2000 magic number)


#19

For reference this is typical signal most modern radio receivers will send to a servo.


#20

Thanks again guys! :slight_smile: