PS2 Mouse

Hello
I've a problem to connect the ps2 mouse to arduino. I've use the ps2-library directly from arduino.cc, use leonardo board and connected my asus usb-mouse to the arduinoboard(VCC= red, ground= black, green=clock(3), white = date(2)). I've tried with sevaral pins. When i use the mouse example from arduino.cc, it compiled but i haven't a result on the Serial-Monitor.
Can anybody help me? :cold_sweat:

A USB mouse is NOT a PS/2 mouse. If you wanna connect a USB mouse, you have to use a USB host shield or an Arduino Due (which incorporates similar hardware).

I found out that some USB mouses are just a PS/2 mouse... Mostly the simple ones..
It doesnt seem like the one you got is a ps/2 mouse so you need the usb host like pylon says.

I've readed that this will be function in the Practical Arduino Book from Jonathan Oxer.
Is there a possibility to connect an USB mouse to Arduino? I've need this for my schoolproject. I will read with the optical mouse the position coordinates of may robo-car. Have everybody done this befor and can send me the sourcecode and library?

You can connect a usb mouse to a usb host shield. Libraries that support mice are provided.

http://www.circuitsathome.com/products-page/arduino-shields/usb-host-shield-2-0-for-arduino

We are using PS/2 mouse to measure wheel rotation, and I don't see why typical USB-mouse wouldn't do that as well.

So, it's time to se the code....?

Cheers,
Kari

I've connected an old PS2-Mouse with a "ball" for tracking. And it works fine. But when I connect an Optical PS2-Mouse, I haven't a signal. I've debugged the code an saw that it hang up in de while loop:

while (digitalRead(MCLK) == HIGH)
;
Anybody a solution?

/*
 * an arduino sketch to interface with a ps/2 mouse.
 * Also uses serial protocol to talk back to the host
 * and report what it finds.
 */

/*
 * Pin 5 is the mouse data pin, pin 6 is the clock pin
 * Feel free to use whatever pins are convenient.
 */
#define MDATA 5
#define MCLK 6
#define MOUSE_FULL_TURN 1510
#define MOUSE_CPI 384 

int     lastMouseX, lastMouseY;
float   lastHead, lastDistance;
float   y_mou, x_mou;
float   dX, dY;
float   dHead;
float   heading_mou;


/*
 * according to some code I saw, these functions will
 * correctly set the mouse clock and data pins for
 * various conditions.
 */
void gohi(int pin)
{
  pinMode(pin, INPUT);
  digitalWrite(pin, HIGH);
}

void golo(int pin)
{
  pinMode(pin, OUTPUT);
  digitalWrite(pin, LOW);
}

void mouse_write(char data)
{
  char i;
  char parity = 1;

  //  Serial.print("Sending ");
  //  Serial.print(data, HEX);
  //  Serial.print(" to mouse\n");
  //  Serial.print("RTS");
  /* put pins in output mode */
  gohi(MDATA);
  gohi(MCLK);
  delayMicroseconds(300);
  golo(MCLK);
  delayMicroseconds(300);
  golo(MDATA);
  delayMicroseconds(10);
  /* start bit */
  gohi(MCLK);
/* wait for mouse to take control of clock);  -----------------------------------------------------------------------------hang up in this loop*/
  while (digitalRead(MCLK) == HIGH)
    ;
  
   /* clock is low, and we are clear to send data */
  for (i=0; i < 8; i++) {
    if (data & 0x01) {
      gohi(MDATA);
    } 
    else {
      golo(MDATA);
    }

    /* wait for clock cycle */
    while (digitalRead(MCLK) == LOW)
      ;
    while (digitalRead(MCLK) == HIGH)
    ;
  
            
    parity = parity ^ (data & 0x01);
    data = data >> 1;
     
}  
  /* parity */
  if (parity) {
    gohi(MDATA);
  } 
  else {
    golo(MDATA);
  }
  while (digitalRead(MCLK) == LOW)
    ;
 
  while (digitalRead(MCLK) == HIGH)
    ;
  /* stop bit */
  gohi(MDATA);
  delayMicroseconds(50);
  while (digitalRead(MCLK) == HIGH)
    ;
  /* wait for mouse to switch modes */
  while ((digitalRead(MCLK) == LOW) || (digitalRead(MDATA) == LOW))
    ;
  /* put a hold on the incoming data. */
  golo(MCLK);
  //  Serial.print("done.\n");
}

/*
 * Get a byte of data from the mouse
 */
