EE – 3332 – 001 Project Lab 3: Group #6 B.E.S.T. Remote / Alternative System Nathan Roseborrough December 10, 2004 Instructor: Dr. Dickens Advisor: Dr. Parten Team Members: Joshua Crabtree, Muneem Shahriar, Chris David, Chuck Morton Department of Electrical Engineering Texas Tech University 1
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
EE – 3332 – 001
Project Lab 3: Group #6
B.E.S.T. Remote / Alternative System
Nathan Roseborrough
December 10, 2004
Instructor: Dr. Dickens
Advisor: Dr. Parten
Team Members: Joshua Crabtree, Muneem Shahriar, Chris David, Chuck Morton
Department of Electrical Engineering
Texas Tech University
1
Abstract
This report will detail the design and construction of a wireless control system intended for
usage by the B.E.S.T. organization. Traditionally, a four channel commercial hobby transmitter and
receiver have been used. Due to the ever-improving nature of the B.E.S.T. organization, a more
advanced and less costly system is needed. The goal of this project is to design one such system. The
alternative system has expanded user interface capabilities and is intended to be less costly than a
The B.E.S.T. (boosting engineering science and technology) organization is a volunteer-run non-profit
robotics competition for students. Held annually, the national competition draws 8000 students from over 700
schools.
Figure 1: B.E.S.T. Competition Event
Each school is given an identical kit consisting of building materials and remote control components. Using
only materials from the kit, students engineer and build a robot for competition. The robots use a traditional
four channel hobby radio control system, operating in the 75MHz frequency range.
Figure 2: Typical Futaba transmitter (left) and receiver (right)
The existing system is becoming increasingly expensive to maintain, and many feel that the limited
control capabilities are hindering the full creativeness of the competing teams. The “speedy-33” digital signal
5
processor is part of the solution, allowing full programmability of robot behavior. However at the time of
writing there is no suitable system to allow remote control of the speedy-33.
Figure 3: Speedy-33 DSP
It is the intention of the project lab 3 students to design and build an alternative replacement system that will
both expand the control capabilities and cost less to implement than the existing control system. This
alternative system is to use the same frequencies designated by the FCC for hobby remote control usage, as
well as conform to all requirements placed on RF devices operating in this range.
Design Considerations
To replace the existing system effectively it is important to understand the full functionality of a hobby radio
control system. The user interacts with the handheld transmitter via 2 joysticks. Each joystick consists of a
vertical stick which manipulates two internal potentiometers. The resistance of these potentiometers is
encoded and used to modulate an FM signal at a frequency dependent upon one of thirty crystals. These
frequencies are 20kHz apart, and span 75.41 MHz to 75.99 MHz. The modulated signal is then transmitted to
the receiver and demodulated using a dual downconversion scheme. The demodulated signal is processed
into seven servo-compliant pulse width modulated signals. The receiver module is able to decode signals
from a transmitter using up to seven inputs, however the system currently in place uses only four. The end
6
result is a system which allows a user to alter servo positions (or other compatible peripherals) in a manner
directly proportional to the input applied on the joysticks.
Input Device
Many input devices were analyzed for usage in a replacement system. Early candidates included computer
keyboard, mouse, trackball, analog joysticks (for computer use), and game console controllers. The computer
keyboard, mouse, and trackball were eliminated since they did not provide 4 axis analog control. Computer
joysticks, while allowing the same four axis control, use USB interfaces. Older designs used a strict analog
signal which was then encoded by the host computer, but retailers which offer this type of joystick are
dwindling. The USB interface requires a host controller. These are difficult and costly to develop and require
software drivers to communicate properly. These drivers are often copyrighted and patented by the
manufacturer and are unavailable in formats other than x86 binary files. Game console controllers are the
obvious choice for this system. Game controllers are designed specifically to provide a comfortable, intuitive,
inexpensive, and versatile method for interaction with a large variety of games. These also prove ideal for the
control of a robot. The controllers for gaming systems currently in production were compared. The three
competing systems are the Microsoft Xbox, Sony Playstation, and the Nintendo Gamecube.
Figure 4: Game controllers, left to right, Sony Playstation, Microsoft Xbox, Nintendo Gamecube
The Microsoft Xbox controller is a USB device with an incorporated two port hub, used for memory
cards. It provides the user with two analog joysticks, two single axis analog triggers, and 16 digital buttons.
7
This controller was eliminated due to its requirement of a costly USB host controller. The Nintendo
Gamecube controller provides two analog joysticks, two triggers, and ten digital buttons. The interface is a
proprietary protocol used by the Nintendo game system family, and could easily be decoded using a
microcontroller. The Sony Playstation “dual shock” controller sports two analog joysticks and sixteen digital
buttons. The interface protocol is comprised of bi-directional clock controlled serial data transfer. This
controller was chosen since Playstation controllers offer backwards compatibility, and interface information is
readily available.
The Playstation controller uses a proprietary nine pin connector. An aftermarket female connector was
selected to allow usage of the controller without need for modification.
Figure 5: Playstation controller cable adapter
To communicate with the controller, a PIC16F676 was chosen. This microcontroller is programmed
in “picbasic” using the PicBasic Pro compiler from MeLabs. The pins of the controller are directly connected
to the PIC microcontroller, with only a single pull-up resistor on the “data” pin. The goal of the PIC is to
emulate communications from a Playstation game console.
8
LOOKING AT THE PLUG
------------------------------- PIN 1-> o o o | o o o | o o o |
\_____________________________/
Figure 6: Diagram of Playstation controller connector
The VCC and GND pins are connected directly to the same power supply used by the microcontroller. The
“data” pin is connected to an I/O pin on the microcontroller and pulled high by a 20Kohm pull-up resistor.
This pin is an open collector input, and is pulled low by the Playstation controller to transmit data to the
microcontroller. The “command” pin is driven directly by an I/O pin and is used to send data to the
Playstation contoller. The “att” pin is also driven directly, and is used to control data transfer to and from the
controller. The “clock” pin is directly driven and controls the actual data transfer. The “ack” pin is used for
error correction and is unused in this system.
To read the state of the buttons and joysticks, a simple transmit and receive algorithm is used. The controller
is polled indefinitely in a loop to provide continuous control data. To initiate communications, the “ATT” pin
is driven low. The PIC then drives the “command” pin high or low, depending on the least significant bit of
the byte being transmitted. The clock pin is then driven high, which triggers the controller to read the state of
the “command” pin. The PIC then reads the state of the “data” pin. A slight delay occurs, the “clock” pin is
driven high, another delay occurs, and the process repeats. Each time a bit is read it is placed into the most
significant bit and shifted right. After this process occurs eight times, a full byte of data is buffered and the
next byte is ready to be read.
To poll the controller, the byte 0x01 is sent, then the byte 0x42 is sent at the same time the controller sends its
identifier. The “command” pin then idles (high) as the controller streams six bytes. These six bytes
correspond directly to the state of the buttons and the position of the analog joysticks.
9
BYTE CMND DATA
01 0x01 idle 02 0x42 0x73 03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 04 idle data SLCT JOYR JOYL STRT UP RGHT DOWN LEFT 05 idle data L2 R2 L1 R1 /\ O X |_| 06 idle data Right Joy 0x00 = Left 0xFF = Right 07 idle data Right Joy 0x00 = Up 0xFF = Down 08 idle data Left Joy 0x00 = Left 0xFF = Right 09 idle data Left Joy 0x00 = Up 0xFF = Down
Figure 7: Sequence of data during controller communication
After receiving a full packet, the microcontroller formats and sends the data at 1200 baud on a standard RS-
232 connector. The sent data consists of a start byte followed by the controller identifier, which is then
followed by the button and position data, then ended with a stop byte.
The Playstation controller communication system is housed in a separate enclosure, and interfaces with the
transmitter (or a computer) via a standard RS-232 port. This arrangement is advantageous for several reasons.
Interference between the input system and the transmitter will be reduced, for example, and the usage of an
RS-232 connector allows the transmitter to be used with any device capable of serial communication (e.g. a
laptop.)
Transmitter
The existing transmitter system is incorporated into the same housing as the joysticks. The existing system is
designed for operation on one of 30 channels, which is changed by swapping the oscillator crystal. FM
modulation is used to send encoded data corresponding to the joystick positions.
The replacement for this system will operate on the same frequencies, but will transmit encoded serial data.
This will allow operation as a one-way serial modem. The transmitter will use FM FSK modulation.
Appendix 1: PSX.BAS Playstation controller interpreter program code listing
'****************************************************************'* Name : PSX.BAS *'* Date : 9/13/2004 *'* Version : 0.1.0 *'* Notes : This program is designed to communicate with a *'* Playstation 1 "dual shock" controller. Originally*'* written as part of a larger control system, this *'* implementation can be used as a generic PSX *'* controller interpreter. *'* : *'* Author : Nathan Roseborrough *'* *'* Version *'* Info 0.0.1 First successful 0.0.1 compile *'* 9/15/04 - 12:06pm *'* Project enters 0.1.0 *'* 0.1.1 Target processor changes from 18F1320 to *'* 16f676 to overcome cross assembling issues *'* 1.0.0 First successful communication *'* 1.0.1 Added: *'* -Weak Pull-up resistors * '* Fixed: *'* -Bit shifting issue in psx comm rountine*'* 1.1.0 Demonstration version for proof of comm. *'* 1.1.1 Removed demo setup, added streaming packet * '* *'* Todo -powerup calibration routine *'* -steering wheel support *'* -external serial detection and support *'* -GPS-like packets to save bandwidth *'* -implement ACK checking *'****************************************************************
'****************************************************************'*** BUG TRACKER SECTION ******************************* :) *****'****************************************************************'*** Date: Bug: ***'** **'* 10/5/04 While in digital controller mode, the "square" *'* button does not report to the proper bit. a *'* simple change in bit assignment may fix this. *'* 10/5/04 While in digital controller mode, serial output *'* timings are distorted. Delays in program and *'* controller interference may be culprits. *'* Fixed - output format change fixed problem. *'** **'*** ***'****************************************************************
include "modedefs.bas" 'used for mode definitions
Define OSC 4 'clock frequency is 4mhz
20
'****************************************************************'* Chip Configuration *'****************************************************************'* Configure registers specific to the 16F676. This is vital *'* since the on-board peripherals (comparator, A/D conv.) can *'* interfere horribly with digital I/O. *'****************************************************************OPTION_REG = OPTION_REG | %10000000 'enable porta weak pull-up resistorsADCON0 = %00000000 'disable analog to dig convertersANSEL = %00000000 'select digital mode for a/d pinsCMCON = %00000111 'disable comparitor mode on port ATRISA = %00000010 'set up PortA.1 as an inputWPUA = %00000011 'turn on porta.0 and 1 resistorsTRISC = %00010001 'port c direction register
'****************************************************************'* I/O Pin Aliases *'****************************************************************'* Making plain-english aliases to the physical pins eases *'* programming and allows changes to pin numbers without further*'* modification of the source code (e.g. porting to a different *'* target PIC device) *'****************************************************************SerialOut VAR PORTA.0 'serial out to targetCData var PORTA.1 'Controller Data inCommand var PORTC.1 'Command OutATT VAR PORTC.2 'Attention PinClock VAR PORTC.3 'ClockACK VAR PORTC.4 'Acknowledge pin
clockdelay con 2 'delay constant for serial transmissiondeadzone con 20 'thumbstick deadzoneButtons VAR BYTE 'to optimize compilation, bits are part of a larger bytedpad_up var Buttons.0 'direction pad updpad_down var Buttons.1 'direction pad downdpad_left var Buttons.2 'direction pad leftdpad_right var Buttons.3 'direction pad righttriangle var Buttons.4 'triangle buttonX var Buttons.5 'X buttonsquare var Buttons.6 'square buttoncircle var Buttons.7 'circle buttonTriggers Var Byte 'triggers encompases the remaining buttonsselct var Triggers.0 'select buttonstart var Triggers.1 'start buttonlt1 var Triggers.2 'left trigger 1lt2 var Triggers.3 'left trigger 2rt1 var Triggers.4 'right trigger 1rt2 var Triggers.5 'right trigger 2pushdown_l var Triggers.6 'analog stick pushdown buttons
21
pushdown_r var Triggers.7LanY var byte 'left analog stick y axisLanX var byte 'left analog stick x axisRanY var byte 'right analog stick y axisRanX var byte 'right analog stick x axiscont_id var byte 'controller identifier byteinbuffer var byte 'playstation input bufferoutbuffer var byte 'playstation output bufferI var BYTE 'integer used in loops
'****************************************************************'* Main Program Start *'****************************************************************
'****************************************************************'* Power on initialization *'****************************************************************'* Variables are initialized and the clock and attention pins *'* are pulled high to prepare for communication. *'****************************************************************Initialize: Buttons = $FF 'All buttons are active low Triggers = $FF 'Set initial state as no buttons pressed LanX = $80 LanY = $80 RanX = $80 RanY = $80 high ATT 'Attention goes low when data is sent/received high clock 'the data is read on the rising edge of the clock, idle high pauseus(clockdelay) 'pause for a moment for the PSX controller pauseus(clockdelay) pauseus(clockdelay) inbuffer = $00 'initialize input buffer outbuffer = $00 'initialize output buffer'****************************************************************'* Controller Polling Routine *'****************************************************************'* The controller is polled for its type and the program *'* branches to the appropriate processing routine. *'**************************************************************** Poll: low ATT 'pull ATT low to get controllers attention outbuffer = $01 'buffer the start command gosub readwrite 'send start command with readwrite routine outbuffer = $42 'buffer the data request command gosub readwrite 'send buffer command cont_id = inbuffer 'received byte is controller identifier outbuffer = $FF 'set output buffer to idle state gosub readwrite 'this should return $5A in the input buffer if cont_id = $41 then digital 'setup for digital controller (has no analog sticks) if cont_id = $23 then negcon 'negcon controller (steering wheel?) if cont_id = $73 then analog 'standard analog controller in red mode if cont_id = $53 then analog 'these are so similar that they can use the same routine high ATT 'if controller id was bad or wasnt available, lose attention pauseus(clockdelay) 'pause (may not be necessary
22
pauseus(clockdelay) pauseus(clockdelay) goto Poll 'if identifier was invalid, keep retrying
'****************************************************************'* Digital Controller Mode *'****************************************************************'* This is the simplest controller type, consisting of only *'* digital input buttons. The states of the buttons are read *'* and the button bits are assigned. Buttons are active low. *'**************************************************************** digital: gosub readwrite 'input the first word selct = inbuffer.0 'set variables to proper state start = inbuffer.3 dpad_up = inbuffer.4 dpad_right = inbuffer.5 dpad_down = inbuffer.6 dpad_left = inbuffer.7 gosub readwrite 'input the second word lt2 = inbuffer.0 'again parse word to attain button states rt2 = inbuffer.1 lt1 = inbuffer.2 rt1 = inbuffer.3 triangle = inbuffer.4 circle = inbuffer.5 X = inbuffer.6 square = inbuffer.7'<============= ERROR HERE!! pauseus(clockdelay) high ATT 'Pull ATT up since it is the end of command goSUB packet_out 'output the packetgoto Poll 'rinse, repeat, wipe hands on pants
'****************************************************************'* Steering Wheel Controller Mode *'****************************************************************'* The playstation steering wheel has inputs similar to the *'* analog controller. While unique, this is still a viable *'* input device. *'****************************************************************negcon: 'This section is for the usage of the steering wheel controller 'No support at this timegoto poll
'****************************************************************'* Analog Controller Mode *'****************************************************************'* This is the most popular controller type and is most *'* recommended for robot control applications. The buttons *'* present on the digital controller are augmented by two *'* bi-axis analog thumb sticks. *'****************************************************************analog: gosub readwrite 'get first byte
'****************************************************************'* Calibration Routine *'****************************************************************'* This routine adjusts the analog values to the center position*'* if they are within tolerence of the deadzone. This prevents *'* creep issues that would need to be fixed with trim. *'****************************************************************calibrate: if RanX < ($80 + deadzone) and RanX > ($80 - deadzone) then RanX = $80 if RanY < ($80 + deadzone) and RanY > ($80 - deadzone) then RanY = $80 if LanX < ($80 + deadzone) and LanX > ($80 - deadzone) then LanX = $80 if LanY < ($80 + deadzone) and LanY > ($80 - deadzone) then LanY = $80 return
'****************************************************************'* Output Routine *'****************************************************************'* This routine formats the data from the controller and formats*'* it for usage by the target. Eventually this will control a *'* transmitter system. *'****************************************************************packet_out: serout SerialOut,N1200,[cont_id,Buttons,Triggers,LanX,LanY,RanX,RanY,13,10] return
24
'****************************************************************'* Playstation Communication Routine *'****************************************************************'* The playstation controller uses an asynchronous communication*'* protocol. This routine both sends and receives data from the*'* controller bit by bit, LSB first. *'* Data is passed between this subroutine and the main program *'* by way of the variables inbuffer and outbuffer. *'****************************************************************readwrite: inbuffer = $00 for I = 0 to 7 low Clock 'pull clock low for setup stage if (outbuffer & %00000001) = %00000001 then high Command 'set command pin high if LSB is high else Low Command endif pauseus(clockdelay) 'pause for setup time high Clock 'set clock to high for read stage pauseus(clockdelay) 'pause for read time if CData = 1 then 'read the pin state and place it in the MSB inbuffer = inbuffer | %10000000 'put Ith bit of the input data into the input buffer else inbuffer = inbuffer & %01111111 endif pauseus(clockdelay) if (I != 7) then 'only do this for the first 7 bits inbuffer = inbuffer >> 1 'shift input buffer to right for next bit outbuffer = outbuffer >> 1 'do the same for the outbuffer endif Next I return
25
APPENDIX B:
SONY PLAYSTATION®
CONTROLLER INFORMATIONWhat you will find here
The Playstation Controller Pinouts The PSX Controller Signals The PSX Controller Data A Circuit to Emulate a PSX Controller in 74XX Logic A Microcontroller to Emulate a PSX Controller
The Playstation Controller Pinouts
LOOKING AT THE PLUG ------------------------------- PIN 1->| o o o | o o o | o o o | \_____________________________/
DATASignal from Controller to PSX.This signal is an 8 bit serial transmission synchronous to the falling edge of clock (That is both the incoming and outgoing signals change on a high to low transition of clock. All the reading of signals is done on the leading edge to allow settling time.)
COMMANDSignal from PSX to Controller.This signal is the counter part of DATA. It is again an 8 bit serial transmission on the falling edge of clock.
VCCVCC can vary from 5V down to 3V and the official SONY Controllers will still operate. The controllers outlined here really want 5V.
The main board in the PSX also has a surface mount 750mA fuse that will blow if you try to draw to much current through the plug (750mA is for both left, right and memory cards).
ATTATT is used to get the attention of the controller.This signal will go low for the duration of a transmission. I have also seen this pin called Select, DTR and Command.
CLOCKSignal from PSX to Controller.Used to keep units in sync.
ACKAcknowledge signal from Controller to PSX.This signal should go low for at least one clock period after each 8 bits are sent and ATT is still held low. If the ACK signal does not go low within about 60 us the PSX will then start interogating other devices.
It should also be noted that this is a bus of sorts. This means that the wires are all tied together (except select which is seperate for each device). For the CLK, ATT, and CMD pins this does not matter as the PSX is always the originator. The DATA and ACK pins however can be driven from any one of four devices. To avoid contentions on these lines they are open collectors and can only be driven low.
The PSX Controller Signals
All transmissions are eight bit serial LSB first. All timing in the PSX controller bus is syncronous to the falling edge of the clock. One byte of the transmissions will look kinda like this. |BIT 0|BIT 1|BIT 2|BIT 3|BIT 4|BIT 5|BIT 6|BIT 7| CLOCK -----___---___---___---___---___---___---___---___-----------
The logic level on the data lines is changed by the transmitting device on the falling edge of clock. This is then read by the receiving device on the leading edge (at the points marked *) allowing time for the signal to settle. After each COMMAND is recieved by a selected controller, that controller needs to pull ACK low for at least one clock tick. If a selected controller does not ACK the PSX will assume that there is no controller present.
When the PSX wants to read information from a controller it pulls that devices ATT line low and issues a start command (0x01). The Controller Will then reply with its ID (0x41=Digital, 0x23=NegCon, 0x73=Analogue Red LED, 0x53=Analogue Green LED). At the same time as the controller is sending this ID byte the PSX is transmitting 0x42 to request the data. Following this the COMMAND line goes idle and the controller transmits 0x5A to say "here comes the data".
This would look like this for a digital controller ATT -______________________________________________________________ | Byte 1 | | Byte 2 | | Byte 3 | CLOCK ---_-_-_-_-_-_-_-_-----_-_-_-_-_-_-_-_-----_-_-_-_-_-_-_-_----- 0xFF 0x41 0x5A DATA -------------------------__________--__----__--__----__--__---- 0x01 0x42 CMND -----_____________-----__--________--__------------------------
After this command initiation proccess the controller then sends all its data bytes (in the case of a digital controller there is only two). After the last byte is sent ATT will go high and the controller does not need to ACK.
The data transmision for a digital controller would look like this (where A0,A1,A2...B6,B7 are the data bits in the two bytes). ATT _______________________________________------- | Byte 4 | | Byte 5 | CLOCK ---_-_-_-_-_-_-_-_-----_-_-_-_-_-_-_-_--------
DATA ---D0D1D2D3D4D5D6D7----E0E1E2E3E4E5E6E7-------
Below are five tables that show the actual bytes sent by the controllers Standard Digital Pad
BYTE CMND DATA
01 0x01 idle 02 0x42 0x41 03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 04 idle data SLCT STRT UP RGHT DOWN LEFT 05 idle data L2 R2 L1 R1 /\ O X |_|
All Buttons active low.
28
NegCon
BYTE CMND DATA
01 0x01 idle 02 0x42 0x23 03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 04 idle data STRT UP RGHT DOWN LEFT 05 idle data R1 A B 06 idle data Steering 0x00 = Right 0xFF = Left 07 idle data I Button 0x00 = Out 0xFF = In 08 idle data II Button 0x00 = Out 0xFF = In 09 idle data L1 Button 0x00 = Out 0xFF = In
All Buttons active low. Analogue Controller in Red Mode
BYTE CMND DATA
01 0x01 idle 02 0x42 0x73 03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 04 idle data SLCT JOYR JOYL STRT UP RGHT DOWN LEFT 05 idle data L2 R2 L1 R1 /\ O X |_| 06 idle data Right Joy 0x00 = Left 0xFF = Right 07 idle data Right Joy 0x00 = Up 0xFF = Down 08 idle data Left Joy 0x00 = Left 0xFF = Right 09 idle data Left Joy 0x00 = Up 0xFF = Down
All Buttons active low. Analogue Controller in Green Mode
BYTE CMND DATA
01 0x01 idle 02 0x42 0x53 03 idle 0x5A Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7 04 idle data STRT UP RGHT DOWN LEFT 05 idle data L2 L1 |_| /\ R1 O X R2 06 idle data Right Joy 0x00 = Left 0xFF = Right 07 idle data Right Joy 0x00 = Up 0xFF = Down 08 idle data Left Joy 0x00 = Left 0xFF = Right 09 idle data Left Joy 0x00 = Up 0xFF = Down