Greeting, first time Arduino user here.
So I am using the Arduino Micro as an HID keyboard device. It accepts arbitrary input from a Node-JavaScript program I am running (so I have full freedom in in the data transferred to the micro).
The goal is for the data transmitted to the micro to include information about a keypress: whether it was pressed or released and which key it is. The serial connections are all fine and dandy - I just have questions regarding the key pressing logic.
As far as the JavaScript program goes, a key down is detected based on the keyCode, not the character code so when tapping “a”, character code 97, the Arduino micro is receiving “A”, character code 65 since the JavaScript detected keyCode is 65. So that all sounds like problems with JavaScript (which it is), but remember that I have freedom in portraying the information sent to the micro.
That being said, instead of detecting by keyCodes and character codes in JavaScript, I could just transmit the letter e.g. “a” with some identifier for press/release such as “+a” for release and “-a” for press. My problem here is how would I handle modifier keys using the Keyboard library.
Should I handle character keys and modifiers keys separately i.e. Keyboard.write
for characters and Keyboard.press/release
for modifiers or are there cases where it would make sense to press and hold “a” (which would also be different than pressing and holding “A”)?
Below is my original code using keyCodes and “u/d” identifiers to denote up or down (which I am thinking now that “u/d” could be easily confused as a letter if I decide to transmit characters as characters:
/*
Receives from the hardware serial, sends to software serial.
Receives from software serial, sends to hardware serial.
The circuit:
RX is digital pin 10 (connect to TX of other device)
TX is digital pin 11 (connect to RX of other device)
Not all pins on the Leonardo and Micro support change interrupts,
so only the following can be used for RX:
8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
*/
#include <SoftwareSerial.h>
#include <Keyboard.h>
SoftwareSerial rpiSerial(10, 11); // RX, TX
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
// Set the data rate for the SoftwareSerial port
rpiSerial.begin(115200);
// initialize control over the keyboard:
Keyboard.begin();
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Keyboard Serial Connection Established");
}
String keyCode = "";
char state;
void loop() {
while (rpiSerial.available() > 0) {
// "Type" via keyCodes (recommended for modifiers)
// https://www.arduino.cc/en/Reference/KeyboardWrite not behaving as expected
int data = rpiSerial.read();
if (isDigit(data)) {
keyCode += (char)data;
}
if (isAlpha(data)) {
state = (char)data;
}
if (data == '\n') {
Serial.print(state);
Serial.println(keyCode.toInt());
if (state == 'd') {
Keyboard.press(keyCode.toInt());
}
if (state == 'u') {
Keyboard.release(keyCode.toInt());
}
keyCode = "";
char state;
}
}
}
I have also noticed that the data from the serial connection parsed by the micro is sometimes incorrect i.e. a keyCode will be misidentified. For instance, by repeatedly pressing “a” through my JavaScript program, the JavaScript program will consistently identify keyCode 65 yet Arduino will identify the received data as keyCode 65 most of the time and then randomly keyCode 64. This happens with other keys as well and the keyCode doesn’t always happen to be just one less nor does it always occur after “n” presses.