karlherrick.com

Controlling a Lego motor with the Raspberry Pi

Monday, 03 February 2014

Raspberry Pi and Gertboard controlling a 4.5v Lego motor #6216m

When the Gertboard originally came out, it was a do it yourself kit that required soldering, and it had enough pieces that made me want to wait until one was offered pre-assembled (you can still get one like the original from Tandy called the Multiface Kit). After purchasing the latest version, I tried putting one of the Lego motors we have around the house through its paces. Using one of the older models (4.5v Lego motor #6216m) and learning from the examples in the Python Gertboard Suite made crafting my own setup surprisingly easy.

The main steps were to code a motor controlling script in Python (see lego-motor-control.py), and demo it in Bash (see lego-motor.sh). I find tinkering around with these components immensely rewarding while exploring topics like the Internet of Things. This type of exploration will only get easier as time goes on, for example, I just noticed today that Gert van Loo created something called the Gertduino. It is similar to the original product, but much smaller and easier to use. What kind of fun projects could be implemented with even smaller kit like TinyDuino or Intel Edison? I do like sticking with the Pi for now, so I dug up a list of compatible shields for your perusal (or browse an even larger list of expansion boards @ elinux.org):

Also, check out the video to get an idea on how the Lego motor and scripts ended up working out:

lego-motor.sh

#!/bin/bash
echo -e "Turning the lego motor right for five seconds...\n"
sudo python ~/lego-motor-control.py right &
pid=$!
sleep 5
sudo kill -INT $pid

echo -e "\nSleeping for three seconds to let the motor wind down\n"
sleep 3

echo -e "Turning the lego motor left for five seconds...\n"
sudo python ~/lego-motor-control.py left &
pid=$!
sleep 5
sudo kill -INT $pid

lego-motor-control.py

#!/usr/bin/env python
import RPi.GPIO as GPIO
import collections, signal, sys
from time import sleep

# get command line arguments
arg_names = ['command', 'direction']
args      = dict(zip(arg_names, sys.argv))
arg_list  = collections.namedtuple('arg_list', arg_names)
args      = arg_list(*(args.get(arg, None) for arg in arg_names))

# set initial values
step      = 1
mota      = 18
motb      = 17
left      = motb
right     = mota
reps      = 400
hertz     = 2000
freq      = (1 / float(hertz)) - 0.0003
ports     = [mota,motb]
percent   = 100

# function to run the motor
def run_motor(reps, pulse_width, port_num, period):
    for i in range(0, reps):
        GPIO.output(port_num, True)
        sleep(pulse_width)
        GPIO.output(port_num, False)
        sleep(period)

# trap SIGINT and provide a clean exit path
def signal_handler(signal, frame):
    GPIO.output(direction, False)
    GPIO.cleanup()
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)

GPIO.setmode(GPIO.BCM)

# initialize the ports being used
for port_num in ports:
    GPIO.setup(port_num, GPIO.OUT)
    print "setting up GPIO port:", port_num
    GPIO.output(port_num, False)

# determine direction or set a default
if args[1] == "left":
    direction = left
elif args[1] == "right":
    direction = right
else:
    direction = right

# the main loop
while True:
    pulse_width = percent / float(100) * freq
    period      = freq - (freq * percent / float(100))
    run_motor(reps, pulse_width, direction, period)


Home

About

Portfolio

Web Apps Web Enabled Applications Corporate Sites Personal Sites
Preferences Dark Theme Light Theme Notifications
Social GitHub LinkedIn RSS Feed Icon