Sterowanie promieniem lasera za pomocą komputerowej myszy
6 Lipiec 2011 Arduino
Artykuł przedstawia w jaki sposób można sterować promieniem lasera za pomocą myszki PS2. Układ nie potrzebuje dostępu do komputera.
Przykładowy film przedstawiający zastosowanie układu.
Potrzebne będą:
- Arduino UNO
- 2x Serwo, np TG9e
- Myszka PS2
- Laser
- Zasilanie zewnętrzne 4,5V
- kabelki podłączeniowe
Układ podłączeniowy
Kod dla Arduino
[ csharp ] code.pdeZaznacz cały
/* * 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 #include <Servo.h> Servo servoX,servoY; /* * 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); */ 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); } int angleX = 100; int angleY = 100; int angleX_memo = 100; int angleY_memo = 100; int sensivity = 4; void setup() { Serial.begin(9600); servoX.attach(9); servoY.attach(10); angleX = angleX * sensivity; angleY = angleY * sensivity; mouse_init(); } /* * get a reading from the mouse and report it back to the * host via the serial line. */ void loop() { char mstat; char mx; char my; int n; /* get a reading from the mouse */ mouse_write(0xeb); /* give me data! */ mouse_read(); /* ignore ack */ mstat = mouse_read(); mx = mouse_read(); my = mouse_read(); servoX.write(angleX/sensivity); servoY.write(angleY/sensivity); /* send the data back up */ Serial.print(mstat, DEC); Serial.print("\tX="); Serial.print(mx, DEC); Serial.print("\tY="); Serial.print(angleX); Serial.println(); n = (mstat); Serial.print(n); if (n==10){ angleX_memo = angleX; angleY_memo = angleY; } if (n==9){ angleX = angleX_memo ; angleY = angleY_memo ; } angleX = angleX - mx; angleY = angleY + my; if (angleX > 180*sensivity) angleX=180*sensivity; if (angleX < 0) angleX=0; if (angleY > 180*sensivity) angleY=180*sensivity; if (angleY < 0) angleY=0; delay(1); /* twiddle */ }
Przeczytaj także
Copyright © TutorialSource 2012

