2

I was trying to check the angle of a servo motor using my Raspberry Pi 3B+. Although when i run the code the servo motor jumps to 90 degrees (physically) and returns an angle of 0.0 in the terminal. This happens every time I run the code at any angle. What do you guys think ? Here is the code. I am not using any external hardware except the servo.

from gpiozero import Servo
from time import sleep

servo = Servo(17)

while True:
    angle = servo.value * 90
    print(f"Current angle: {angle:.1f} degrees")
    
    sleep(0.5)

This is the output

Current angle: 0.0 degrees
6
  • "What do you think?" is not very specific question. Please ask specifically what do you want to know.
    – Vadim
    Commented Mar 14, 2023 at 15:53
  • I meant "Why doesn't it return the right angle "
    – Coder
    Commented Mar 14, 2023 at 17:14
  • As Joan pointed out you can only read angle within the program which sets the angle. Servos have no way of knowing what angle they are set to. Until a PWM stream is present the position is unknown.
    – Milliways
    Commented Mar 14, 2023 at 21:34
  • If you are using hardware PWM the Pi hardware will continue to output the pulse stream continuously and you could potentially read the current setting.
    – Milliways
    Commented Mar 14, 2023 at 21:37
  • NOTE AFAIK gpiozero DOES NOT support hardware PWM, but this may depend on which library you are using.
    – Milliways
    Commented Mar 14, 2023 at 21:39

3 Answers 3

2

Generally servos have no method of reporting their position. You command it to an angle and have to assume it went to that angle.

I assume gpiozero just returns the angle you last requested. Given that you have not set an angle it is not surprising that 0 is returned (presumably the default value).

5
  • Appreciate the response, thank you for that, but I did set the servo to different angles before i ran this code, the output was still 0.0 and the servo still moved to a 90 degree position. Is there a way to receive the desired output ? i.e an accurate reading of the servo motors angle.
    – Coder
    Commented Mar 14, 2023 at 15:59
  • Do you mean you manually rotated the servo before running the code? Be careful you can damage the gears. As the code does not set an angle the gpiozero default of 0 will be sent to the servo. This will always be the servos central position. Some expensive servos include encoders which can return the current position. It is a very rare feature.
    – joan
    Commented Mar 14, 2023 at 16:13
  • I appreciate you indulging in our conversation, by manually I meant I rotation the servo to different angles using another program I wrote, I didn't physically rotate the servo. The servo I am using is an sg-90, you think it has the feature ? I tried the same code with additional code that presets servo value as per user input and then checks the servo's angle. It would set it to the entered angle but it would still return 0.0 and turn the servo to 90 degree . Is it because the sg-90 does not have the required features ?
    – Coder
    Commented Mar 14, 2023 at 16:38
  • You can not get the position of a sg-90 servo from the servo itself. It will be the same answer for all 3-pin servos (ground, power, control). Remember a servo moves to an absolute angle. So 0 will always set the centre. It does not move to an angle relative to the current position.
    – joan
    Commented Mar 14, 2023 at 17:30
  • Yes, I did a bit more research and reached the same conclusion as you. I am moving towards a new circuit that includes a few extra devices like a potentiometer or a rotary encoder. Thanks again !!
    – Coder
    Commented Mar 15, 2023 at 16:56
0

You can try and correlate this yourself, as even different servos of the same make and model (nb. I've mostly only used cheap little things like generic SG90s) will have clear differences this way, and even the exact same servo may behave noticeably different at different points in time, and of course load changes things.

This seems to be true even when using a dedicated servo/PWM board or a clock-tied microcontroller such as on the Arduino (the Pi PWM channels are clock-tied anyway).

I think the only way to get precise positioning with a servo is to have some independent system of locating/calibrating it. I've done this with a continuous rotation servo that had a fair bit of gear on top, including a Pi Zero and an Arduino, using a photoresistor at the top of a tube that extended from the top almost all the way to the bottom of the servo, which was mounted on a plastic plate with 12 or 16 leds mounted in it at the same radius as the tube. By lighting up one led, I could rotate the servo to an exact point because the signal (light from the led) attenuated very rapidly because of the tube (making it easy to center it directly over the led). I also had a routine at start up where I'd light them all up, it would rotate to one, then they were turned off one by one (the interval could be quite short, 100 ms or so) to locate the position.

I in fact do not recommend that at all, it was ponderous and a lot of work. However, you get the idea; using hall effect sensors the same way might be better (guessing...). Finally, if you really want precise control a stepper motor is probably a better choice.

3
  • Thank you for the response, I must say the idea of the led strip was pretty unique and intelligent. I don't think I will be using that method though because I want to conserve space on my project. I do think you're right about having an independent system to check the angle of the servo is the right way to go. I'm going to think of an independent measuring system that fits in a smaller space and if that doesn't work I'll probably end up using a potentiometer or a rotary encoder. Would you say using any of the 2 devices mentioned above is a better solution ?
    – Coder
    Commented Mar 14, 2023 at 15:55
  • I'm not actually an electronics expert; a major reason I persisted with that led thing was it provided me a learning opportunity WRT transistor control of the led array (they weren't each on a gpio, I used a darlington array I think..). I haven't used a rotary encoder -- the "optical" variety sounds like a refined version of my idea! -- but it does seem to precisely fit the bill.
    – goldilocks
    Commented Mar 14, 2023 at 16:40
  • Nice !! I am going to try the stuff I mentioned above now, I am looking forward to it. I can let you know how it turns out if you wish.
    – Coder
    Commented Mar 15, 2023 at 16:58
0

RC models servos behaves as an open loop (no feedback) from the controller point of view, you set the desired angle by modulating the PWM signal (this could be easily done trough a library) and the servo tries to reach that angle. Without any external feedback input it's impossible to know if and when the servo reaches the desired position and you can only assume the servo position by reading the set value.

An interesting option would be using Adafruit custom servo supplied with and analog feedback output: https://learn.adafruit.com/analog-feedback-servos

You could even customize your own servo as the feedback output is just a cable: https://www.instructables.com/Servo-Feedback-Hack-free/

Interfacing such servos to a rapsberry is not straight forward as you need an ADC to convert the analog feedback to a digital value, but this is another topic.

Hope this help

1
  • Thanks for the response, I did find some other pieces of hardware to measure the angle of the servo. I'll try your suggestions as well and sorry for the late response. Again thanks a tone.
    – Coder
    Commented Mar 25, 2023 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.