char mouse_read(void)
{
  char data = 0x00;
  int i;
  char bit = 0x01;

  //  Serial.print("reading byte from mouse\n");
  /* start the clock */
  gohi(MCLK);
  gohi(MDATA);
  delayMicroseconds(50);
  while (digitalRead(MCLK) == HIGH)
    ;
  delayMicroseconds(5);  /* not sure why */
  while (digitalRead(MCLK) == LOW) /* eat start bit */
    ;
  for (i=0; i < 8; i++) {
    while (digitalRead(MCLK) == HIGH)
      ;
    if (digitalRead(MDATA) == HIGH) {
      data = data | bit;
    }
    while (digitalRead(MCLK) == LOW)
      ;
    bit = bit << 1;
  }
  /* eat parity bit, which we ignore */
  while (digitalRead(MCLK) == HIGH)
    ;
  while (digitalRead(MCLK) == LOW)
    ;
  /* eat stop bit */
  while (digitalRead(MCLK) == HIGH)
    ;
  while (digitalRead(MCLK) == LOW)
    ;

  /* put a hold on the incoming data. */
  golo(MCLK);
  //  Serial.print("Recvd data ");
  //  Serial.print(data, HEX);
  //  Serial.print(" from mouse\n");
  return data;
}

void mouse_init()
{
  gohi(MCLK);
  gohi(MDATA);
  //  Serial.print("Sending reset to mouse\n");
  mouse_write(0xff);
  mouse_read();  /* ack byte */
  //  Serial.print("Read ack byte1\n");
  mouse_read();  /* blank */
  mouse_read();  /* blank */
  //  Serial.print("Sending remote mode code\n");
  mouse_write(0xf0);  /* remote mode */
  mouse_read();  /* ack */
  //  Serial.print("Read ack byte2\n");
  delayMicroseconds(100);
}

void setup()
{
  Serial.begin(9600);
  while (!Serial) { }
  //Serial.print("Initialization of Mouse");
  mouse_init();  
}

/*
 * get a reading from the mouse and report it back to the
 * host via the serial line.
 */
void loop()
{
  char mstat;
  int sensMouseX;
  int sensMouseY;
  float dPos;

  /* get a reading from the mouse */
  mouse_write(0xeb);  /* give me data! */
  mouse_read();      /* ignore ack */
  mstat = mouse_read();
  sensMouseX = (int)mouse_read();
  sensMouseY = (int)mouse_read();

  dX = sensMouseX - lastMouseX;
  dHead = dX * 360.0 / MOUSE_FULL_TURN;
  heading_mou += dHead;
  lastHead += dHead;

  while (heading_mou>=359)
    heading_mou-= 360.0;
  while (heading_mou<0)
    heading_mou+= 360.0;   

  dY = sensMouseY - lastMouseY;
  lastDistance += dY * 25.4 / MOUSE_CPI;
  dPos = dY * cos(heading_mou * PI/180) * 25.4 / MOUSE_CPI;
  y_mou += dPos;
  dPos = dY * sin(heading_mou * PI/180) * 25.4 / MOUSE_CPI;
  x_mou += dPos; 
  

  /* send the data back up */
  //Serial.print("Heading=");
  //Serial.print(lastHead, DEC);
  Serial.print("\tDistance=");
  Serial.print(lastDistance, DEC);
  Serial.println();
  //Serial.print(mstat, BIN);
  Serial.print("X=");
  Serial.print(dX, DEC);
  Serial.print("\tY=");
  Serial.print(dY, DEC);
  Serial.println();
  delay(20);  /* twiddle */
}

Hello i´m a Arduino beginner an I need help with the ps2 Protocol.
I want to take a laptop trackpannel to control my MIDI gear.
How can I read the mouse scroll in my sketch?

/*
Pin 5 is the mouse data pin, pin 6 is the clock pin
Pin 8 and 9 are connected with Resistors to 2 leds
Feel free to use whatever pins are convenient.
/
#define MDATA 5
#define MCLK 6
int xn = 0;
int yn = 0;
int xa;
int ya;
int mxn;
/

*/
int led = 8;
int helligkeit_led = 0;
int led1 = 9;
int helligkeit_led1 = 0;

boolean l = 0;
boolean r= 0;
boolean m= 0;
boolean la;
boolean ra;
boolean ma;

void gohi (int pin)
{
pinMode (pin, INPUT);
digitalWrite (pin, HIGH);
}

void golo (int pin)
{
pinMode (pin, OUTPUT);
digitalWrite (pin, LOW);
}

void mouse_write (char data)
{
char i;
char parity = 1;

// Serial.print("Sending ");
//// Serial.print(" to mouse\n");
//Serial.print("RTS");

/* put pins in output mode */
gohi (MDATA);
gohi (MCLK);

delayMicroseconds(300);
golo (MCLK);

delayMicroseconds(300);
golo (MDATA);

delayMicroseconds(10);
/* start bit /
gohi (MCLK);
/
wait for mouse to take control of clock); /
while (digitalRead(MCLK) == HIGH);
/
clock is low, and we are clear to send data /
for (i = 0; i < 8; i++)
{
if (data & 0x01)
{
gohi(MDATA);
}
else
{
golo(MDATA);
}
/
wait for clock cycle /
while (digitalRead(MCLK) == LOW)
;
while (digitalRead(MCLK) == HIGH)
;
parity = parity ^ (data & 0x01);
data = data >> 1;
}
/
parity */
if (parity)
{
gohi(MDATA);
}
else
{
golo(MDATA);
}
while (digitalRead(MCLK) == LOW);
while (digitalRead(MCLK) == HIGH);

/* stop bit */
gohi(MDATA);
delayMicroseconds(50);
while (digitalRead(MCLK) == HIGH);

/* wait for mouse to switch modes /
while ((digitalRead(MCLK) == LOW) || (digitalRead(MDATA) == LOW));
/
put a hold on the incoming data. */
golo (MCLK);
// Serial.print("done.\n");
}

