May 24, 2018

USB HID – Teenyduino keyboard led feedback

(Last Updated On: 20th September 2016)

After doing a bit of Google-Fu I managed to work out how to read the state of the simulated keyboard LEDs for the Teensyduino.  It turns out you read a single value with the predefined variable keyboard_leds which when converted to binary shows the state of each LED in the least significant bits.  The what?  Let’s look.

We have a byte of data (00000000).  The bits that make the least difference to the value are the right hand side, so the least significant bit is the one furthest to the right.  An example of this is 0 (00000000) and 1 (00000001).  See how that right hand bit only increased our number by one?  An example of the most significant bit 0 (00000000) and 128 (10000000).  See how that 1 bit change made the number jump by 128!

Okay so the 5 least significant bits are set dependant if the LEDs are lit or not.  Going left to right, they are in the order KANA (for Japanese keyboards), COMPOSE, SCROLL, CAPS and NUM.  So we know that if only the CAPS lock is lit, then the 5 least significant bits will be 00010.  Still with me?  If not go back and read again.

The integer value for CAPS only (16 or 32 bit int as all those bits to left will be zero) will always be 2 because that’s just binary for you.  See guide here if you’re confused.  Unfortunately we can’t use this integer value to check if CAPS lock is on as if both CAPS lock and NUMS lock is on the bits would be …00011 which makes 3, not a 2!  So we need to check if that bit is a 1 or 0, not check the whole keyboard_leds variable value.  With me?  Good, we do this with a bitwise operator called AND.  The AND operator will work compare to bits and return a 1 if they are both set to 1.

Let see some examples (CAPS only and CAPS + NUM lock) to see how this works.

Compare CAPS with NUM
keyboard_leds variable set to …00010
known NUM LOCK state is     …00001
AND these together                   …00000 (which as an integer is equal to 0).

Compare CAPS with CAPS
keyboard_leds variable set to …00010
known CAPS LOCK state is     …00010
AND these together                   …00010 (which as an integer is equal to 2).

Compare CAPS and NUM with CAPS
keyboard_leds variable set to …00011
known CAPS LOCK state is     …00010
AND these together                   …00010 (which as an integer is equal to 2).

With these examples we can see that if the bit we are testing for isn’t set then we get a zero returned, otherwise we get an integer which isn’t a zero.  With Arduino code, a return code of 0 is FALSE and anything else is TRUE.  So with this in mind, we can now create an if statement to perform the exact comparison we did in the examples by using the cpp operator &.

The code below begins by defining each of the integer values for the individual LEDs so we can compare them later by name rather than integer.

void setup() {
#define USB_LED_NUM_LOCK 1
#define USB_LED_CAPS_LOCK 2
#define USB_LED_SCROLL_LOCK 4
#define USB_LED_COMPOSE 8
#define USB_LED_KANA 16
}
bool ledStatus(int ledCode)
{
if(keyboard_leds & ledCode)
{
return 1;
}
else
{
return 0;
}
}

void loop(){
if(ledStatus(USB_LED_NUM_LOCK)
{
// Num lock is on
}

if(!ledStatus(USB_LED_CAPS_LOCK)
{
// CAPS lock is off
}
}
Previous «
Next »

Simon is a sysadmin for Local Government in North Yorkshire with a real passion for security and coding.

Leave a Reply

Subscribe to SYNACK via Email

%d bloggers like this: