Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

control servo #118

Open
christianrauch opened this issue Nov 8, 2021 · 3 comments
Open

control servo #118

christianrauch opened this issue Nov 8, 2021 · 3 comments

Comments

@christianrauch
Copy link

I try to control a servo using the PWM timings in the range of 1000 us to 2000 us (https://en.wikipedia.org/wiki/Servo_control#/media/File:Servomotor_Timing_Diagram.svg).

I set the maximum steps to 2000 us:

MBox Board Revision: 0xa01041
DMA Channels Info: 0x7ff5, using DMA Channel: 14
Using hardware:                   PWM
Number of channels:                32
PWM frequency:                 500 Hz
PWM steps:                        200
Maximum period (100  %):       2000us
Minimum period (0.500%):         10us
DMA Base:                  0x3f007000
Initialised, Reading /dev/pi-blaster.

so the duty cycle should be from 0.5 to 1.0. I assume that sending echo "4=0.5" > /dev/pi-blaster should turn the servo to -90 deg and echo "4=1" should turn the servo by 180 deg into the +90 deg position. While the servo moves somehow related to these values, I cannot get it reliably into these -/+90 or 0 deg position (echo "4=0.75"). The servo also seems to "hum", probably because the PWM signal is sent periodically, while the servo only expects a single up-down edge.

Eventually, I would like to control an ESC which would use the same PWM duty cycle settings but with a periodic signal. I am currently using the servo as a simpler component to test the PWM generator.

The original ServoBlaster project contains a servodebug.c to "help debug issues with ServoBlaster". Does pi-blaster have a similar tool that could help me to debug the signal that is sent out to the servo?

@sarfata
Copy link
Owner

sarfata commented Nov 8, 2021

I think most servos expect a signal that is slower than what you are sending here. The schematic you linked to mentions 20ms, that would be a 50Hz frequency (and not 500Hz).

The hmm is typically because the signal is not stable. Servos do expect the signal to be repeated continuously but here I guess it might be coming in too fast.

Try reducing the PWM frequency.

You can compile with the debug option and then write debug_samples into /dev/pi-blaster. It should show you more info on what is being sent.

@christianrauch
Copy link
Author

I think most servos expect a signal that is slower than what you are sending here. The schematic you linked to mentions 20ms, that would be a 50Hz frequency (and not 500Hz).

You are right and this makes sense.

I set CYCLE_TIME_US to 20000 and now get a 50Hz signal:

MBox Board Revision: 0xa01041
DMA Channels Info: 0x7ff5, using DMA Channel: 14
Using hardware:                   PWM
Number of channels:                32
PWM frequency:                  50 Hz
PWM steps:                       2000
Maximum period (100  %):      20000us
Minimum period (0.050%):         10us
DMA Base:                  0x3f007000

With the 10x maximum period, I can now set the servo with the 1/10 duty cycle values without the humming. echo "4=0.075" > /dev/pi-blaster will centre the servo and 0.05 and 0.1 respectively will set the -/= 90 deg positions.

From a pure PWM signal perspective, this makes sense. However, looking at the range of servo inputs, this feels a bit unintuitive. The servo only operates in "high" durations from 1 to 2 ms, so setting anything above 2000us makes no sense for the servo.

Maybe it would make sense to configure a minimum and maximum timing (0% and 100%) separately from the signal period, instead of computing one from the other? This way a user can define exactly when the rising and falling edge will take place and at which period, with the maximum frequency still being 1/max-period.
For the servo case, this would be min period 1000us, max period 2000us and frequency of 50Hz. An ESC configuration would use the same min/max period settings but a higher frequency (500Hz in this case).

@sarfata
Copy link
Owner

sarfata commented Nov 16, 2021

From a pure PWM signal perspective, this makes sense. However, looking at the range of servo inputs, this feels a bit unintuitive. The servo only operates in "high" durations from 1 to 2 ms, so setting anything above 2000us makes no sense for the servo.

Servos are just designed this way. They are not measuring the duty cycle of the incoming signal, they measure the duration of an impulse and they need a long silence between impulses to reset their counter. This probably has to do with the electronics of early servos.

The wikipedia page gives a little more information:

The period of 20 ms (50 Hz) comes from the days where the signal was encoded in PPM (pulse-position modulation) format to be sent over the air.[10] The PPM period was around 22.5 ms, and the conversion to PWM was trivial: the time of the PWM high state was the time position of the PPM pulse for that servo.

When a pulse is sent to a servo that is less than 1.5 ms, the servo rotates to a position and holds its output shaft some number of degrees counterclockwise from the neutral point. When the pulse is wider than 1.5 ms the opposite occurs. The minimal and maximal widths of pulse that will command the servo to turn to a valid position are functions of each servo. Different brands, and even different servos of the same brand, will have different maxima and minima. Generally, the minimal pulse will be about 1 ms wide, and the maximal pulse will be 2 ms wide.

You said:

Maybe it would make sense to configure a minimum and maximum timing (0% and 100%) separately from the signal period, instead of computing one from the other?

pi-blaster was built specifically to do PWM. There already is another project called servoblaster that is dedicated to controlling servos. I built pi-blaster (from servoblaster) because there was no way with servo impulses to get to 100% pwm.

Yes we could make pi-blaster more complicated and take a min/max timing (pull requests welcomed!) but you can also easily do that calculation in your code - or take a look at servoblaster instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants