0

I am running MicroPython on a Raspberry Pi Pico. I can set the position of the servo by changing the duty cycles:

from machine import Pin, PWM

servo = PWM(Pin(0))
servo.freq(50)
servo.duty_u16(1350) # sets position to 0 degrees

I may have missed something, but I have read through the docs and couldn't find any way to read the current position of the servo. Is there any way to do this?

luek baja
  • 1,475
  • 8
  • 20

1 Answers1

0

Most servos do not provide any sort of position information. You know what the position is because you set it. You can write code that will keep track of this value for you. For example, something like:

from machine import Pin, PWM


class Servo:
    min_duty = 40
    max_duty = 1115

    def __init__(self, pin):
        servo = PWM(Pin(pin))
        servo.freq(50)
        self.servo = servo

        self.setpos(90)

    def setpos(self, pos):
        '''Scale the angular position to a value between self.min_duty
        and self.max_duty.'''

        if pos < 0 or pos > 180:
            raise ValueError(pos)

        self.pos = pos
        duty = int((pos/180) * (self.max_duty - self.min_duty) + self.min_duty)
        self.servo.duty(duty)

You would use the Servo class like this:

>>> s = Servo(18)
>>> s.pos
90
>>> s.setpos(180)
>>> s.pos
180
>>> s.setpos(0)
>>> s.pos
0
>>>

In your question, you have:

servo.duty_u16(1350)

I'm suspicious of this value: at 50Hz, the duty cycle is typically between 40 and 115 (+/1 some small amount at either end), corresponding to ≈ 1ms (duty=40) to 2ms (duty=115).

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Is there any way I might be able to calculate the current position based on the distance and the time it takes to rotate? Also, I've seen a few tutorials for the exact hardware I'm working with and they all use that same line of code. The max range is 0-65355 so I guess it is scaled in some way. It seems to be working fine though. – luek baja Aug 01 '21 at 13:48