You are on page 1of 33

MICROCONTROLLER PROJECT PS2 controlled omni bot

A PROJECT REPORT

submitted by

PRAVEEN(10BEE1058) SAKSHI MISHRA(10BEE1076) AKSHAY SINGH(10BEE1012) SRIRAM PARAVASTU(10BEE1060)

in partial fulfillment for the award of the degree of

BACHELOR OF TECHNOLOGY
in

ELECTRICAL AND ELECTRONICS ENGINEERING

Problem statement:
Build a wirelessly controlled OMNI directional bot. The wireless control is using a PS2(sony playstation 2) joystick. The bot should be maneuverable in any given direction according to the commands.

Introduction:

What is an Omni-Wheel Robot?

A robot that uses omni-wheels can move in any direction, at any angle, without rotating beforehand. If you want a robot that can straff, use an omni-wheel robot. If you want a robot that can spin while translating forward at the same heading, then you want this type of robot. Omni wheels or poly wheels, similar to Mecanum wheels, are wheels with small discs around the circumference which are perpendicular to the rolling direction. The effect is that the wheel will roll with full force, but will also slide laterally with great ease. These wheels are often employed in holonomic drive systems. Below are a few of the available omni-wheels on the market. The wheel size and diameter are dependent on things like expected robot speed, weight, etc.

Playstation 2 controller with receiver (2.4Ghz)

Theory behind:
Holonomic vs Non-Holonomic Robots

There are only two types of mobile robots, holonomic robots and non-holonomic robots. Non-holonomic robots are ones that cannot instantaneously move in any direction, such as a car. This type of robot has to perform a set of motions to change heading. For example, if you want your car to move sideways, you must perform a complex 'parallel parking' motion. For the car to turn, you must rotate the wheels and drive forward. This type of robot would have '1.5' degrees of freedom, meaning that it can move in both the X and Y direction, but requires complex motions to achieve the X direction.

A holonomic robot however can instantaneously move in any direction. It does not need to do any complex motions to achieve a particular heading. This type of robot would have 2 degrees of freedom in that it can move in both the X and Y plane freely. A robot arm typically is omnidirectly too, with many more degrees of freedom.

Our bot employs three omni wheels in a triangular configuration.


Control of an Omni Wheel Robot

For an omni-wheel robot to translate at a particular angle, each wheel must rotate at a particular rotational velocity and direction. Since the robot is moving

at angles, it will need to do trigonometric calculations to determine these wheel speeds.

Angle control. For an omni-wheel robot to translate at a certain angle, each motor needs to go at a certain speed with relation to the others. The speed doesnt matter, just the ratios. Motor speed. The faster the motors go, the faster the robot goes. Rotational control. For an omni-wheel robot to rotate at some particular speed, it must add or subtract equally from the motor speed of each motor. Maximum motor speed. Motors can only go so fast, so when you do ratios, and rotational control additions, you must make sure that you are not commanding a motor to go faster than it can.

Methodology (hardware setup):

Block diagram:

SCHEMATIC:

FLOWCHART:

START

Initialize the motor and wireless controller receiver

NO

Check if the connection between the microcontroller and receiver is established

YES

Read the command from the controller

connector

connector

Process the command according to the button programmed in subroutines Check the Next command Button X-120 deg rotation

Button -240 deg rotation

STOP

ALGORITHM: 1. Start 2. Initialize the pins as output and input according to the motor driver and ps2 receiver connections. 3. Initialize connection with the PS2 controller and enable the motors. 4. If a link between the ps2 controller and the receiver is established, read data from the ps2 controller.

5. Decode The data read from the controller using the datasheet of the controller, which shows the timing diagrams for the data/clock and also the data sent for various button configuration. As shown below: byte enter_config[]={0x01,0x43,0x00,0x01,0x00}; byte set_mode[]={0x01,0x44,0x00,0x01,0x03,0x00,0x00,0x00,0x00}; byte set_bytes_large[]={0x01,0x4F,0x00,0xFF,0xFF,0x03,0x00,0x00,0x00}; byte exit_config[]={0x01,0x43,0x00,0x00,0x5A,0x5A,0x5A,0x5A,0x5A}; byte enable_rumble[]={0x01,0x4D,0x00,0x00,0x01}; byte type_read[]={0x01,0x45,0x00,0x5A,0x5A,0x5A,0x5A,0x5A,0x5A};

6. Control the bot according to the button pressed on the controller. All the actions for a specific button is configurable. Say, if the up arrow button is pressed , command the bot to move forward and if the down arrow is pressed, command the bot to move backward and so on based on the picture below: The drive mechanism is explained in the picture below:

