4

I am trying to make Arduino Uno to act as a keyboard. I have successfully flashed the USB-HID firmware in it using this link also and programmed it like this.

uint8_t buf[8] = {
 0
};

int inpin1 = 7; 
int inpin2 = 8;
int val1 = 0;
int val2 = 0;

void setup() {
  Serial.begin(9600);
  delay(200);
  pinMode(inpin1, INPUT);
  pinMode(inpin2, INPUT);
}

void loop() {
  val1 = digitalRead(inpin1);
  if(val1 != HIGH) {
   buf[2] = 80; // Left Arrow
   Serial.write(buf, 8);
   releaseKey();
  }
  val2 = digitalRead(inpin2);
  if(val2 != HIGH) {
    buf[2] = 79; // Right Arrow
    Serial.write(buf, 8);
    releaseKey();
  }
}

void releaseKey() {
  buf[0] = 0;
  buf[2] = 0;
  Serial.write(buf, 8);
}

The above code works fine but the problem is that when I tried to play a game, which uses right arrow and left arrow, and to control a car I was using the push button, which I connected to Arduino as left and right arrow keys. But suppose I want to turn a car. I have to press the key and then release the key to move it a very little to the right or left. So, if I want to turn the car either left or right, I have to press and release so many times that it becomes impossible to play the game. Do you anyone know how to resolve this problem?

2
  • 2
    I believe this library that goes along with it. That would be the way to go instead of sending byte array through serial. This way you have the functions press and release, that you need.
    – Gerben
    Commented Jan 9, 2017 at 19:25
  • +1 for impressive. I know the RpiZero has been used for this, but this is the first time I've seen a write-up of an Arduino doing it. Coolness.
    – SDsolar
    Commented May 4, 2018 at 2:30

1 Answer 1

1

You should just not call the releaseKey function, until the button is released.

int oldVal1 = 0;
int oldVal2 = 0;

void loop() 
{
    val1 = digitalRead(inpin1);
    if( val1!=oldVal1 )
    {
        oldVal1 = val1;
        if(val1 != HIGH)
        {
            buf[2] = 80; // Left Arrow
            Serial.write(buf, 8);
        }
        else
        {
            releaseKey();
        }
    }

    val2 = digitalRead(inpin2);
    if( val2!=oldVal2 )
    {
        oldVal2 = val2;
        if(val2 != HIGH)
        {
            buf[2] = 79; // Right Arrow
            Serial.write(buf, 8);
        } 
        else 
        {
            releaseKey();
        }
    }

}
5
  • 1
    Right sort of idea, but I don't this is going to work since there are two buttons and releaseKey() doesn't seem like it will distinguish. So probably the un-pushed button will immediately undo the pushed one, preventing any improvement. I'm not sure if the problem can be solved with shared "had anything been pushed?" tracking or if the key states will need to be tracked and released independently. Commented Jan 9, 2017 at 23:17
  • Perhaps things might be simplified by writing the code so that if one button is pushed the other gets ignored, but the code will need to be sure to release any pushed button before it indicates the push of another. Commented Jan 9, 2017 at 23:18
  • Just asking, why not using "while-loop" instead?
    – duck
    Commented Jan 10, 2017 at 2:19
  • @ChrisStratton good point. Changed it so it only send press or release when the button state has changed. That doesn't handle pressing multiple buttons at the same time, but keeps it simple enough to understand.
    – Gerben
    Commented Jan 10, 2017 at 11:01
  • @dhimaspw A while loop would block any other code. So that will work for this simple sketch, but will cause issues if you ever want to add additional code. Like for example pressing multiple buttons at the same time.
    – Gerben
    Commented Jan 10, 2017 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.