0

I am using a Raspberry Pi 3 to control a servo motor (via PWM with RPi.GPIO) and a Pi Camera. What I want to do is, I want to move the servo motor several hundred times to a specific position. In order to avoid that the servo slightly changes the position, I stop the pwm inbetween movements. The following Python code is working well:

import RPi.GPIO as GPIO
import time
from picamera import PiCamera
import numpy as np

## settings for Servo motor control (forward and backward movement)
FW = 8.5
BW = 7.4

#GPIO.setwarnings(False)
camera = PiCamera()

# use GPIO pin numbering convention
GPIO.setmode(GPIO.BCM)

# define GPIO pin for PWM (for the servo motor)
ServoPin = 25

# set pin 25 servo pin for output
GPIO.setup(ServoPin, GPIO.OUT)

ISI = 10
n = ISI - 1
stim = [n*i for i in range(0,150)]

lastStimOn = stim[-1]
print lastStimOn

current_date = (time.strftime("%y%m%d"))
current_time = (time.strftime("%H%M%S"))

automatic_name = "".join(("/home/pi/Desktop/", current_date, "_", current_time, "_ISI", str(ISI), ".h264"))
camera.start_recording(automatic_name)
print(automatic_name)
time.sleep(10)
camera.stop_recording()

This works well, the video is recorded. But if the following code is then run, the servo stops after moving 240 times (although it should move more often) and the video file that is created, does not include any data (it has a size of only 19 bytes):

stimON = np.array(stim)
stimOFF = stimON + 5

# create object for PWM at 50 Hz
pwm = GPIO.PWM(ServoPin, 50)

# set Timer to 0
Timer = 0

try:
    for x in range(0, (lastStimOn+120)):
        print (x, Timer)
        Timer = Timer + 1
        time.sleep(0.1) # run this line, if you want to speed up
        #time.sleep(1)

        if any(stimON == Timer):
            pwm = GPIO.PWM(ServoPin, 50)
            # move dummy forwards
            pwm.start(FW)
            # wait 0.5 sec
            time.sleep(0.5)
            # stop PWM output
            pwm.stop()

        if any(stimOFF == Timer):
            pwm = GPIO.PWM(ServoPin, 50)
            pwm.start(BW)
            time.sleep(0.5)
            pwm.stop()
        if (Timer == (lastStimOn-5)):
            current_date = (time.strftime("%y%m%d"))
            current_time = (time.strftime("%H%M%S"))
            automatic_name = "".join(("/home/pi/Desktop/", current_date, "_", current_time, "_ISI", str(ISI), ".h264"))
            camera.start_recording(automatic_name)

        if (Timer == (lastStimOn+119)):
            camera.stop_recording()
            Timer = 0
            RUN = False
            pwm = GPIO.PWM(ServoPin, 50)
            pwm.start(BW)
            time.sleep(0.5)
            pwm.stop()
            GPIO.cleanup()

except KeyboardInterrupt: # If CTRL+C is pressed, exit cleanly:
    GPIO.cleanup() # cleanup all GPIO
    print "Finished"

Does anyone have encountered this problem as well? Can someone having a PiCamera run this code and try to reproduce the problem I have? What can I do to avoid it? Any ideas? Thanks,
Steffi

2 Answers 2

1

You really shouldn't be controlling servos with software timed pulses.

However that is not the problem with the code.

Have a look through http://sourceforge.net/p/raspberry-gpio-python/tickets

I think the problem is the stop/start of PWM which is not needed and eventually crashes the module.

1
  • Thanks, that helped a lot. I am now using your pigpio library and it works great!
    – Steffi
    Commented Jun 9, 2016 at 9:52
0

At the point when you call camera.start_recording(automatic_name), you're inside a conditional that tests if (Timer == (lastStimOn-5)): . By my count lastStimOn is (((10 - 1) * 150) - 5) = 1345 at the time of the final loop iteration. You tell the camera to stop recording when Timer == (lastStimOn+119), which should therefore be at Timer = 1469. Unfortunately, presumably to speed up testing, you're incrementing Timer every 0.1 seconds, which means that your video clip is going to be (1469 - 1345)/10 = 12 seconds long. That should be long enough to achieve some kind of capture, but I suppose it's just about possible that the warm-up time required is reducing that to such a degree that you get a 19 byte file output.

1
  • 1
    12 sec is usually enough time. When I do a recording at a specific earlier time point, let's say 100, and then stop it after Timer has reached 100+120, it creates a proper video file with data in it. The 'broken' file might be related to the problem with the pwm, which I now have solved.
    – Steffi
    Commented Jun 9, 2016 at 9:57

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.