/Get a byte of data from the mouse/
char mouse_read(void)
{
char data = 0x00;
char bit = 0x01;
int i;

// Serial.print("reading byte from mouse\n");
// delay (500);

/* start the clock */
gohi (MCLK);

gohi (MDATA);

delayMicroseconds(50);

while (digitalRead(MCLK) == HIGH);

delayMicroseconds(5); /* not sure why */

while (digitalRead(MCLK) == LOW); /* eat start bit */

for (i = 0; i < 8 ; i++)
{
while (digitalRead(MCLK) == HIGH);
if (digitalRead(MDATA) == HIGH)
{
data = data | bit;
}
while (digitalRead(MCLK) == LOW);
bit = bit << 1;
}
/* eat parity bit, which we ignore /
while (digitalRead(MCLK) == HIGH);
while (digitalRead(MCLK) == LOW);
/
eat stop bit */
while (digitalRead(MCLK) == HIGH);
while (digitalRead(MCLK) == LOW);

/* put a hold on the incoming data. */
golo (MCLK);

//Serial.print("Recvd data ");
//Serial.println(data, DEC);
// Serial.print(" from mouse\n");

return data;
}

void mouse_init()
{
gohi (MCLK);
gohi (MDATA);
// Serial.print("Sending reset to mouse\n");
mouse_write (0xff);
mouse_read(); /* ack byte /
// Serial.print("Read ack byte1\n");
mouse_read(); /
blank /
mouse_read(); /
blank /
// Serial.print("Sending remote mode code\n");
mouse_write (0xf0); /
remote mode /
mouse_read(); /
ack */
// Serial.print("Read ack byte2\n");
delayMicroseconds(100);
}

void X_Y()
{
char mstat;
char mx;
char my;
char mz;
boolean ml;
boolean mr;
boolean mm;

/* get a reading from the mouse /
mouse_write(0xeb); /
give me data! /
mouse_read(); /
*/
mstat = mouse_read();

mx = mouse_read(); //X Axis
my = mouse_read(); //Y Axis
//mz = mouse_read1(); //Z Axis

ml = bitRead(mstat, 0); //Rightclick
mr = bitRead(mstat, 1); //Leftclick
mm = bitRead(mstat, 2); //Middleclick

if (((mx || my) != 0) || (la != ml) || (ra != mr) || (ma != mm))
{
xn = xa + mx;
yn = ya + my;
// zn = ya+my;

l = ml;
r = mr;
m = mm;

xn = constrain(xn, -127, 127); //sets limit
yn = constrain(yn, -127, 127); //sets limit

Serial.print(mstat, BIN);
Serial.print("\tmx=");
Serial.print(mx, DEC);
Serial.print("\tX=");
Serial.print(xn, DEC);
Serial.print("\tmy=");
Serial.print(my, DEC);
Serial.print("\tY=");
Serial.print(yn, DEC);
Serial.print("\tl=");
Serial.print(l);
Serial.print("\tr=");
Serial.print(r);
Serial.print("\tm:=");
Serial.print(m);
// Serial.print("\tmz=");
// Serial.print(mz, DEC);
Serial.println();

xa = xn; //buffer
ya = yn; //buffer
la = l; //buffer
ra = r; //buffer
ma = m; //buffer
// za = zn;
}
}
void setup()
{
Serial.begin(9600);
mouse_init();
}
void loop()
{

X_Y();
helligkeit_led = map(xn, -127, 127, 0, 255);
analogWrite(led, helligkeit_led );

helligkeit_led1 = map(yn, -127, 127, 0, 255);
analogWrite(led1, helligkeit_led1 );

}

Was anyone able to find a solution to marco131's question? I have the same issue. Ball ps2 mouse works great, but optical ps2 mouse lights up but no data. It seems to stick on the statement checking for when the clock goes low [while (digitalRead(MCLK) == HIGH)]. Any help is hugely appreciated.

FYI: I am making a stitch regulator for my wife's sewing machine which will increase speed that faster the fabric is moved and slower stitching the slower the fabric moves to achieve constant distance between stitches. All working, but optical would be better than ball mouse on fabric. Thanks!

Did you figure this out @alchle ? I'm working on the same project (stitch regulator) and I've had success with a native PS/2 optical mouse, the "Logitech PS/2 Optical Wheel Mouse" which I bought recently from Amazon ( https://www.amazon.com/gp/product/B000HGMMH6/ref=oh_aui_search_detailpage?ie=UTF8&psc=1 )