Engineers Garage

  • Projects and Tutorials
    • Electronic Projects
      • 8051
      • Arduino
      • ARM
      • AVR
      • PIC
      • Raspberry pi
      • STM32
    • Tutorials
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Products News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • Digi-Key Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • EE Resources
    • DesignFast
    • LEAP Awards
    • Oscilloscope Product Finder
    • White Papers
    • Webinars
  • EE Learning Center
    • Design Guides
      • WiFi & the IOT Design Guide
      • Microcontrollers Design Guide
      • State of the Art Inductors Design Guide
  • Women in Engineering

How To Use PS2 Mouse To Move A Character In LCD- (Part 39/49)

By Ajish Alfred

The PS2 mouse is a device which can communicate with a host device using the PS2 protocol. It can be connected to a host device using the 6 pin mini DIN connector. The mouse will continuously give output which can be decoded to get the movement in the X-Y plane and also the status of the buttons on the mouse. The PS2 protocol is a simple two wire synchronous protocol which makes it possible for the simple microcontroller board to interface the standard PS2 mouse or keyboard with it.The data read from the mouse can be decoded to get the amount of change in position of the mouse with respect to the position at the previous read. This data is normally used in PCs to move a cursor in the screen. This particular project also does a similar kind of demonstration in which a smiley is moved in a 16x2 LCD corresponding to the movement of a PS2 mouse both connected to an Arduino board.

The AVR microcontroller boards which are provided with all the basic circuitry for the operation of the microcontroller which has been flashed with the Arduino boot-loader are called Arduino boards. The Arduino board has all the required circuitry to get the built-in AVR microcontroller running. When it comes to programming the Arduino board anyone who have basic knowledge of c programming can quickly get started with the Arduino IDE.

 


 

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;

Typical Arduino Pro-Mini Board

Fig. 2: Typical Arduino Pro-Mini Board

 

Arduino IDE Software Window

Fig. 3: Arduino IDE Software Window

Another hardware which can perform the USB to TTL conversion is used to upload the program into the arduino board.

External USB To TTL Converter Board For Programming Arduino And Serial Communication

Fig. 4: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. These projects make use of the average velocity calculated from the PS2 data output over an interval of time. The data from the PS2 mouse gives the direction of the movement also and which is significant in determining the direction of movement of the smiley in the LCD screen.The smiley displayed in this project is done with the help of custom characters that can be generated in an LCD module. The method of generating custom characters is well explained in a previous project on how to create custom characters in an LCD. The code written for this project has a function lcd.createChar() which helps to create the custom characters in an LCD screen. The details of the lcd.createChar() function is already explained in previous projects on how to create custom characters and how to create smileys on LCD screen using Arduino.

The function lcd.createChar() is available in Arduino IDE from the library called <LiquidCrystal.h> which provides lot of functions to access the LCD module. Few functions from the library are already discussed in the previous projects on how to interface an LCD, how to display sensor value on LCD, how to connect the LCD with the PC and how to make an LCD scrolling display.

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 details of the functions are discussed in the following.

mouse.initialize()

The function mouse.initialize() is used to perform all the necessary things to initialize data reporting from a mouse. Once the initialization is done properly the mouse starts sending the data regarding its X-Y movement and the status of the buttons on the mouse. The function takes no parameter and returns nothing but will exist only when the initialization is properly done.

mouse.report(data)

The function mouse.report(data) can be used to read the current data from the mouse. The function should be provided with an integer array of three elements and the function will fill the elements with the required values. The first element is written with the status value, the second element with the X movement value and the third element will be written with the Y movement value.

If there is no movement in the X-Y plane the value for both the second and the third variables will be zero and if there is no button press the first element will be having a value 8. The first element of the array will be having the values 8, 10 and 12 for left-button press, right-button press and center-button press respectively.

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

6 Pin Mini-DIN Male Connector For PS2 Interface

Fig. 5: 6 pin mini-DIN Male connector for PS2 interface

