Servo library

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
User avatar
deshipu
Posts: 1348
Joined: Thu May 28, 2015 5:54 pm

Servo library

Post by deshipu » Mon May 16, 2016 7:37 pm

For all those who want to use the ESP8266 with Micropython to build robots, here's a very simple library for controlling hobby servos:

https://bitbucket.org/thesheep/micropython-servo/src

Just a convenience wrapper, really, but I hope it will come useful.

I'm posting it here, instead of the "Hardware and Drivers" section, because it's pretty much specific to ESP8266's "machine.PWM" API, which doesn't seem to be used in any other port.

Tetje
Posts: 5
Joined: Sat Aug 27, 2016 3:26 pm

Re: Servo library

Post by Tetje » Sat Sep 03, 2016 11:45 am

Thanks a lot,

I thought I have to write it myself. I am you wondering that python is fast enough. ;) But when it is, it's great. Additionally I have a question an an idea. But is 3V3 enough, our do you connect the servo to a different level (with higher maximum current?) The thing that confues me in this class is, that in the example for the esp min is said to be 40 and max to be 115... and I thought how can you make 180° out off that (Chapter 7.2)
http://docs.micropython.org/en/latest/e ... obby-servo

Then I looked into your source and you used totally differnent values for min and max microseconds 600 and 2400. Than checked the arduino reference and they to also took totally different values 1000 to 2000. See:
https://www.arduino.cc/en/Reference/Ser ... croseconds

How is it possible? Is it a depending on the servo manufacture that youre values are min is 400 µs lower and your max is 400 µs larger. Why are the examples from the mircopython docu totaly different?

Finally an idea. What about an read method, at least the arduino as one. ;)

Great to have to option to use servo with the board! Than can realy be useful.

markxr
Posts: 62
Joined: Wed Jun 01, 2016 3:41 pm

Re: Servo library

Post by markxr » Sat Sep 03, 2016 12:22 pm

I have connected some micro-servos to the Raspberry Pi's GPIO ports (which also run at 3.3 volts).

3.3V seems just fine for the pulse inputs to the servos which are powered at 5v.

Mark

User avatar
deshipu
Posts: 1348
Joined: Thu May 28, 2015 5:54 pm

Re: Servo library

Post by deshipu » Sat Sep 03, 2016 7:43 pm

The way the servos work is that you send them a square wave signal with a fixed frequency (for analog servos this is usually 50Hz, digital servos may be able to accept up to 300Hz signal), where the duty cycle controls the servo position. The tradition is that at duty cycle of 1500µs the servo goes to its center position. That's pretty much the only thing that is standard.

Different servo models will have different total range (usually servos are only guaranteed to have 90° of rotation, though most of them can actually do 180°). For example, the cheap SG90 servos that I am often using have the range from about 400µs to about 2600µs (that is, 1100µs both ways from the 1500µs center position). This actually differs between individual servos bought at different places, and you should always fine-tune this experimentally for the particular servos that you have. For more expensive servos the parameters are probably much more consistent, and the manufacturer might even specify the recommended ranges in the documentation.

The other differences that confuse you come from using different units. The PWM class of ESP8266 uses percentages converted to range 0-1023 to specify the duty cycle length. That means that at 50Hz, value 1023 sets 20ms duty cycle (100%). From this you can easily calculate, that value of 40 gives you ~782µs, and value of 115 gives ~2248µs. This is close to the values 400µs and 2400µs that I'm using, leaving a bit of a margin for different models of the servos.

If you look at the documentation for the Arduino library (https://www.arduino.cc/en/Reference/ServoAttach) you can see that you can also manually specify the minimum and maximum values, and that they default to 544µs and 2400µs respectively. They then assume that this is over a range of 180° and map it into degrees based on that, so that you can use values 0-180. My library also lets you do a similar thing with the write_angle method, where you can use either degrees or radians, except that you should also specify the total angle of the servo (the last argument to the constructor), to tell the library how to map the angles exactly. This angle is the physically measured angle between the minimum and maximum positions.

I'm letting you set all those values, because there is no real standard for this stuff, and no two servos are identical. If you are lucky, the servos of the same model bought in the same place at the same time may be consistent. If you are not, you might need to test each servo and use different values for every one of them.

I hope that helps.

User avatar
deshipu
Posts: 1348
Joined: Thu May 28, 2015 5:54 pm

Re: Servo library

Post by deshipu » Sat Sep 03, 2016 7:48 pm

As for the voltages, 3.3V is enough for the signal to the servos. You shouldn't power the servos from your board, though, because they usually take much too much current -- the power for the servo should be separate, preferably some rechargeable batteries.

User avatar
dhylands
Posts: 3228
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Servo library

Post by dhylands » Sat Sep 03, 2016 7:57 pm

For example, here are some plots I did with 3 different servos comparing position versus pulse width.
http://davehylands.com/Robotics/Servos/ ... tions.html

And even 2 identical servos had different curves.

You have to remember that parts like resistors typically have 5% or 10% variation, and these variations typically cause slightly different voltages, even on identical boards in identical servos, which is why its good to be able to calibrate your servos to compensate.

markxr
Posts: 62
Joined: Wed Jun 01, 2016 3:41 pm

Re: Servo library

Post by markxr » Sat Sep 03, 2016 9:06 pm

Clearly the thing to do is use "closed loop" control with servos, so if your robot finds itself driving (flying?) a bit to the right, it steers left, and vice versa.

I used continuous rotation servos with a closed loop control based on an IMU gyroscope device, it works really well for keeping a good heading on a skid-steer robot (next obviously I need some sensor to detect forward motion to calibrate actual movement)

User avatar
deshipu
Posts: 1348
Joined: Thu May 28, 2015 5:54 pm

Re: Servo library

Post by deshipu » Sat Sep 03, 2016 9:38 pm

Well, a (non-continous rotation, standard) servo is supposed to have a closed loop controller already built in. You just have to calibrate for it a little in your program.

markxr
Posts: 62
Joined: Wed Jun 01, 2016 3:41 pm

Re: Servo library

Post by markxr » Sat Sep 03, 2016 10:44 pm

Right, but there is usually another "level of indirection", we don't really want to control the position of the steering wheels or rudder, we actually just want the vehicle pointing the correct way.

So if we add a closed-loop controller to control the "next level", then any variations in the behaviour of the servo should be ironed out by active feedback.

Llwy
Posts: 34
Joined: Thu Mar 10, 2016 7:43 am

Re: Servo library

Post by Llwy » Sun Sep 04, 2016 8:10 am

Hello,
I made a very similar library for the robot project I am working with.
Just one thing I did differently that may interest you:
Instead of setting the frequency to 50Hz, I set it to 100Hz (you could go even slightly higher). The idea is to get a better positioning resolution.
I tried first with the 50Hz value which was used in the MycroPython tutorial but basically a 1 digit increase in PWM duty cycle resulted in a 2 degrees step of the servo (rather low resolution). With 100Hz, you have pretty much 1 degree for 1 digit (duty cycle values can only be integers...)

From what I understand of hobby servos, the frequency does not really matter at all, the key value is the pulse length (between 1 and 2 ms).
By doubling the frequency, you double the number of values that you can specify between the 1 and 2ms range.

One possible draw back which I have not yet had to check is that if other ESP activities (Wifi etc..) become to demanding for the MCU, the 100Hz might be harder to keep than the 50Hz, especially if you use all 8 PWM pins as I am currently doing. I will try to verify this.

Best regards,

Llwy

Post Reply