PS2/Mouse Interface
Mission Statement
I was given the task of creating a serial bidirectional 2-line interface for a PS2Mouse such that it will be able to talk in PS2Mouse Protocol to the MBED. Eventually this is to be placed on the bottom of the Sumovore, such that it is able to calibrate its motors for straight driving and also to create a distance counter and possibly even a position detector/logger.
Pinout
Looking into end of the plug:
nc ---> o o <--- clk
+5V ---> o o <--- GND
||
nc ---> o || o <--- data
N.B. There is no need to ground the nc pins.
Hello World! - Mouse Style
There isn't currently a class which deals with the bidirectional IO lines used in PS2 mice. When communicating with a PS2mouse, the clocking is always done by the device and the host has to look on; despite this, the host is the one in control! The host and mouse have to do a little dance to each other before they know for sure that data may be transmitted in either direction. In the following program the host (MBED) sends out the command 0xFF which means RESET and the mouse undergoes a BAT (Basic Assurance Test) - a self-diagnostic -. The mouse then replies with 0xAA for SUCCESS or 0xFC for ERROR, followed by its ID (normally 0x00). Thereafter the mouse is plunged into Stream Mode.
As can be seen, the rd() and wr() functions are fairly chunky and not very nice at all, so having included them in the PS2Mse class will come as a relief to many. I have used the printf() function from the serial class to display my data in Tera term, which I highly recommend!
Modes of Operation
The PS2Mouse has four modes of operation;
| Reset Mode:: The mouse is in this mode on power up and after receiving the mse.reset() function |
| Stream Mode:: This is the default mode. Movement Data Packages are sent to the host (MBED) whenever there is a change in status or position. It is entered after reset mode. |
| Remote Mode:: Here the mouse only ever sends information when requested. |
| Wrap Mode:: The mouse sends every byte received back to the host. |
I have only decided to include Reset and Stream modes, since they are the two most commonly used. Despite this, I may later include a PS2Mse_extension class to cater for the plethora of functions less used.
Example Program
N.B.
Before any of the data may be taken from the mouse the initialise(void) function MUST be stated in the coding. If this is not done the mouse may not return the data wanted. It really depends on the type of mouse!
Default Settings
The set_defaults(void) function set the following settings:
| Sample Rate | 100 samples/sec |
| Resolution | 4 counts/mm |
| Scaling | 1:1 |
| Data reporting | OFF |
To alter the above settings you will either have to follow the link to http://www.computer-engineering.org/ps2mouse/ where the commands are stated, whereupon you may simply write the hex command into the wr() function i.e.
wr(0xE9); //status request
(you will have to edit the metric_ x or y() function in order to accommodate for a different conversion value to convert from counts to millimetres) or wait till I write and upload an extension to the PS2Mse class, however, for the current time I doubt there will be a great need for the PS2Mse_extension class.
Cool Mini-Project
Cursor
The following program takes the mouse coordinates and uses them to plot a cursor on a small Nokia LCD Screen, which in effect is using the primary function of the mouse, as a pointer.
#include "mbed.h" #include "PS2Mse.h" #include "MobileLCD.h" PS2Mse mse(28, 26); MobileLCD lcd(5, 6, 7, 8, 9); Serial pc(USBTX, USBRX); int last_x = 0; int last_y = 0; int main() { mse.initialise(); lcd.background(0x000000); while(1) { int x = (int)mse.metric_x(1); int y = (int)mse.metric_y(1); y = -y; if((x < 2)||(y < 2)) { continue; } lcd.pixel(last_x, last_y, 0x000000); lcd.pixel((last_x+1), last_y, 0x000000); lcd.pixel(last_x, (last_y+1), 0x000000); lcd.pixel((last_x+1), (last_y+1), 0x000000); lcd.pixel(x, y, 0xFFFFFF); lcd.pixel((x+1), y, 0xFFFFFF); lcd.pixel(x, (y+1), 0xFFFFFF); lcd.pixel((x+1), (y+1), 0xFFFFFF); last_x = x; last_y = y; } }
The following link is to a video of the cursor http://mbed.co.uk/projects/cookbook/svn/PS2Mouse/doc/Mouse%20cursor.avi
API
Follow this link to the PS2Mse library:
http://mbed.co.uk/projects/cookbook/svn/PS2Mouse/trunk
| PS2Mse | a PS2 Mouse interface |
| Functions | |
| PS2Mse | Creates an instance of the PS2Mse class. |
| rd | read a single byte without ignoring parity and START/STOP bits |
| wr | write out a command |
| rd_movement | read the movement vectors and button statuses |
| reset | reset mouse |
| set_defaults | set mouse defaults |
| enable_data_reporting | enable movement data packages to be sent from the mouse |
| initialise | configure the mouse |
| metric_x | converts x-axis movement vectors into metric |
| metric_y | converts y-axis movement vectors into metric |
| button_status | turns the various button flags on and off depending on the status of the buttons |
More Info
For some more information on how a mouse works, take a look at the following sites:
- Mouse Stuff http://www.computer-engineering.org/ps2mouse/
- 2's Complement Values http://en.wikipedia.org/wiki/2%27s_complement
Have Fun!
Dan W