7. On exit,Close the controller connections. Turn of all the motors.

8. stop

CODE: The Arduino code for the bot is below.

#include <PS2X_lib.h> //Looking from the back of the omni bot //P: +ve; N:-ve; Clockwise +ve #define MFP 1 //motor front +ve terminal #define MFN 3 //motor front -ve terminal #define MLP 4 // motor left #define MLN 5 #define MRP 6 //motor right #define MRN 7 //EN pins. currently not used but used in case the velocities of the motors have to be varied using PWM #define MF_EN 9 #define ML_EN 10

#define MR_EN 11 PS2X ps2x; // create PS2 Controller Class

int error = 0; // error b/w the link between the PS2 controller and receiver byte type = 0; // type of the controller byte vibrate = 0; // Vibration of rumble motors

void setup(){ Serial.begin(57600); // init serial with 57600 baud rate for debugging info pinMode(MFP,OUTPUT); pinMode(MFN,OUTPUT); pinMode(MLP,OUTPUT); pinMode(MLN,OUTPUT); pinMode(MRP,OUTPUT); pinMode(MRN,OUTPUT); pinMode(MF_EN,OUTPUT); pinMode(ML_EN,OUTPUT); pinMode(MR_EN,OUTPUT);

error = ps2x.config_gamepad(2,12,8,13); //setup GamePad(clock, command, attention, data) pins, check for error

if(error == 0){

Serial.println("LInk established successfully");

else if(error == 1) Serial.println("No controller found, ");

else if(error == 2) Serial.println("Controller found but not accepting commands");

//Serial.print(ps2x.Analog(1), HEX);

type = ps2x.readType(); switch(type) { case 0: Serial.println("Unknown Controller type"); break;

case 1: Serial.println("DualShock Controller Found"); break;

//ps2x.enableRumble();

//enable rumble vibration motors

if(!ps2x.enablePressures()) //enable reading the pressure values from the buttons. Serial.println("Controller refusing Pressures mode, may not support it.");

void loop(){

if(error != 0) //skip loop if no controller found return;

{ //DualShock Controller

// ps2x.read_gamepad(false, vibrate); to spin at 'vibrate' speed ps2x.read_gamepad(); if(ps2x.Button(PSB_START)) pressed Serial.println("Start is being held"); if(ps2x.Button(PSB_SELECT)) Serial.println("Select is being held");

//read controller and set large motor

//will be TRUE as long as button is

if(ps2x.Button(PSB_PAD_UP)) { forward(); } if(ps2x.Button(PSB_PAD_RIGHT)){ clockwise();

//will be TRUE as long as button is pressed

} if(ps2x.Button(PSB_PAD_LEFT)){

anticlockwise(); } if(ps2x.Button(PSB_PAD_DOWN)){ backward(); } if(ps2x.ButtonPressed(PSB_PINK)) { twofortydegrees(); clockwise(); twofortydegrees(); clockwise(); twofortydegrees();

} if(ps2x.ButtonPressed(PSB_BLUE)) { anticlockwise(); onetwentydegrees(); anticlockwise(); onetwentydegrees(); anticlockwise(); onetwentydegrees(); }

vibrate = ps2x.Analog(PSAB_BLUE); speed based on

//this will set the large motor vibrate

//how hard you press the blue (X) button

if (ps2x.NewButtonState()) (on to off, or off to on) {

//will be TRUE if any button changes state

if(ps2x.Button(PSB_L3)) Serial.println("L3 pressed"); if(ps2x.Button(PSB_R3)) Serial.println("R3 pressed"); if(ps2x.Button(PSB_L2)) Serial.println("L2 pressed"); if(ps2x.Button(PSB_R2)) Serial.println("R2 pressed"); if(ps2x.Button(PSB_GREEN)) twofortydegrees(); //Serial.println("Triangle pressed");

if(ps2x.ButtonPressed(PSB_RED)) pressed onetwentydegrees();

//will be TRUE if button was JUST

//if(ps2x.ButtonReleased(PSB_PINK)) released //Serial.println("Square just released");

//will be TRUE if button was JUST

// Serial.println("X just changed");

if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) // print stick values if either is TRUE { Serial.print("Stick Values:"); Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX Serial.print(",");

Serial.print(ps2x.Analog(PSS_LX), DEC); Serial.print(","); Serial.print(ps2x.Analog(PSS_RY), DEC); Serial.print(","); Serial.println(ps2x.Analog(PSS_RX), DEC); }

//delay(50); //

} // function to command the omni bot to move forward void forward() {Serial.println("going forward"); digitalWrite(MR_EN,1); digitalWrite(ML_EN,1); digitalWrite(MRP,1); digitalWrite(MRN,0);

digitalWrite(MLP,0); digitalWrite(MLN,1); delay(200); digitalWrite(MR_EN,0); digitalWrite(ML_EN,0); } //function to command the omni bot to move backward void backward() {Serial.println("going backward"); digitalWrite(MR_EN,1); digitalWrite(ML_EN,1); digitalWrite(MRP,0); digitalWrite(MRN,1); digitalWrite(MLP,1); digitalWrite(MLN,0); delay(200); digitalWrite(MR_EN,0); digitalWrite(ML_EN,0); } // function to command the omni bot to rotate clockwise void clockwise() {

digitalWrite(MR_EN,1); digitalWrite(ML_EN,1); digitalWrite(MRP,1); digitalWrite(MRN,0); digitalWrite(MLP,1); digitalWrite(MLN,0); delay(200); digitalWrite(MR_EN,0); digitalWrite(ML_EN,0); }

//function to command the omni bot to rotate anti-clockwise void anticlockwise() { digitalWrite(MR_EN,1); digitalWrite(ML_EN,1); digitalWrite(MRP,0); digitalWrite(MRN,1); digitalWrite(MLP,0); digitalWrite(MLN,1); delay(200); digitalWrite(MR_EN,0);

digitalWrite(ML_EN,0); }

