Go Down

Topic: Update still won't work: Keyboard Library presses keys at different rates? (Read 297 times) previous topic - next topic

tvdp

Hello all, I started learning Arduino in January and caught the bug! So I made a wearable USB video game controller using the Sparkfun Pro Micro (uses Arduino Micro) with the Arduino keyboard library. The thing works really well right now, with a slide potentiometer set up to the left and right arrow keys, a flex sensor to the 'action' button, and a photocell to jump.
There's one problem: for some reason the right arrow key pushes much slower. When playing Limbo, the boy moves right, but at such a slow clip that the game barely works. In nidhogg, the guy moves right but in a weird slide animation at half speed. And for Super Meat Boy......I don't want to talk about it.
Here is the code:
Code: [Select]
include <Keyboard.h>

void setup() {
Serial.begin(9600);
Keyboard.begin(); // }

void loop() {
//here is the slide pot
int sliderValue = analogRead(A3);
 if (sliderValue > 750) {
Keyboard.release(KEY_LEFT_ARROW);
Keyboard.press(KEY_RIGHT_ARROW);
}
if (sliderValue < 230) {
Keyboard.release(KEY_RIGHT_ARROW);
Keyboard.press(KEY_LEFT_ARROW);
}
 else {
Keyboard.release(KEY_LEFT_ARROW);
Keyboard.release(KEY_RIGHT_ARROW);
 }

//here is the force sensitive resistor
 int forcevalue = analogRead(A0);
 if (forcevalue < 230) {
Keyboard.press(KEY_UP_ARROW);
}
else {
Keyboard.release(KEY_UP_ARROW);
}

//here is the photoresistor int lightvalue = analogRead(A1);
if (lightvalue < 240) {
Keyboard.press(KEY_LEFT_ALT);
}
else {
 Keyboard.release(KEY_LEFT_ALT);
}
//print the values for troubleshooting
 Serial.println(String("slider ")+sliderValue+" fsr " + forcevalue + " photocell " + lightvalue);
delay(20);
}


In the serial monitor, it's clear that the problem isn't with the slide potentiometer. Like, when the potentiometer is in the correct place to go 'right', it stays in that place. I tried using different USB cords, but that has made no difference. I reset my Mac's USB thing (I don't remember what it's called),,,,that's done nothing either. I also tried switching out Keyboard.press for Keyboard.write in the code, which changed nothing. I have no clue what to do!
I'll post a tutorial once I fix this glitch! It's really cool right now, as a refurbished varsity jacket equipped with these sensors integrated onto the sleeve. It's meant to make gaming a social and physical experience, and from playtesting, it does just that! And I want more people to make their own.
My computer is a Mac with the current OS (10.11.6).

Thanks in advance to anybody who helps or even just reads the whole dang thing!

pert

I'm not even going to try to read that code. Put each statement of your code on a separate line, then come back and post it again on this thread.

Please use code tags (</> button on the toolbar) when you post code or warning/error messages. The reason is that the forum software can interpret parts of your code as markup, leading to confusion, wasted time, and a reduced chance for you to get help with your problem. This will also make it easier to read your code and to copy it to the IDE or editor. Using code tags and other important information is explained in the How to use this forum post. Please read it.

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read.

tvdp

Code: [Select]
void setup() { Serial.begin(9600); Keyboard.begin(); // }
void loop() {
//here is the slide pot
int sliderValue = analogRead(A3);
if (sliderValue > 750) {
 Keyboard.release(KEY_LEFT_ARROW);
Keyboard.press(KEY_RIGHT_ARROW);
}
if (sliderValue < 230) {
Keyboard.release(KEY_RIGHT_ARROW);
Keyboard.press(KEY_LEFT_ARROW);
}
 else {
 Keyboard.release(KEY_LEFT_ARROW);
 Keyboard.release(KEY_RIGHT_ARROW);
}

//here is the force sensitive resistor
 int forcevalue = analogRead(A0);
if (forcevalue < 230) {
Keyboard.press(KEY_UP_ARROW);
}
 else {
Keyboard.release(KEY_UP_ARROW);
 }

//here is the photoresistor
int lightvalue = analogRead(A1);
if (lightvalue < 240) {
Keyboard.press(KEY_LEFT_ALT);
 }
else {
Keyboard.release(KEY_LEFT_ALT);
}

//print the values for troubleshooting
 Serial.println(String("slider ")+sliderValue+" fsr " + forcevalue + " photocell " + lightvalue);
delay(20);
 }

tvdp

I'm not even going to try to read that code. Put each statement of your code on a separate line, then come back and post it again on this thread.

Please use code tags (</> button on the toolbar) when you post code or warning/error messages. The reason is that the forum software can interpret parts of your code as markup, leading to confusion, wasted time, and a reduced chance for you to get help with your problem. This will also make it easier to read your code and to copy it to the IDE or editor. Using code tags and other important information is explained in the How to use this forum post. Please read it.

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read.
I fixed it! And yes, I did try auto format, forgot to mention that in my initial post.

pert

You still left your whole setup() mashed onto one line. There's just no point in doing something like that, especially when you're a beginner.

You forgot to Auto Format. It only takes a second and it makes the code so much easier to read.

Try changing:
Code: [Select]
if (sliderValue < 230) {
to:
Code: [Select]
else if (sliderValue < 230) {

Here's the problem, I think your intention is that if sliderValue is greater than 750 the right arrow should be held down, if sliderValue is less than 230 the left arrow should be held down, and if sliderValue is between 230 and 750 no arrow keys should be held down. However, what your code actually does if sliderValue is greater than 750 is it holds the right arrow down for a few microseconds, then checks if sliderValue is less than 230, finds it is not, so it executes the contents of the else:
Code: [Select]
Keyboard.release(KEY_LEFT_ARROW);
 Keyboard.release(KEY_RIGHT_ARROW);

which immediately releases the right arrow key. So this causes the right arrow key to be pressed and released so fast that it isn't even registered by the computer most of the time since it's expecting a human to be pressing the key and humans can't press keys down for only a few microseconds. By changing the second if to else if you are ensuring that the right arrow key is held down continuously the whole time sliderValue is greater than 750.

Please take the time to read:
https://www.arduino.cc/en/Reference/Else

tvdp

You still left your whole setup() mashed onto one line. There's just no point in doing something like that, especially when you're a beginner.

You forgot to Auto Format. It only takes a second and it makes the code so much easier to read.

Try changing:
Code: [Select]
if (sliderValue < 230) {
to:
Code: [Select]
else if (sliderValue < 230) {

Here's the problem, I think your intention is that if sliderValue is greater than 750 the right arrow should be held down, if sliderValue is less than 230 the left arrow should be held down, and if sliderValue is between 230 and 750 no arrow keys should be held down. However, what your code actually does if sliderValue is greater than 750 is it holds the right arrow down for a few microseconds, then checks if sliderValue is less than 230, finds it is not, so it executes the contents of the else:
Code: [Select]
Keyboard.release(KEY_LEFT_ARROW);
 Keyboard.release(KEY_RIGHT_ARROW);

which immediately releases the right arrow key. So this causes the right arrow key to be pressed and released so fast that it isn't even registered by the computer most of the time since it's expecting a human to be pressing the key and humans can't press keys down for only a few microseconds. By changing the second if to else if you are ensuring that the right arrow key is held down continuously the whole time sliderValue is greater than 750.

Please take the time to read:
https://www.arduino.cc/en/Reference/Else
I appreciate it.

My code is clean in the console I promise! It just looks weird in the forum because it jumbles when I copy/paste it. Either way I'll be sure to make it clean next time I post here.

I will switch to the else if statement! It feels pretty obvious now and I feel a bit silly haha. What a difference one word makes. Well, I'll test it again next time I'm in the lab, and thanks for your help!

tvdp

Update:
I did the changes and the key problem remains !

Here is the updated code:

Code: [Select]
#include <Keyboard.h>

void setup() {
  Serial.begin(9600);
  Keyboard.begin();
  //
}

void loop() {

  //here is the slide pot
  int sliderValue = analogRead(A3);
  if (sliderValue > 750) {
    Keyboard.release(KEY_LEFT_ARROW);
    Keyboard.write(KEY_RIGHT_ARROW);

  } else if (sliderValue < 230) {
    Keyboard.release(KEY_RIGHT_ARROW);
    Keyboard.press(KEY_LEFT_ARROW);
  } else {
    Keyboard.release(KEY_LEFT_ARROW);
    Keyboard.release(KEY_RIGHT_ARROW);
  }

  //here is the force sensitive resistor
  int forcevalue = analogRead(A0);
  if (forcevalue < 230) {
    Keyboard.press(KEY_UP_ARROW);
  }
  else {
    Keyboard.release(KEY_UP_ARROW);
  }

  //here is the photoresistor
  int lightvalue = analogRead(A1);
  if (lightvalue < 240) {
    Keyboard.press(KEY_LEFT_ALT);
  }
  else {
    Keyboard.release(KEY_LEFT_ALT);
  }

  //print the values for troubleshooting
  Serial.println(String("slider ") + sliderValue + "  fsr " + forcevalue + "  photocell " + lightvalue);
  delay(100);
}


SliderValue is where the problem is. I successfully uploaded the code to the board several times, so that is not the problem

pert

Does the left arrow work correctly?

Are you seeing the expected readings in the Serial Monitor?

Go Up