Como fazer um sistema de rastreamento de caminho sem fio usando mouse, XBee e Arduino- (Parte 43/49)

How to make a wireless path tracking system using mouse, XBee and Arduino - (Part 43/49)

Microcontroller applications are not limited to controlling simple electrical or electronic devices, but are widely used in the robotics and automotive industries today. From simple rear view mirror control to complex engine control functions are performed by the microcontroller. The microcontroller can even implement automatic control of the vehicle without a human driver inside it and these types of vehicles are called Unmanned Vehicles (UV). UVs are commonly used in the research, military, rescue, and agricultural fields. For any UVs, real-time tracking of their path is necessary to ensure they are moving in the correct path.

This project demonstrates how it is possible to make a simpler trajectory tracking device for a land vehicle with the help of an optical mouse . An optical mouse is a device that has a very small camera inside it that can detect the movement of the ground beneath it and communicate the change in XY coordinate with an external device through simple serial communication protocols. This project uses an optical mouse that works on the PS2 protocol and interfaces with an Arduino board to read data from it. Mouse data is then transmitted wirelessly using a pair of Xbee transceivers to a distant computer, where the data is displayed graphically as a track on which mouse movement occurs.

Xbee is the brand name for a wireless transceiver device that works on the ZigBee protocol. ZigBee is the name of a wireless protocol maintained by the IEEE 802.15 standard. This is a protocol specified for wireless personal area networks (PAN) using low-power wireless transceivers. They can also be used for simple point-to-point communication systems.

Two Xbee S1 series transceiver modules are used in this project, and the image of the same module is shown in the following figure. Since the pin pitch of the modules is not compatible with the breadboard, you can use the Xbee based design boards which come with pins compatible with the breadboard.

Fig. 2: Xbee S1 Series Transceiver Module

Since 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 output and UART data input. Pin number 2, UART Data Out is connected to RX1 pin of Arduino pro mini board and pin number 3, UART Data is connected to TX0 pin.

In this project the Arduino pro-mini board is used, which comes pre-programmed with the Arduino bootloader . The programming IDE used for this project is Arduino IDE version 1.0.3 on the Windows operating system. The image of the Arduino pro-mini board and Arduino IDE is shown below:

Fig. 3: Typical Arduino Pro-Mini board

Fig. 4: Arduino IDE software window

Another hardware that can perform USB to TTL conversion is used to load the program onto the Arduino board. This board can also be used when it is necessary to carry out serial communication between the PC and the Arduino board.

5: External USB to TTL Converter Board for Arduino Programming and Serial Communication

It is assumed that the reader has gone through the project how to get started with Arduino and done all the things discussed in it.

The PS2 mouse uses synchronous communication with the PC that is very 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 communicates with the host device. The mouse always has a 6-pin male mini-DIN connector for PS2 interface, and the host device always has the corresponding female pin. The images and pinouts of the PS2 male and female connectors are shown in the following image:

The PS2 male pin image

6: 6-pin mini-DIN male connector for PS2 interface

The female PS2 pin image

Fig. 7: 6-pin Mini DIN female connector plug for PS2 interface

The pinout of the PS2 male and female connectors

Fig. 8: Pinout of male and female PS2 connectors

When it comes to connecting the female connector to the circuit board, you should be able to identify the pins on the bottom of the PS2 connector and the following image will be helpful.

Fig. 9: Bottom of the Mini DIN female connector for PS2 interface

The code written for this project uses the custom PS2 library file called “PS2Mouse.h” which has all the routines needed to access a PS2 mouse. There are two functions that the user can use directly in their code: “mouse.initialize ” and “mouse.report (data)”. The method of reading PS2 mouse data using the above functions and decoding to obtain the XY coordinates are explained in a previous project on how to interface a PS2 mouse with Arduino .

The project implementation that can receive data from the PS2 mouse and transmit the XY coordinate extracted from the mouse data through Xbee is represented by the following block diagram:

Fig. 10: Block diagram of wireless path tracking system using mouse and Xbee with Ardiuno

The code written for this project on Arduino reads data from PS2 mouse continuously and writes the data to Xbee for transmission with the help of serial communication functions provided by Arduino IDE. The functions like Serial.begin which helps to initialize the serial port with a certain baud rate, Serial.write to send 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 have already been discussed in previous projects on how to do serial communication with Arduino , how to send and receive serial data using Arduino and how to do serial debugging with Arduino . The method to get the required XY data from the PS2 mouse is explained in the previous project on how to interface a PS2 mouse with Arduino . The method of interfacing an Xbee module and transmitting data using it is discussed in the previous project on how to interface Xbee module with Arduino .

The code reads hundreds of sets of mouse data at once and calculates the average change in the X value of that data. This average value of the change in the X coordinate is then used to compensate for the position of a '*' character in a line that must be transmitted and displayed on the distant computer. Thus, as the mouse moves, the average value of the change in the X direction varies, which varies the position of the '*' character in the serial monitor window on the distant PC. Since the character '*' is printed continuously each time on a new line with a position according to the mouse movement, it can be considered similar to the drawn trail that follows the mouse movement in the X direction.

When the coding is complete you can check and upload the code to the Arduino board as explained in the project how to get started with Arduino . As soon as the board is turned on, the Xbee on the Arduino board automatically establishes communication with another Xbee that 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 that was used to program the Arduino board. Move the mouse and the change in the track can be observed using any serial monitoring software or using the Arduino IDE's own serial monitoring software as explained in the project how to do serial debugging with Arduino .

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:

 DATE 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++)

 {

 of

 {

 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);

 date = date >> 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; // Party 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

Circuit diagram making a wireless path tracking system using mouse-XBee-Arduino

Project Components

  • Arduino ProMini
  • LCD
  • LED
  • Resistor

Project video

Related Content

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.