arduino-libraries / Keyboard

GNU Lesser General Public License v3.0
229 stars 160 forks source link

Keyboard with modifier keys not working as expected #83

Closed arjena closed 1 year ago

arjena commented 1 year ago

I am trying to make four buttons to act as modifiers (I'm on a Mac, so those are command, alt, control and shift). In my work, most of the time I use my left hand only to press these buttons on the keyboard and my right hand to draw on a tablet, use the mouse and type a single character. For instance command-alt-forwardslah or command-'plus sign'. You get the picture. Due to an operation I will not be able to use my left hand for a while so I thought if I can use my feet to press the modifiers, I can still work with only my right hand. My code is 'sort of' working. If I press one of the buttons, functions in the OS are modified as expected. Like selecting multiple items (shift or command key), right mouse click (control) and copy drag files (alt). But pressing one (or multiple) key and a key on the (real) keyboard does not work. And that is the whole point of these buttons. Is it at all possible what I am trying to achieve or is my code simply faulty?


  #include <Keyboard.h>

  const int cmndPin = 4;         // input pin for command button
  const int altPin = 5;         // input pin for alt button
  const int cntrlPin = 6;         // input pin for control button
  const int shiftPin = 7;       // input pin for shoft button
  const int disablePin = 8;         // input pin for disable button, just to be sure the keyboard function does not interfere with   reprogramming
  bool cmnd = false;
  bool cntrl = false;
  bool alt = false;
  bool shift = false;

  void setup() {
    // make the pushButton pin an input:
    pinMode(cmndPin, INPUT_PULLUP);
    pinMode(cntrlPin, INPUT_PULLUP);
    pinMode(altPin, INPUT_PULLUP);
    pinMode(shiftPin, INPUT_PULLUP);
    pinMode(disablePin, INPUT_PULLUP);
    // initialize control over the keyboard:
    Keyboard.begin();
  }

  void loop() {
    //check if we are in programming or keyboard mode
    int disableState = digitalRead(disablePin);
    // read the pushbuttons:
    if (disableState) {
      int cmndState = digitalRead(cmndPin);
      int cntrlState = digitalRead(cntrlPin);
      int altState = digitalRead(altPin);
      int shiftState = digitalRead(shiftPin);

    //if the command button is pressed send keypress to computer (left and right to see
    //if this solves my problem, but it does not) and set a flag to prevent repeating key-presses
    if (!cmndState && !cmnd) {
      Keyboard.press(KEY_LEFT_GUI);
      Keyboard.press(KEY_RIGHT_GUI);
      cmnd = true;
    }

    //if the command button is released, release the key-press and reset the flag. 
    if (cmndState && cmnd) {
      Keyboard.release(KEY_LEFT_GUI);
      Keyboard.release(KEY_RIGHT_GUI);
      cmnd = false;
    }

    if (!altState && !alt) {
      Keyboard.press(KEY_LEFT_ALT);
      Keyboard.press(KEY_RIGHT_ALT);
     alt = true;
    }

    if (altState && alt) {
      Keyboard.release(KEY_LEFT_ALT);
      Keyboard.release(KEY_RIGHT_ALT);
      alt = false;
    }
    if (!cntrlState && !cntrl) {
      Keyboard.press(KEY_LEFT_CTRL);
      Keyboard.press(KEY_RIGHT_CTRL);
      cntrl = true;
    }

    if (cntrlState && cntrl) {
      Keyboard.release(KEY_LEFT_CTRL);
      Keyboard.release(KEY_RIGHT_CTRL);
      cntrl = false;
    }
    if (!shiftState && !shift) {
      Keyboard.press(0x81);
      Keyboard.press(0x85);
      shift = true;
    }

    if (shiftState && shift) {
      Keyboard.release(0x81);
      Keyboard.release(0x85);
      shift = false;
    }

  }

}
edgar-bonet commented 1 year ago

This looks like a problem at the OS level, rather than a problem with your code. If I understand correctly, the issue is that, if you press Command on one keyboard and C on another keyboard, the OS does not interpret that as the Command+C combination.

The only solution I can think of is to connect your keyboard to the Arduino, and have the Arduino forward the key actuations to the computer… adding the modifiers. Then, as far as the computer is concerned, there is only one keyboard. You would need something like a USB host shield. I have no experience with those.

arjena commented 1 year ago

Thanks for your reply and yes, you are right. I just attached an extra keyboard to my laptop and indeed pressing a modifier on one and a key on the other does not take the modifier into account. Hopefully someone knows how to solve this. I have an Arduino due with two usb ports, where one is supposed to have USB-host capabilities. Will definitely check this tomorrow.