3

I'm writing a program which requires Servo's basic movement. Here's the code:

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
pwm = GPIO.PWM(18, 100)
pwm.start(5)


def update(angle):
    duty = float(angle) / 10.0 + 2.5
    output = pwm.ChangeDutyCycle(duty)
    print output

def loop():
        update(170)
        time.sleep(1)
        update(20)
        time.sleep(1)

def main():
        i=0
        while i<3:
                loop()
                i+=1
        return 0

if __name__=="__main__":
    main()

It works very well - no questions about that. However I also would like to check if servo is available/connected to the port. However if I unplug it the program works just fine. I do understand that basically I'm sending the signal to a registered PWM port and that it reaches the port but there is nothing to read it. The question is - is there a possible solution for this? Maybe I should read data from the port and check if it's empty or is there a macro defined for it. Thanks!

2

I do understand that basically I'm sending the signal to a registered PWM port and that it reaches the port but there is nothing to read it.

Yes, but there's a distinction here which complicates things -- although I'm not an RPi.GPIO (or python) user I would assume it applies.

PWM pulses need to be precisely timed without depending on CPU instructions, since on a multitasking OS the CPU cannot be counted on for this purpose and forcing it to do so would be (very) detrimental to system performance. So there are dedicated bits of SoC hardware which can be controlled and run independently much like other peripherals. The fundamental component of this is a 19.2 Mhz clock, which can be processed into two independent channels. Each of the PWM pins (12, 13, 18, 19) is wired to one of these channels, so when you control the pulse what you are actually controlling is connected to two pins, although whether they actually output this signal depends on the mode set on them.

Anyway, that clock and the channels just run whenever the power is on, regardless of whether they are used to do anything (there may be things the clock is always used for other than PWM, I don't know). The same will apply to pins set to carry their signal.

In short, I do not think there a way to detect if anything beyond the pin is making use of the signal; this also applies to outputs. However, setting the pin as an input may produce a predictable result, or it may "float" as it does when disconnected (i.e., read as either high or low). The problem with relying on this is there's no way to differentiate a chance reading on a floating pin from one which is pulled up or down by a connection, unless perhaps you experimented with polling the pins to see how likely no variance is likely to happen on a disconnected pin over a duration -- but I doubt that will be very reliable either.

The solution is to add some additional circuitry, preferably something which would set an input high when the servo is connected. Of course, that is likely to complicate the processes of attaching and detaching servos. The two things I can think of off the top of my head both involve a 3-pole switch, the kind where in one position wires A and B are connected, and the other, B and C.

  1. Switch between 5V and servo, assuming you are using 5V for the servo. "B" is the voltage source, "A" is the servo, "C" is an appropriate voltage divider with a GPIO input on Vout. While the switch is off, that GPIO will be pulled high. This idea means wasting power while the servo is off though, which is particularly bad if you are actually using batteries as a ~6V power source.

  2. Switch between the control line and the servo, "B" is the control, "A" is again the servo, "C" is another GPIO set as an input (you can connect an output directly to an input), the input set with a pull-up and the output on low. While the switch is off (B -> C), the input will be low, when it is on (B -> A) the input will be pulled high.

Both of these ideas mean you have to use the switch when you plug in the servo.

  • Thank you for your prompt reply. Do you have a suggestion for which scheme should I implement? I have connected servo to 4AAA(sequential) source, I just tried putting LED between + and servo voltage input - LED worked, but servo didn't - not enough power I'd assume – Constantine Samoilenko Jun 7 '16 at 12:44
  • I've added a couple of suggestions at the end, but I also suggest you ask it as a separate question, referencing this one, to see what ideas other people have -- I'm no electronics expert, I've just learned a lot about and via the pi over the past few years. So there may be something much simpler that doesn't occur to me. – goldilocks Jun 7 '16 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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