RoboVero with RC Servo, Xbox 360 Controller, and Webcam

In our very first rainy day project we are going to convert your boring old webcam into a gamepad-controlled, panning webcam. This should take less than an hour if you have all of the materials and the Python Client Library installed on your development system.

 

Materials:

 

  • Gumstix RoboVero expansion board
  • Continuous rotation RC servo
  • Xbox 360 Controller
  • Webcam
  • Cardboard box
  • Xacto knife

 

Assembly:

 

  • Cut a rectangle in the bottom of the box to fit the servo. Now, flip the box over and insert. The mounting flanges will keep the servo from falling through. Your webcam should now stick out of the base with the servo wires hanging inside.
  • Cut out slots in one side of the base for all three USB connectors (two A and one mini-B) and a hole for the power adapter.
  • Put RoboVero inside the box and plug in the webcam, USB controller, USB cable to your computer, and power adapter from the outside. If you were careful with your cutting and the base is somewhat rigid, these should hold the board in place.
  • Reach inside the base and connect the servo to PWM1.
  • That’s it. If you want to be fancy you can use a plastic or metal case and screw everything together. Otherwise, let’s get to the code.

 

Software:

 

import pygame
import Image
from pygame.locals import *
import opencv
from opencv import highgui

from robovero.LPC17xx import LPC_PWM1
from robovero.lpc17xx_pwm import PWM_TC_MODE_OPT,
          PWM_MATCH_UPDATE_OPT, PWM_MATCHCFG_Type,
          PWM_MatchUpdate, PWM_ConfigMatch, PWM_ChannelCmd,
          PWM_ResetCounter, PWM_CounterCmd, PWM_Cmd
from robovero.extras import roboveroConfig, initMatch
from robovero.lpc_types import FunctionalState

def get_image():
  """Capture an image from the webcam.
  """
  im = highgui.cvQueryFrame(camera)
  im = opencv.cvGetMat(im)
  return opencv.adaptors.Ipl2PIL(im)

# start pygame
fps = 30.0
pygame.init()
window = pygame.display.set_mode((640,480))
pygame.display.set_caption("Panning Webcam")
screen = pygame.display.get_surface()

# start the joystick
if (pygame.joystick.get_count() < 1):
  exit("error: no joystick found")
gamepad = pygame.joystick.Joystick(0)
gamepad.init()

# start the camera
camera = highgui.cvCreateCameraCapture(0)
if not camera:
  exit("error: no camera found")

# start the servo
roboveroConfig()
initMatch(0, 20000)                             # period = 20000us = 20ms = 50Hz
initMatch(1, 1500)                                         # pulse width = 1.5ms
PWM_ChannelCmd(LPC_PWM1, 1, FunctionalState.ENABLE)
PWM_ResetCounter(LPC_PWM1)
PWM_CounterCmd(LPC_PWM1, FunctionalState.ENABLE)
PWM_Cmd(LPC_PWM1, FunctionalState.ENABLE)

while True:
  # check for joystick position change
  events = pygame.event.get()
  for event in events:
    if event.type == QUIT or event.type == KEYDOWN:
      exit(0)
    if event.type == JOYAXISMOTION:
      if event.axis == 0:
        match_value = 1500 + (event.value*25)
        PWM_MatchUpdate(
            LPC_PWM1,
            1,
            match_value,
            PWM_MATCH_UPDATE_OPT.PWM_MATCH_UPDATE_NOW
            )

  # capture and display an image
  im = get_image()
  pg_img = pygame.image.frombuffer(im.tostring(), im.size, im.mode)
  screen.blit(pg_img, (0,0))
  pygame.display.flip()

  # wait to get the next frame
  pygame.time.delay(int(1000 * 1.0/fps))