首页 > 解决方案 > Java Robot keyPress 按住一个键

问题描述


我今天正在尝试制作一个 arduino 项目,该项目可以基于随后由 Java 应用程序处理的串行通信“复制”或模拟键盘。
因此,我正在尝试编写一个与我的 Arduino Mega 接口的 Java 应用程序以“复制”键盘,并且我需要 Java 应用程序将接收到的串行字节“转换”为击键以发送到操作系统本身。问题是,无论我试图在串行读取字节不变的情况下保持按下键,我都会陷入单键按下情况或在几乎没有时间的情况下发送的无限循环击键(游戏我'我目前正在为这个项目做这个项目这个想法来自哪里预期的行为当前的行为......)
我还想说,我知道我可以对 Arduino 固件进行重新编程,使其被识别为另一个“桥”芯片,以使键盘库正常工作,但我也希望能够将此板用于其他项目,并且只需重新编译和上传我每次需要的草图并在一分钟内切换项目对我来说是必须的,因为我周围只有一块板,只是买了便宜的装备而不是“法布里亚诺”,节省了一些妈妈的学校预算“ 一个(我住的地方是知名的、优质且不便宜的品牌)……

这是我的 Arduino 代码(如果需要,但非常适合它需要做的事情):

const int SECOND = 1000;
const int Hz = 2; // change to 250Hz~1000Hz when ready to use
const int firstPin = A6;
const int secondPin = A7;

void setup() {
  pinMode(13, OUTPUT);
  pinMode(firstPin, INPUT);
  pinMode(secondPin, INPUT);
  analogWrite(firstPin, LOW); // initialize to LOW both pins to overcome
  analogWrite(secondPin, LOW); // incorrect read values in the future
}

void sendData() {
  if (analogRead(firstPin) > 300) {
    Serial.write(0b00001011);
  }
  else {
    Serial.write(0b00001010);
  }
  if (analogRead(secondPin) > 300) {
    Serial.write(0b00010101);
  }
  else {
    Serial.write(0b00010100);
  }
}

int connectionSetup() {
  Serial.begin(9600);
  while(!Serial.available()) {
    ;
  }
  if(Serial.read()==0b10101010) {
    Serial.write(0b10101010);
    Serial.write(0b01010101);
    while(!Serial.available()) {
      ;
    }
    if(Serial.read()==0b01010101) {
      return 0;
    }
  }
  return -1;
}

void loop() {
  if(connectionSetup() == 0) {
    while(true) {
      sendData();
      delay (SECOND / Hz);
    }
  }
}


这是我的错误 Java 代码:

package ArduinoSerialKeyboard;
import com.fazecast.jSerialComm.*;
import java.awt.AWTException;
import java.io.IOException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
/**
 *
 * @author BJPGameVideosITA
 */
public class Startup {
    private static SerialPort sp = SerialPort.getCommPort("COM5"); // device name, change it if needed
    private static int key1 = KeyEvent.VK_Q, key2 = KeyEvent.VK_W; // change if needed
    private static boolean key1state = false, key2state = false;
    private static Thread t;

    private static int setup() throws IOException, InterruptedException {
        sp.setComPortParameters(9600, 8, 1, 0); // default connection settings for Arduino
        sp.setComPortTimeouts(SerialPort.TIMEOUT_READ_BLOCKING, 0, 0); // block until bytes can be read
        t = new Thread(new Runnable() {
            @Override
            public void run() {
                pressKey.setup(key1, key2);
            }
        });
        t.start();
        if (sp.openPort()) {
            System.out.println("Port opened!");
            Thread.sleep(1000); // waits for the serial connection to be established and ready
            sp.getOutputStream().write(0b10101010);
            sp.getOutputStream().flush();
            while(sp.getInputStream().available() < 1) {
                ;
            }
            if(sp.getInputStream().read()==0b10101010) {
                while(sp.getInputStream().available() < 1) {
                    ;
                }
                if(sp.getInputStream().read()==0b01010101) {
                    sp.getOutputStream().write(0b01010101);
                    sp.getOutputStream().flush();
                    return 0;
                }
            }
            System.out.println("Error in synchronization!");
            return -1;
        }
        else {
            System.out.println("Error in opening port!");
            return -1;
        }
    }

    private static int read() throws IOException {
        while(sp.getInputStream().available() < 1) {
            ;
        }
        int b = sp.getInputStream().read();
        return b;
    }

    private static void keyboard() throws IOException {
        boolean exit = false;
        do {
            int read = read();
            if(read == -1) {
                break;
            }
            switch (read) {
                case 10: if(!key1state) {pressKey.stop(1); key1state=!key1state;} break;
                case 11: if(key1state) {pressKey.start(1); key1state=!key1state;} break;
                case 20: if(!key2state) {pressKey.stop(2); key2state=!key2state;} break;
                case 21: if(key2state) {pressKey.start(2); key2state=!key2state;} break;
                case 0: exit = true; break;
            }
        } while (!exit);
    }

    private static int close() {
        if (sp.closePort()) {
            System.out.println("Port closed!");
        }
        else {
            System.out.println("Error in closing port!");
            return -1;
        }
        return 0;
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        setup();
        keyboard();
        close();
    }
}

class pressKey {
    private static boolean toPress[] = {false, false};
    private static int key1, key2;

    public static void setup(int k1, int k2) {
        key1 = k1;
        key2 = k2;
    }

    private static void run(int key) {
        try {
            Robot robot = new Robot();
            if(key == key1) {
                while (toPress[0]) {
                    robot.keyPress(key1);
                }
                robot.keyRelease(key1);
            }
            if(key == key2) {
                while (toPress[1]) {
                    robot.keyPress(key2);
                }
                robot.keyRelease(key2);
            }
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }

    public static void start(int key) {
        toPress[key-1] = true;
        if(key == 1)
            run(key1);
        if(key == 2)
            run(key2);
    }

    public static void stop(int key) {
        toPress[key-1] = false;
    }
}


提前感谢大家,任何帮助表示赞赏。

PS:我发现了其他 StackOverflow 问题,但它们都与无论如何保持键关闭有关,我需要将它保持下来,就好像它是由用户处理的一样,让操作系统处理它(这意味着它必须停止一段时间在第一次按下之后,然后按下每个 TimeoutSetByTheOperatingSystem 秒,而不是像视频中所示的那样粉碎超过 9000 次,因为前面提到的游戏需要按下键而不是按下键来保持“滑块”,如“其中想法来自“视频...有关游戏本身的更多信息)我已经尝试过所有这些都没有成功...谢谢!

标签: javaarduinokeyboarddeserializationinterpreter

解决方案


推荐阅读