//function to command the omni bot to move right void rightturn() {

digitalWrite(MFP,0); digitalWrite(MFN,1); digitalWrite(MF_EN,1); digitalWrite(MR_EN,1); digitalWrite(ML_EN,1);

digitalWrite(MRP,1); digitalWrite(MRN,0); digitalWrite(MLP,1); digitalWrite(MLN,0);

delay(200); digitalWrite(MR_EN,0); digitalWrite(ML_EN,0);

delay(20); digitalWrite(MF_EN,0); }

//function to command the omni bot to move left void leftturn() { digitalWrite(MFP,1); digitalWrite(MFN,0); digitalWrite(MF_EN,1); digitalWrite(MR_EN,1); digitalWrite(ML_EN,1);

digitalWrite(MRP,0); digitalWrite(MRN,1); digitalWrite(MLP,0); digitalWrite(MLN,1);

delay(200); digitalWrite(MR_EN,0); digitalWrite(ML_EN,0); delay(20);

digitalWrite(MF_EN,0); } //functionn to command the bot to move at 240degrees void twofortydegrees() { digitalWrite(MR_EN,1);

digitalWrite(MF_EN,1); digitalWrite(MRP,1); digitalWrite(MRN,0); digitalWrite(MFP,0); digitalWrite(MFN,1); delay(200); digitalWrite(MR_EN,0);

digitalWrite(MF_EN,0); } //function to move the bot at 120degrees void onetwentydegrees() { digitalWrite(ML_EN,1);

digitalWrite(MF_EN,1); digitalWrite(MLP,1); digitalWrite(MLN,0); digitalWrite(MFP,0); digitalWrite(MFN,1); delay(200); digitalWrite(ML_EN,0);

digitalWrite(MF_EN,0); }

Future Enhancements: 1.Precise direction control.

2.Mixed Linear and Angular Movement

Should the robot need to rotate its body while moving towards the ball, linear and angular velocity can be combined by calculating the sum of both contributions

DATA SHEETS (PIN OUT DIAGRAMS ) OF ICs USED:

Overview
The Arduino Uno is a microcontroller board based on the ATmega328 (datasheet). It has 14 digital input/output pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16 MHz ceramic resonator, a USB connection, a power jack, an ICSP header, and a reset button. It contains everything needed to support the microcontroller; simply connect it to a computer with a USB cable or power it with a AC-to-DC adapter or battery to get started.

The Uno differs from all preceding boards in that it does not use the FTDI USB-to-serial driver chip. Instead, it features the Atmega16U2 (Atmega8U2 up to version R2) programmed as a USB-to-serial converter.

Summary
Microcontroller ATmega328 Operating Voltage 5V Input Voltage (recommended) 7-12V Input Voltage (limits) 6-20V Digital I/O Pins 14 (of which 6 provide PWM output) Analog Input Pins 6 DC Current per I/O Pin 40 mA DC Current for 3.3V Pin 50 mA Flash Memory 32 KB (ATmega328) of which 0.5 KB used by bootloader SRAM 2 KB (ATmega328) EEPROM 1 KB (ATmega328) Clock Speed 16 MHz

REFERENCES: http://en.wikipedia.org/wiki/Omni_wheel

http://www.billporter.info/2011/03/27/arduinoplaystation-2-controller-library-troubleshooting-guide/

http://store.curiousinventor.com/guides/PS2/

http://nex-robotics.com