The applications of microcontroller are not limited to control simple electrical or electronic device but they are widely used in robotics and automotive industries nowadays. From simple rear view mirror control to complex engine control functions are done by the microcontroller. The microcontroller can even implement to automatically controlling the vehicle without a human driver inside it and such kinds of vehicles are called Unmanned Vehicles (UV). The UVs are commonly used research, military, rescue and agriculture fields. For any UVs the real time tracking of their path is necessary to ensure that they are moving through the proper way.
This project demonstrates how it is possible to make a simplest path tracking device for a ground vehicle with the help of optical mouse. The optical mouse is a device which has a very small camera inside it which can sense the movement of the ground below it and communicate the change in the X-Y coordinate with an external device through simple serial communication protocols. This project makes use of an optical mouse which works on PS2 protocol and is interfaced with an Arduino board to read the data from it. The data from the mouse is then transmitted wirelessly using anXbee transceiver pair to a distant computer where the data is displayed graphically as a track in which the mouse movement occurs.
The Xbee is the brand name a wireless transceiver device that works on the ZigBee protocol. The ZigBee is the name of a wireless protocol maintained by the IEEE 802.15 standard. This is a protocol specified for wireless Personal Area Network (PAN) using low-powered wireless transceivers. They can be used for simple point-to-point communication systems also.
Two Xbee S1 series transceivers modules are used in this project, and the image of the same module is shown in the following figure. Since the pitch of the pins of the modules are not breadboard compatible, one can use the Xbee-based design boards, which comes with breadboard-compatible pins.
Fig. 2: Xbee S1 Series Transceiver Module
Since the Xbee modules communicate using serial communication protocol with the interfacing devices, they can be connected to a microcontroller using a minimum of four pins, Power supply, and ground, UART Data Out, and UART Data In pins. The pin number 2, UART Data Out is connected to the RX1 pin of the Arduino pro mini board and pin number 3, UART Data is connected to the TX0 pin.
In this project, the Arduino pro-mini board is used, which is pre-programmed with the Arduino boot-loader. The programming IDE used for this project is Arduino IDE version 1.0.3 on Windows operating system. The image of the Arduino pro-mini board and the Arduino IDE is shown in the following:
Fig. 3: Typical Arduino Pro-Mini Board
Fig. 4: Arduino IDE Software Window
Another hardware which can perform the USB to TTL conversion is used to upload the program into the arduino board. This board can be also when it is required to perform serial communication between the PC and the Arduino board.
Fig. 5: External USB to TTL converter board for programming Arduino and serial communication
It is assumed that the reader has gone through the project how to get started with the arduino and done all the things discussed in it.
The PS2 mouse uses a synchronous communication with the PC which is very much similar to the Two Wire Interface protocol. The PS2 connector has a pin for Data and another pin for Clock and using only these two pins the mouse communicate with the host device. The mouse always has 6 pin mini-DIN male connector for PS2 interface and the host device always has the corresponding female pin. The images and the pin-outs of the PS2 male and female connectors are shown in the following image:
The image of the PS2 male pin
Fig. 6: 6 pin mini-DIN Male connector for PS2 interface
The image of the PS2 female pin
Fig. 7: 6 Pin Mini DIN Female Connector Plug for PS2 interface
The pin-out of the PS2 male and female connectors
Fig. 8: Pin-Out Of PS2 Male and Female Connectors
When it comes to connecting the female connector with the circuit board one should be able to identify the pins at the bottom of the PS2 connector and the following image will be helpful.
Fig. 9: Bottom of Mini DIN Female Connector Plug for PS2 interface
The code written for this project uses the custom PS2 library file called “PS2Mouse.h” which has all the necessary routines for accessing a PS2 mouse. There are two functions which the user can directly make use in their code and are namely “mouse.initialize()” and “mouse.report(data)”.The method of reading the data from the PS2 mouse using the above functions and decoding them to get the X-Y coordinates are explained in a previous project on how to interface a PS2 mouse with the Arduino.
The implementation of the project which can receive the data from PS2 mouse and transmit the X-Y coordinate extracted from the mouse data through Xbee is represented using the following block diagram:
Fig. 10: Block Diagram Of Wireless Path Tracking System Using Mouse & Xbee With Ardiuno
The code written for this project on Arduino reads the PS2 mouse data continuously and writes the data to the Xbee for transmission with the help of serial communication functions provided by the Arduino IDE. The functions like Serial.begin() which helps to initialize the serial port with a given baud rate, Serial.write() to send a data to the serial port, Serial.available() and Serial.read() functions to read data from the serial port are used in this project and they are already discussed in previous projects on how to do serial communication with the Arduino, how to send and receive serial data using arduino and how to do serial debugging with the Arduino. The method of getting the required X-Y data from the PS2 mouse is explained in the previous project on how to interface a PS2 mouse with the Arduino. The method of interfacing an Xbee module and transmission of data using it is discussed in as previous project on how to interface Xbee module with Arduino.
The code reads hundred data sets from the mouse at once and calculates the average change in the X value from those data. This average value of the change in X coordinate is then used to offset the position of a character ‘*’ in a line that has to be transmitted and displayed in the distant computer. Thus as the mouse moves the average value of change in X direction varies which varies the position of the character ‘*’ in the serial monitor window in the distant PC. As the character ‘*’ is printed continuously each time in a new line with a position according to the movement of the mouse one can find it similar to the track drawn which follows the movement of the mouse in X direction.
When the coding is finished one can verify and upload the code to the Arduino board as explained in the project how to get started with the Arduino. As soon as the board is powered up the Xbee in the Arduino board automatically establishes communication with another Xbee which is connected to the serial port of a PC. The second Xbee board can be connected to the PC using the same USB to TTL converter board which has been used to program the Arduino board. Move the mouse and the change in track can be observed using any serial monitoring software or using the Arduino IDE’s serial monitoring software itself as explained in the project how to do serial debugging with the Arduino.
You may also like:
Project Source Code
### /*============================ EG LABS ===================================// Demonstration on how to wirelessly send path information data of the movement of a PS2 mouse in X direction using Xbee The circuit: LCD: * LCD RS pin to digital pin 12 * LCD Enable pin to digital pin 11 * LCD D4 pin to digital pin 7 * LCD D5 pin to digital pin 6 * LCD D6 pin to digital pin 5 * LCD D7 pin to digital pin 4 * LCD R/W pin to ground * 10K resistor: * ends to +5V and ground * wiper to LCD pin 3 * LED anode attached to digital output 9 * LED cathode attached to ground through a 1K resistor MOUSE: DATA PIN TO PIN NUMBER 8 CLOCK PIN TO PIN NUMBER 3 XBEE: RX PIN OF XBEE TO TX0 PIN OF ARDUINO SHORT THE GROUND PINS OF ARDUINO AND XBEE ============================== EG LABS ===================================*/ #include "PS2Mouse.h" #define MOUSE_DATA 8 #define MOUSE_CLOCK 3 // include the library code: #include// initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 7, 6, 5, 4); // initialize the mouse library PS2Mouse mouse(MOUSE_CLOCK, MOUSE_DATA, STREAM); int i; int x_acc = 0; int pos = 0; int data[2]; void setup() { pinMode(9, OUTPUT); // set up the lcd's number of columns and rows: lcd.begin(16, 2); lcd.print("ENGINEERS GARAGE"); lcd.setCursor(0, 1); lcd.print(" MOUSE to XBEE "); delay(2000); digitalWrite(9, HIGH); Serial.begin(9600); mouse.initialize(); // initialize the PS2 mouse connected with the Arduino } void loop() { x_acc = 0; for(i = 0; i < 100; i ++) { do { mouse.report(data); // get data from the mouse }while(data[1] == 0); x_acc += data[1]; } //=== get the average movement in the x direction ===// x_acc = x_acc / 200; x_acc = x_acc + pos; if(x_acc > 100) x_acc = 100; else; //=== get the average movement in the x direction ===// Serial.println(); for(i = 0; i < (100 + x_acc); i ++) Serial.print(" "); Serial.print("*"); pos = x_acc; } ###
Project Source Code
### //#include "WConstants.h" #include "HardwareSerial.h" #include "PS2Mouse.h" #include "Arduino.h" PS2Mouse::PS2Mouse(int clock_pin, int data_pin, int mode) { _clock_pin = clock_pin; _data_pin = data_pin; _mode = mode; _initialized = false; _disabled = true; _enabled = false; } int PS2Mouse::clock_pin() { return _clock_pin; } int PS2Mouse::data_pin() { return _data_pin; } void PS2Mouse::initialize() { pull_high(_clock_pin); pull_high(_data_pin); delay(20); write(0xff); // Send Reset to the mouse read_byte(); // Read ack byte delay(20); // Not sure why this needs the delay read_byte(); // blank read_byte(); // blank delay(20); // Not sure why this needs the delay if (_mode == REMOTE) { set_remote_mode(); } else { enable_data_reporting(); // Tell the mouse to start sending data again } delayMicroseconds(100); _initialized = 1; } void PS2Mouse::set_mode(int data) { if (_mode == STREAM) { disable_data_reporting(); // Tell the mouse to stop sending data. } write(data); // Send Set Mode read_byte(); // Read Ack byte if (_mode == STREAM) { enable_data_reporting(); // Tell the mouse to start sending data again } if (_initialized) { delayMicroseconds(100); } } void PS2Mouse::set_remote_mode() { set_mode(0xf0); _mode = REMOTE; } void PS2Mouse::set_stream_mode() { set_mode(0xea); _mode = STREAM; } void PS2Mouse::set_sample_rate(int rate) { if (_mode == STREAM) { disable_data_reporting(); // Tell the mouse to stop sending data. } write(0xf3); // Tell the mouse we are going to set the sample rate. read_byte(); // Read Ack Byte write(rate); // Send Set Sample Rate read_byte(); // Read ack byte if (_mode == STREAM) { enable_data_reporting(); // Tell the mouse to start sending data again } delayMicroseconds(100); } void PS2Mouse::set_scaling_2_1() { set_mode(0xe7); // Set the scaling to 2:1 } void PS2Mouse::set_scaling_1_1() { set_mode(0xe6); // set the scaling to 1:1 } // This only effects data reporting in Stream mode. void PS2Mouse::enable_data_reporting() { if (!_enabled) { write(0xf4); // Send enable data reporting read_byte(); // Read Ack Byte _enabled = true; } } // Disabling data reporting in Stream Mode will make it behave like Remote Mode void PS2Mouse::disable_data_reporting() { if (!_disabled) { write(0xf5); // Send disable data reporting read_byte(); // Read Ack Byte _disabled = true; } } void PS2Mouse::set_resolution(int resolution) { if (_mode == STREAM) { enable_data_reporting(); } write(0xe8); // Send Set Resolution read_byte(); // Read ack Byte write(resolution); // Send resolution setting read_byte(); // Read ack Byte if (_mode == STREAM) { disable_data_reporting(); } delayMicroseconds(100); } void PS2Mouse::write(int data) { char i; char parity = 1; pull_high(_data_pin); pull_high(_clock_pin); delayMicroseconds(300); pull_low(_clock_pin); delayMicroseconds(300); pull_low(_data_pin); delayMicroseconds(10); pull_high(_clock_pin); // Start Bit while (digitalRead(_clock_pin)) {;} // wait for mouse to take control of clock) // clock is low, and we are clear to send data for (i=0; i < 8; i++) { if (data & 0x01) { pull_high(_data_pin); } else { pull_low(_data_pin); } // wait for clock cycle while (!digitalRead(_clock_pin)) {;} while (digitalRead(_clock_pin)) {;} parity = parity ^ (data & 0x01); data = data >> 1; } // parity if (parity) { pull_high(_data_pin); } else { pull_low(_data_pin); } while (!digitalRead(_clock_pin)) {;} while (digitalRead(_clock_pin)) {;} pull_high(_data_pin); delayMicroseconds(50); while (digitalRead(_clock_pin)) {;} while ((!digitalRead(_clock_pin)) || (!digitalRead(_data_pin))) {;} // wait for mouse to switch modes pull_low(_clock_pin); // put a hold on the incoming data. } int * PS2Mouse::report(int data[]) { write(0xeb); // Send Read Data read_byte(); // Read Ack Byte data[0] = read(); // Status bit data[1] = read_movement_x(data[0]); // X Movement Packet data[2] = read_movement_y(data[0]); // Y Movement Packet return data; } int PS2Mouse::read() { return read_byte(); } int PS2Mouse::read_byte() { int data = 0; pull_high(_clock_pin); pull_high(_data_pin); delayMicroseconds(50); while (digitalRead(_clock_pin)) {;} delayMicroseconds(5); // not sure why. while (!digitalRead(_clock_pin)) {;} // eat start bit for (int i = 0; i < 8; i++) { bitWrite(data, i, read_bit()); } read_bit(); // Partiy Bit read_bit(); // Stop bit should be 1 pull_low(_clock_pin); return data; } int PS2Mouse::read_bit() { while (digitalRead(_clock_pin)) {;} int bit = digitalRead(_data_pin); while (!digitalRead(_clock_pin)) {;} return bit; } int PS2Mouse::read_movement_x(int status) { int x = read(); if (bitRead(status, 4)) { for(int i = 8; i < 16; ++i) { x |= (1< pinMode(pin, OUTPUT); digitalWrite(pin, LOW); } void PS2Mouse::pull_high(int pin) { pinMode(pin, INPUT); digitalWrite(pin, HIGH); } **************Header File for Mouse Intefacing*****************************
#define PS2Mouse_h #define REMOTE 1 #define STREAM 2 class PS2Mouse { private: int _clock_pin; int _data_pin; int _mode; int _initialized; int _enabled; int _disabled; int read_byte(); int read_bit(); int read_movement_x(int); int read_movement_y(int); void pull_high(int); void pull_low(int); void set_mode(int); public: PS2Mouse(int, int, int mode = REMOTE); void initialize(); int clock_pin(); int data_pin(); int read(); int* report(int data[]); void write(int); void enable_data_reporting(); void disable_data_reporting(); void set_remote_mode(); void set_stream_mode(); void set_resolution(int); void set_scaling_2_1(); void set_scaling_1_1(); void set_sample_rate(int); }; #endif###
Circuit Diagrams
Project Components
Project Video
Filed Under: Arduino Projects, Electronic Projects
Filed Under: Arduino Projects, Electronic Projects
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.