The image of the PS2 female pin

 6 Pin Mini DIN Female Connector Plug For PS2 Interface

Fig. 6: 6 Pin Mini DIN Female Connector Plug for PS2 interface

The pin-out of the PS2 male and female connectors

 Pin-Out Of PS2 Male And Female Connectors

Fig. 7: 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.

 Bottom Of Mini DIN Female Connector Plug For PS2 Interface

Fig. 8: Bottom of Mini DIN Female Connector Plug for PS2 interface

The code calculates the average velocity of the movement of the mouse in X direction only and the position in the second line of the LCD where the smiley has to be displayed is set accordingly. Thus each time the mouse moves one can find the smiley displayed in the second line of the 16*2 LCD also moves in the same direction.

Make sure that the files “PS2Mouse.h” and “PS2Mouse.cpp” are kept in the same folder where the .pde file has been saved. 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

Project Source Code

###




/*============================ EG LABS ===================================//

 

 Demonstration on how to use PS2 MOUSE to move a smiley in 16*2 LCD

 

 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

============================== EG LABS ===================================*/


#include "PS2Mouse.h"

#define MOUSE_DATA 8

#define MOUSE_CLOCK 3

// include the library code:

#include <LiquidCrystal.h>


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


//----------------- store the custom characters in arrays ---------------------//

byte smile[8] = 

              {

                0b00000,

                0b00000,

                0b01010,

                0b00000,

                0b10001,

                0b01110,

                0b00000,

                0b00000

              };

//----------------- store the custom characters in arrays ---------------------//


int i;

int x_acc = 0;

int pos = 0;

int data[2];

  

void setup()

{

  pinMode(9, OUTPUT);  

  //---- create custom characters ----//

  lcd.createChar(1, smile);

  //---- create custom characters ----//

  

  // set up the lcd's number of columns and rows: 

  lcd.begin(16, 2);

  lcd.print("ENGINEERS GARAGE");

  lcd.setCursor(0, 1);

  lcd.print("    PS2 MOUSE   ");

  delay(2000);

  digitalWrite(9, HIGH);

  

  mouse.initialize();                                                // initialize the PS2 mouse connected with the Arduino

}


void loop()

{

  x_acc = 0;

  

  for(i = 0; i < 100; i ++)

  {

      mouse.report(data);                                           // get data from the mouse

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

    x_acc = 7;

  else;

  //=== get the average movement in the x direction ===// 

  

  lcd.clear();

  lcd.setCursor((8 + x_acc), 1);                                  // display the smiley at the required position

  lcd.write(1);

  

  pos = x_acc;

  

}

//*************** PS2.h ************//
//#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<<i);

    }

  }

  return x;

}

int PS2Mouse::read_movement_y(int status) {

  int y = read();

  if (bitRead(status, 5)) {

    for(int i = 8; i < 16; ++i) {

      y |= (1<<i);

    }

  }

  return y;

}

void PS2Mouse::pull_low(int pin) {

 pinMode(pin, OUTPUT);

  digitalWrite(pin, LOW);  

}

void PS2Mouse::pull_high(int pin) {

  pinMode(pin, INPUT);

  digitalWrite(pin, HIGH);

}
###

 


Project Source Code

###




#ifndef PS2Mouse_h

#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-Using-PS2-Mouse-Move-Character-LCD

Project Components

  • Arduino Pro Mini
  • LCD
  • LED
  • Resistor

Project Video


Filed Under: Arduino
Tagged With: Arduino, lcd
 

Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.



Tell Us What You Think!! Cancel reply

You must be logged in to post a comment.

HAVE A QUESTION?

Have a technical question about an article or other engineering questions? Check out our engineering forums EDABoard.com and Electro-Tech-Online.com where you can get those questions asked and answered by your peers!


