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 */
}