Electronic – How to make smaller steps with the servo

duty cyclepwmraspberry piservo

I've got a Raspberry Pi with which I control a servo. The servo controlls the rudder in an autonomous boat I'm building. I'm using Golang and this gpio library to control the PWM.

The input I get from the program ranges from -100 (full left) to 100 (full right). I've got some code (proof-of-concept) which works great (paste here).

I use:

  • a frequency of 100
  • a cycle length of 100
  • I vary the duty cycle between 3 (full left) and 14 (full right).

This works great, but since the library only accepts ints as input for the duty cycle, I only have 11 discrete steps to which the servo can be set. I would like to be able to have more fine grained control though. I would like to use a minimum of about 25 discrete steps.

So I played around with the numbers of the frequency, the cycle length and the duty cycle minimum and maximum, but I really can't get more steps.

Could anybody give me some hints as to how I can create more discrete steps? All tips are welcome!

So far so good.

Best Answer

Your pin frequency is far too low. This establishes the basic clock used to produce the PWM.

You normally want the PWM signal to have a period close to 20 ms, which corresponds to an update rate of 50 Hz. The pulse width needs to vary between 1 and 2 ms. If you want 200 steps to cover this range (-100 to +100), the pin frequency (PIN_FREQ) needs to be

$$\frac{200}{2\text{ ms} - 1\text{ ms}} = 200\text{ kHz}$$

If you want to update at 50 Hz, that means that the cycle length (CYCLE_LENGTH) should be

$$\frac{200\text{ kHz}}{50\text{ Hz}} = 4000$$

and to vary the pulse width between 1 ms and 2 ms, you use duty cycle (dutyCycle) values between

$$200\text{ kHz} \times 1\text{ ms} = 200$$

and

$$200\text{ kHz} \times 2\text{ ms} = 400$$