Featured Tutorials

  • Introduction to Brain Waves & its Types (Part 1/13)
  • Understanding NeuroSky EEG Chip in Detail (Part 2/13)
  • Performing Experiments with Brainwaves (Part 3/13)
  • Amplification of EEG Signal and Interfacing with Arduino (Part 4/13)
  • Controlling Led brightness using Meditation and attention level (Part 5/13)
  • Control Motor’s Speed using Meditation and Attention Level of Brain (Part 6/13)

Stay Up To Date

Newsletter Signup

Sign up and receive our weekly newsletter for latest Tech articles, Electronics Projects, Tutorial series and other insightful tech content.

EE Training Center Classrooms

EE Classrooms

Recent Articles

  • Key factors to optimize power consumption in an embedded device
  • EdgeLock A5000 Secure Authenticator
  • How to interface a DS18B20 temperature sensor with MicroPython’s Onewire driver
  • Introduction to Brain Waves & its Types (Part 1/13)
  • An Embedded Developer’s Perspective on IOT (Internet of Things)

Most Popular

5G 555 timer circuit 8051 ai Arduino atmega16 automotive avr bluetooth dc motor display Electronic Part Electronic Parts Fujitsu ic infineontechnologies integratedcircuit Intel IoT ir lcd led maximintegratedproducts microchip microchiptechnology Microchip Technology microcontroller microcontrollers mosfet motor powermanagement Raspberry Pi remote renesaselectronics renesaselectronicscorporation Research samsung semiconductor sensor software STMicroelectronics switch Technology vishayintertechnology wireless

RSS EDABOARD.com Discussions

  • Request for clarification question related to Segger J-Link
  • Dynamic power consumption.
  • Limits of duty cycle for ICM7555 IC?
  • pmos folded cascode vs nmos folded cascode for LDO
  • Pic 16f877A Hex file

RSS Electro-Tech-Online.com Discussions

  • Help wanted to power an AC120v induction motor ( edited from Brushless motor - thank you @SHORTBUS= )
  • How does a NOAC work?
  • Need help working with or replacing a ferrite tube
  • Trying to make a custom automated water container for my UV purifier. Can anyone help with where to begin?
  • Funny Images Thread!
Engineers Garage
  • Analog IC TIps
  • Connector Tips
  • DesignFast
  • EDABoard Forums
  • EE World Online
  • Electro-Tech-Online Forums
  • Microcontroller Tips
  • Power Electronic Tips
  • Sensor Tips
  • Test and Measurement Tips
  • 5G Technology World
  • About Us
  • Contact Us
  • Advertise

Copyright © 2022 WTWH Media LLC. All Rights Reserved. The material on this site may not be reproduced, distributed, transmitted, cached or otherwise used, except with the prior written permission of WTWH Media
Privacy Policy | Advertising | About Us

Search Engineers Garage

  • Projects and Tutorials
    • Electronic Projects
      • 8051
      • Arduino
      • ARM
      • AVR
      • PIC
      • Raspberry pi
      • STM32
    • Tutorials
    • Circuit Design
    • Project Videos
    • Components
  • Articles
    • Tech Articles
    • Insight
    • Invention Stories
    • How to
    • What Is
  • News
    • Electronic Products News
    • DIY Reviews
    • Guest Post
  • Forums
    • EDABoard.com
    • Electro-Tech-Online
    • EG Forum Archive
  • Digi-Key Store
    • Cables, Wires
    • Connectors, Interconnect
    • Discrete
    • Electromechanical
    • Embedded Computers
    • Enclosures, Hardware, Office
    • Integrated Circuits (ICs)
    • Isolators
    • LED/Optoelectronics
    • Passive
    • Power, Circuit Protection
    • Programmers
    • RF, Wireless
    • Semiconductors
    • Sensors, Transducers
    • Test Products
    • Tools
  • EE Resources
    • DesignFast
    • LEAP Awards
    • Oscilloscope Product Finder
    • White Papers
    • Webinars
  • EE Learning Center
    • Design Guides
      • WiFi & the IOT Design Guide
      • Microcontrollers Design Guide
      • State of the Art Inductors Design Guide
  • Women in Engineering