Teensy LC keyboard sends wrong key

Snooker

Member
Hello,
I am trying to program some kind of pageturner with a Teensy LC with Arduino IDE 2.1.1
Code:
.
I use the digital ports 1, 2, 3, ..., 6. The following key codes should be sent to a Windows PC:
1 - KEY_LEFT
2 - KEY_RIGHT
3 - KEY_HOME
4 - KEY_END
5 - KEY_PAGE_UP
6 - KEY_PAGE_DOWN

The program runs, but on the PC (tested with an editor) not the desired keys arrive but only letters (1 - P, 2 - O, 3 - J, ...).

Where is my error?

Many greetings
Volker

Here is my code:
Code:
#include <Keyboard.h>
#include <ezButton.h>

/* Keys
  1	KEY_LEFT_ARROW
  2 KEY_RIGHT_ARROW
  3 KEY_HOME
  4 KEY_END
  5 KEY_PAGE_UP
  6 KEY_PAGE_DOWN
*/

const byte Foot1 = 1;
const byte Foot2 = 2;
const byte Foot3 = 3;
const byte Foot4 = 4;
const byte Foot5 = 5;
const byte Foot6 = 6;

const byte LEDbuildin = 13;

byte Foot1state = HIGH;
byte Foot2state = HIGH;
byte Foot3state = HIGH;
byte Foot4state = HIGH;
byte Foot5state = HIGH;
byte Foot6state = HIGH;

ezButton deb1(Foot1);
ezButton deb2(Foot2);
ezButton deb3(Foot3);
ezButton deb4(Foot4);
ezButton deb5(Foot5);
ezButton deb6(Foot6);

void setup() 
{
  pinMode(Foot1, INPUT_PULLUP);   // links Port 1
  deb1.setDebounceTime(25);

  pinMode(Foot2, INPUT_PULLUP);   // rechts Port 2
  deb2.setDebounceTime(25);

  pinMode(Foot3, INPUT_PULLUP);   // links Port 1
  deb3.setDebounceTime(25);

  pinMode(Foot4, INPUT_PULLUP);   // rechts Port 2
  deb4.setDebounceTime(25);

  pinMode(Foot5, INPUT_PULLUP);   // links Port 1
  deb5.setDebounceTime(25);

  pinMode(Foot6, INPUT_PULLUP);   // rechts Port 2
  deb6.setDebounceTime(25);

  pinMode(LEDbuildin, OUTPUT);    // LED Port 1
  digitalWrite(LEDbuildin, LOW);

  Serial.begin(9600);
  Keyboard.begin();
}

void loop() {
  deb1.loop();
  deb2.loop();
  deb3.loop();
  deb4.loop();
  deb5.loop();
  deb6.loop();

  int debo1 = deb1.getState();
  int debo2 = deb2.getState();
  int debo3 = deb3.getState();
  int debo4 = deb4.getState();
  int debo5 = deb5.getState();
  int debo6 = deb6.getState();

  if (debo1 == LOW && Foot1state == HIGH)
  {
    digitalWrite(LEDbuildin, HIGH);
    //delay(80);
    Foot1state = LOW;
    Keyboard.write(KEY_LEFT);
  }

  if (debo1 == HIGH && Foot1state == LOW)
  {
    digitalWrite(LEDbuildin, LOW);
    //delay(80);
    Foot1state = HIGH;
  }

  if (debo2 == LOW && Foot2state == HIGH)
  {
    digitalWrite(LEDbuildin, HIGH);
    //delay(80);
    Foot2state = LOW;
    Keyboard.write(KEY_RIGHT);
  }

  if (debo2 == HIGH && Foot2state == LOW)
  {
    digitalWrite(LEDbuildin, LOW);
    //delay(80);
    Foot2state = HIGH;
  }

  if (debo3 == LOW && Foot3state == HIGH)
  {
    digitalWrite(LEDbuildin, HIGH);
    //delay(80);
    Foot3state = LOW;
    Keyboard.write(KEY_HOME);
  }

  if (debo3 == HIGH && Foot3state == LOW)
  {
    digitalWrite(LEDbuildin, LOW);
    //delay(80);
    Foot3state = HIGH;
  }

  if (debo4 == LOW && Foot4state == HIGH)
  {
    digitalWrite(LEDbuildin, HIGH);
    //delay(80);
    Foot4state = LOW;
    Keyboard.write(KEY_END);
  }

  if (debo4 == HIGH && Foot4state == LOW)
  {
    digitalWrite(LEDbuildin, LOW);
    //delay(80);
    Foot4state = HIGH;
  }

  if (debo5 == LOW && Foot5state == HIGH)
  {
    digitalWrite(LEDbuildin, HIGH);
    //delay(80);
    Foot5state = LOW;
    Keyboard.write(KEY_PAGE_UP);
  }

  if (debo5 == HIGH && Foot5state == LOW)
  {
    digitalWrite(LEDbuildin, LOW);
    //delay(80);
    Foot5state = HIGH;
  }

  if (debo6 == LOW && Foot6state == HIGH)
  {
    digitalWrite(LEDbuildin, HIGH);
    //delay(80);
    Foot6state = LOW;
    Keyboard.write(KEY_PAGE_DOWN);
  }

  if (debo6 == HIGH && Foot6state == LOW)
  {
    digitalWrite(LEDbuildin, LOW);
    //delay(80);
    Foot6state = HIGH;
  }
}
 
Hello,
I have changed the program:
instead of
Code:
Keyboard.write(KEY_LEFT);
I now use the two commands
Code:
Keyboard.press(KEY_LEFT);
  Keyboard.releaseAll();
and everything works.

Why does Keyboard.write not work?

Greetings
 
The situation is complicated. Like most Arduino compatible classes, several inline functions are present to avoid C++ ambiguous overload errors.

Code:
        virtual size_t write(uint8_t c) { usb_keyboard_write(c); return 1; }
        size_t write(unsigned long n) { return write((uint8_t)n); }
        size_t write(long n) { return write((uint8_t)n); }
        size_t write(unsigned int n) { return write((uint8_t)n); }
        size_t write(int n) { return write((uint8_t)n); }

Arduino IDE 2.1.1 does indeed show info, but due to these inline functions and #define constants defaulting to "int" type, it finds the "size_t write(int n)".

screenshot.png

Maybe another IDE could see through the inline functions and show the actual function that will be called?

Indeed we are truncating to uint8_t. Maybe that's not the best behavior. But again the situation is complicated...

Keyboard class tries to support these types of input with Keyboard.press() and Keyboard.release().

ASCII (8 bits)
UTF8 (8 bits) - gcc generates this for strings with non-ascii characters
Key codes (16 bits)
Unicode (16 bits)
UTF8 packed into 16 bits - gcc generates this for non-ascii char constants

With Keyboard.write(), we try to support the uint8_t things, only ASCII and UTF8, because it's the traditional Arduino API which takes 8 bit data.

Maybe Keyboard.write() should also try to accept the 16 bit stuff? But then we get into another possibly confusing situation where the inline functions for "int" and "long" do something different than the 8 bit API. Perhaps that's ok? I'm not sure... maybe something to consider for future versions?

But hopefully this at least helps answer "Why does Keyboard.write not work".
 
Back
Top