7 Replies Latest reply on Jan 30, 2015 3:48 PM by fontie98

    Galileo Servo Library Fixes

    Mikal.Hart

      I've been studying the Servo library that ships with Galileo and have developed a new version that addresses a couple of issues that I've discovered.

       

      If you'd like to try the new version:

      1. Download the latest archive at Releases · mikalhart/galileo-Servo · GitHub

      2. Unzip the archive and use the two contained files (Servo.h and Servo.cpp) to overwrite those in ../hardware/arduino/x86/libraries/Servo.

      3. Exit the Arduino IDE software and restart it.

       

      First, a bit of background about why the Servo experience on Galileo is a little less than optimal, even after my changes.  A typical servo expects to see a series of pulses at 50Hz on its control line.  The width ("duty cycle") of each pulse determines whether the servo goes to 0 degrees (2.7% duty), 180 degrees (12% duty), or somewhere in between.  On Galileo, this pulse stream is generated by an internal PWM ("pulse width modulation") mechanism, but because this is quite low resolution--the duty cycle is defined by just 8 bits--the effective accuracy of the library for off-the-shelf servos can only be guaranteed to within about 10 degrees.

       

      Now the authors of the original Servo library provide an option, enabled by default, to increase the Servo angular resolution by shrinking the width of the pulse from 20ms (50Hz) to about 5.3ms.  While this is an admirable idea in many ways, it doesn't work at all for any of the servos I tried.  These sub-$10 servos can't deal with the out-of-spec pulse widths, so they just sit there twitching.  And so one of my library changes is to make this "hi resolution", 188Hz mode not the default.

       

      My overriding goal for these changes and the other mods I'm offering is to make it so a person coming from Uno to Galileo experiences as little discomfort as possible.  One of the mottoes of the group I work for is "It just works."  If we can give a new Galileo user as close as possible to the "it just works" experience, well, so much the better.


      Details of changes

      • The default min/max pulse widths in Uno (544us and 2400us) have been restored.
      • Removed code that recenters (moves to 90 degrees) the servo whenever it is attach()ed to the library or changes resolution.  The AVR version of the library does not recenter, and it's bad form to assume that 90 degrees is a safe or even possible position for a given application.
      • Default to low-resolution 48Hz mode, because 188Hz mode is not usable by many servos and we don't want 'panicked twitching' to be the default experience.
      • Removed a diagnostic line that floods the Serial monitor and resets the minimum pulse with to an incorrect value.
        ("if(this->min=1000) Serial.println(max_byte);")
      • Replace hard constants 0 and 180 with symbols defined in Servo.h

       

      Comments and change suggestions encouraged.

       

      LIbrary at Releases · mikalhart/galileo-Servo · GitHub.

        • 1. Re: Galileo Servo Library Fixes
          AlexanderMerz

          There is still a bug in it. I came across this problem while dealing with servos using Python (means: no library support). The datasheet of the IO Expander chip on the Galileo tell us: the programmable PWM clock source is 367,6Hz. If you set a divider of 0x02, you get 183.8Hz, not 188Hz as it is written everywhere.

          • 2. Re: Galileo Servo Library Fixes
            Mikal.Hart

            Yep, I noticed that misnaming too, Alexander, but left it there for compatibility.  But hey, there probably aren't yet that many users out there that call set188hz().  I'm going to change it.

             

            You bring up a point that I wanted to mention.  I don't like that ultra-specific method naming.  Even if we change to set184hz(), it's still extremely specific to the Cypress hardware.  If a new version of Galileo came out with an improved PWM chip, this would immediately become obsolete.

             

            I am going to make a new version of Servo that replaces set44hz() and set188hz() with setResolution(int resolution) where higher values of resolution generate lower dividers, and therefore higher pulse frequencies.  The default will be low for maximum compatibility with existing servos.  Thanks for pointing that out, Alexander.

             

            Again, I should mention that I am not on the Galileo team, so this is by no means an official statement.

            • 3. Re: Galileo Servo Library Fixes
              Don_Fantom_Juan

              What a great artical!

              It solved my many questions. But I'm still confused why there must be a

              Wire.beginTransmission(0x20);

              I've read the Cypress datasheet, but this code seemmingly have nothing to do with Cypress. The code behind it is truly to configurate PWM's register.

              Besides, if I want to control 6 servos in one loop, should I change the 188hz to 44hz every time?

              And the final question is  "servo goes to 0 degrees (2.7% duty), 180 degrees (12% duty)"

              but in my memory, it's 0 degrees(0%) ~ 180 degrees(100%)

              Thank you very much!

              • 4. Re: Galileo Servo Library Fixes
                Mikal.Hart

                Don, the 0x20 is the i2c address of the Cypress device on the Galileo.

                 

                Servo Angle Schematic 180 3.8

                 

                A "standard" servo pulse width is 20ms (20000us) long.  As you can see from the above diagram, the HiTec HS-55 servo goes all the way to the left when the pulse is high for 600us (about 3% duty) and all the way to the right when high for 2400us (about 12% duty).

                1 of 1 people found this helpful
                • 5. Re: Galileo Servo Library Fixes
                  Don_Fantom_Juan

                  Thank you. I'd ever read a book ,it said 0%(0 degree) 100%(180 degree). Maybe he's wrong.

                  And I test your new Servo.h, contrast to the old version, the data is as follows:

                  New_Servo.h
                  setxxhzangleduty cyclefrequency(Hz)old duty cycle
                  4801.9-2.1%424.20%
                  18809.80%18917.0-18.9%
                  48453.8-4.0%425.0-5.5%
                  1884518.60%18922.6-24.5%
                  48905.7-5.9%425.5-5.9%
                  1889027.30%18928.3-28.4%
                  481357.8-8.0%426.7-7.1%
                  18813527.30%18932.1-34
                  4818010.1-10.3%428.0~8.4%
                  18818036.00%18935.8-37.7%
                  默认453.8-4.0%4224.5-22.6%
                  • 6. Re: Galileo Servo Library Fixes
                    cristaltech

                    Thank you!  I've been scratching my head for days.  At first I thought it was because I was running the 1.53 IDE on Linux, so I went back to windows.  Same problems.  I wish I would have read this a few days ago.  Thanks again for your post.  I'll let you know what I find.

                    • 7. Re: Galileo Servo Library Fixes
                      fontie98

                      Hello Mikal,

                      I have followed your instructions to the number but,

                      the libraries are still not being recognized by the

                      Galileo. I have removed the old libraries, unzipped the

                      new libraries and replaced them with yours. On

                      opening the IDE for Galileo and selecting servo from

                      examples. The #include <Servo.h> is in black text.

                      This indicates that the IDE can't see it. It is most

                      probably my doing but, i could really use some input.

                      Font