Raspberry Pi RC Car Design
-
Upload
nicolaas-dreyer -
Category
Documents
-
view
94 -
download
2
Transcript of Raspberry Pi RC Car Design
Nicolaas Dreyer
3/1/2015
Raspberry Pi RC Car Design
Page 1 of 11
Table of Contents Table of Contents .................................................................................................................................................................... 1
Design Overview ..................................................................................................................................................................... 2
Interface Board Schematic ...................................................................................................................................................... 3
Possible Interface Board Layout ............................................................................................................................................. 4
Interface Board BOM .............................................................................................................................................................. 5
Mechanical Parts (Brief) .......................................................................................................................................................... 5
Raspberry Pi Setup (Brief) ....................................................................................................................................................... 6
Raspberry Pi Python Code ....................................................................................................................................................... 7
References ............................................................................................................................................................................ 10
Page 2 of 11
Design Overview The goal of this design is to remotely control an RC car. The Wiimote has been chosen as a controller because of its ease-
of-use and simple Bluetooth communication. A Bluetooth dongle will receive the Wiimote’s commands so that they can
be interpreted and used to control the RC car’s movement. The device that will power the dongle and interpret the
information it relays is the Raspberry Pi, chosen for its versatility. An interface board with a rechargeable battery will, in
turn, power the Raspberry Pi and buffer its output signals to drive the various motors on the RC car. Designs for the
mechanical parts of the RC car are not included here because they will vary greatly depending on the materials available
and the car’s intended terrain. However, a brief list of the required mechanical parts has been included. The high-level
design is summarized in Figure 1.
Figure 1: High-Level Design of RC Car
Wiimote Controls
USB Dongle
Raspberry Pi
Interface Board
RC Car Motors
Page 3 of 11
Interface Board Schematic
Page 4 of 11
Possible Interface Board Layout
IC3 (L293D)
Extra L293D
IC1 (LM317)
IC2 (LM317)
STATUS
R5
R4
R1
R3
Capacitors
Servo Pins
RPI-12,
RPI-19
Motor Pins
RPI-10 RPI-8
R2 on other side
5V to RPi
VB
AT
Note: IC3 pins 10, 11, 14, and 15 unused here
VA
DJ
and
GN
D r
ails
Page 5 of 11
Interface Board BOM Qty Value Parts Description ==================================== 1 9.6V BAT1 RECHARGEABLE BATTERY 2 100n C1, C4 CAPACITOR 2 10u C2, C5 CAPACITOR 2 1u C3, C6 CAPACITOR 2 IC1, IC2 TO-220 LM317 VOLTAGE REGULATOR 1 IC3 DIP 16 L293D MOTOR DRIVER 7 OUTPUT PINS PIN HEADER 1 560 R1 RESISTOR 1 180 R2 RESISTOR 1 10k R3 POTENTIOMETER 1 1k R4 RESISTOR 1 330 R5 RESISTOR 1 5mm STATUS LED Additional parts not on schematic: Qty Value Description ==================================== 2 TO-220 HEAT SINK FOR LM317 1 7x5cm THROUGH-HOLE PC BOARD 4 PIN HEADER FOR RPI OUTPUT TO CONNNECT TO 4 FEMALE-FEMALE JUMPER CABLE TO CONNECT BETWEEN BOARD AND RPI N/A HOOK-UP WIRE AND SOLDER AS NEEDED Parts for optional headlights: Qty Value Description ==================================== N/A 5mm ULTRA-BRIGHT LED N/A 1k RESISTOR (1 PER LED)
Mechanical Parts (Brief) Description ========== DC motor(s) Gearbox (highly recommended) Servo motor Steering mechanism parts Suspension parts Chassis Wheels Fasteners Cable ties Adhesives
Page 6 of 11
Raspberry Pi Setup (Brief) 1. Flash an SD card with the latest version of Raspbian. Or you can simply update Raspbian if you’ve already been
running it on your RPi:
sudo apt-get update sudo apt-get upgrade
2. Install servoblaster [1]. For simplicity, have the executable servoblaster file in an accessible location.
3. Set up pin(s) and pulse-width modulation on servoblaster to control the servo. The settings will depend on the servo
you use. This will take some trial-and-error but the readme can help [2]. Note that servoblaster uses a different pin
mapping scheme. For example, I used pin 12 on the RPi to control my servo, which corresponds to servo number 2 in
servoblaster. Figure 2, produced by Matt Hawkins, shows the RPi Model B pins [3]. The RPi pin numbers referred to
in programs like servoblaster typically refer to those inside the circles and the RPi GPIO numbers are those in the
small rectangles.
Figure 2: RPi GPIO Pins [3]
4. Get a USB Bluetooth dongle working with the RPi. ASUS dongles work well. More information on compatible dongles
can be found here [4].
5. Connect a Wiimote to your RPi via the Bluetooth dongle and use it to control the motor(s) and servo. The Python
code I used to do this was modified from an example script I found [5]. For simplicity, make sure the .py file is in the
same directory as the executable servoblaster file. You will need to tailor the settings in the code to your specific
design, particularly the pulse-width modulation settings for servoblaster.
6. Run the Python code and make sure the Wiimote connects and controls the motors properly. Tweak the settings in
the code as needed.
7. Once you are satisfied with the settings, try running the program without having your RPi connected to a display.
The STATUS LED will prompt you when to connect the Wiimote:
STATUS LED State Interpretation
Off Not ready to connect to Wiimote
On Ready to connect to Wiimote
Flashing Failed to connect to Wiimote
8. To go fully screen-less, you will need to make a simple .py file that runs your code in a loop and runs as soon as you
boot into the LXDE environment. The .py file should be easy enough (a few lines) if you’ve been successful with the
code so far. A tutorial on running the .py file as soon as you boot into the LXDE environment can be found on this
page [6]. After this point, simply watch the STATUS LED for your cue to connect the Wiimote. If you fail to connect
the first time, wait for the LED to turn solid again in the next loop.
Page 7 of 11
Raspberry Pi Python Code
Below is a modified version of Matt Hawkins’ example script that can be used to control an RC car with a Wiimote [5].
#!/usr/bin/python
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k|
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
# wii_remote_1.py
# Connect a Nintendo Wii Remote via Bluetooth
# and read the button states in Python. Use the
# button states to control an RC car.
#
# Project URL :
# http://www.raspberrypi-spy.co.uk/?p=1101
#
# Author : Matt Hawkins
# Date : 30/01/2013
#
# RC car modifications by : Nicolaas Dreyer
# Date modified : 19/12/2014
# -----------------------
# Import required Python libraries
# -----------------------
import cwiid
import time
import os
#------------------------
# Car setup
#------------------------
import RPi.GPIO as GPIO # GPIO configuration
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
FWD = 10 # Pin for Forward control
REV = 8 # Pin for Backward control
LED = 19 # Pin for LED status light
GPIO.setup(FWD, GPIO.OUT)
GPIO.setup(REV, GPIO.OUT)
GPIO.setup(LED, GPIO.OUT)
LOW = False # GPIO settings (LOW = 0V, HIGH = 5V)
HIGH = True
os.system("sudo ./servod") # Start servoblaster
os.system("clear") # Hide annoying servoblaster messages
RIT = "echo 2=95 > /dev/servoblaster" # Servo movement commands
LFT = "echo 2=65 > /dev/servoblaster"
STR = "echo 2=80 > /dev/servoblaster"
DEL = 0 # Wait time (if necessary)
Page 8 of 11 # Function to drive the car; controls direction and steering:
def drive(pin1, dir1, pin2, dir2, turn, wait):
"drive_the_car"
GPIO.output(pin1, dir1) # Configure first pin
GPIO.output(pin2, dir2) # Configure second pin
os.system(turn) # Control the servo
time.sleep(wait) # Wait (if necessary)
return
#------------------------
# Wiimote setup
#------------------------
button_delay = 0.1
GPIO.output(LED, HIGH) # Indicate that program has started
print 'Press 1 + 2 on your Wii Remote now ...'
time.sleep(1)
# Connect to the Wii Remote. If it times out then quit.
try:
wii=cwiid.Wiimote()
except RuntimeError:
print "Error opening wiimote connection"
GPIO.output(LED, LOW) # Flash error status
time.sleep(0.5)
GPIO.output(LED, HIGH)
time.sleep(0.5)
GPIO.output(LED, LOW)
GPIO.cleanup() # Reset pins on exit
quit()
wii.rumble = 1
time.sleep(0.5)
wii.rumble = 0
GPIO.output(LED, LOW)
print 'Wii Remote connected...\n'
print 'Press some buttons!\n'
print 'Press PLUS and MINUS together to disconnect and quit.\n'
wii.rpt_mode = cwiid.RPT_BTN
#-------------------------
# Control sequence
#-------------------------
while True:
buttons = wii.state['buttons']
# If Plus and Minus buttons pressed
# together then rumble and quit.
Page 9 of 11 if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):
print '\nClosing connection ...'
wii.rumble = 1
time.sleep(0.5)
wii.rumble = 0
os.system(STR) # Turn wheels straight
os.system("sudo killall servod") # Kill servo
GPIO.cleanup() # Reset pins
exit(wii)
# Check if other buttons are pressed by
# doing a bitwise AND of the buttons number
# and the predefined constant for that button.
if (buttons - cwiid.BTN_B == 0): # Forward
print 'Forward'
drive(REV, LOW, FWD, HIGH, STR, DEL)
time.sleep(button_delay)
if (buttons - cwiid.BTN_LEFT - cwiid.BTN_B == 0): # F+Left
print 'F+L'
drive(REV, LOW, FWD, HIGH, LFT, DEL)
time.sleep(button_delay)
if (buttons - cwiid.BTN_RIGHT - cwiid.BTN_B == 0): # F+Right
print 'F+R'
drive(REV, LOW, FWD, HIGH, RIT, DEL)
time.sleep(button_delay)
if (buttons - cwiid.BTN_A == 0): # Backward
print 'Backward'
drive(REV, HIGH, FWD, LOW, STR, DEL)
time.sleep(button_delay)
if (buttons - cwiid.BTN_LEFT - cwiid.BTN_A == 0): # B+Left
print 'B+L'
drive(REV, HIGH, FWD, LOW, LFT, DEL)
time.sleep(button_delay)
if (buttons - cwiid.BTN_RIGHT - cwiid.BTN_A == 0): # B+Right
print 'B+R'
drive(REV, HIGH, FWD, LOW, RIT, DEL)
time.sleep(button_delay)
if (buttons - cwiid.BTN_LEFT == 0): # Left
print 'Left'
os.system(LFT)
time.sleep(button_delay)
if (buttons - cwiid.BTN_RIGHT == 0): # Right
print 'Right'
os.system(RIT)
time.sleep(button_delay)
Page 10 of 11 # Unused buttons that can be mapped:
if (buttons & cwiid.BTN_UP):
print 'Up pressed'
time.sleep(button_delay)
if (buttons & cwiid.BTN_DOWN):
print 'Down pressed'
time.sleep(button_delay)
if (buttons & cwiid.BTN_1):
print 'Button 1 pressed'
time.sleep(button_delay)
if (buttons & cwiid.BTN_2):
print 'Button 2 pressed'
time.sleep(button_delay)
if (buttons & cwiid.BTN_HOME):
print 'Home Button pressed'
time.sleep(button_delay)
if (buttons & cwiid.BTN_MINUS):
print 'Minus Button pressed'
time.sleep(button_delay)
if (buttons & cwiid.BTN_PLUS):
print 'Plus Button pressed'
time.sleep(button_delay)
# Brake if no buttons pushed:
if (buttons == 0):
drive(REV, LOW, FWD, LOW, STR, DEL)
References
[1] The Raspberry Pi Foundation, "Servos and servoblaster in Python...," 28 August 2013. [Online]. Available:
http://www.raspberrypi.org/forums/viewtopic.php?f=44&t=54067. [Accessed 1 March 2015].
[2] R. Hirst, "GitHub," GitHub, Inc., December 2013. [Online]. Available:
https://github.com/richardghirst/PiBits/tree/master/ServoBlaster. [Accessed 1 March 2015].
[3] M. Hawkins, "Simple Guide to the RPi GPIO Header and Pins," 9 June 2012. [Online]. Available:
http://www.raspberrypi-spy.co.uk/2012/06/simple-guide-to-the-rpi-gpio-header-and-pins/. [Accessed 1 March
2015].
[4] eLinux.org, "RPi USB Bluetooth adapters," 19 January 2015. [Online]. Available:
http://elinux.org/RPi_USB_Bluetooth_adapters. [Accessed 1 March 2015].
Page 11 of 11
[5] M. Hawkins, "Nintendo Wii Remote, Python and The Raspberry Pi," 30 January 2013. [Online]. Available:
http://www.raspberrypi-spy.co.uk/2013/02/nintendo-wii-remote-python-and-the-raspberry-pi/. [Accessed 1 March
2015].
[6] Stack Exchange Inc., "Execute script on start-up," 8 November 2013. [Online]. Available:
http://raspberrypi.stackexchange.com/questions/8734/execute-script-on-start-up. [Accessed 1 March 2015].
Cover picture credit: K. Ho, "Photo of Nicolaas Dreyer's RC Car," IEEE BCIT Student Branch, Burnaby, 2014.