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

saper_arduino

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

Kategorie