Teensy 2 Keyboard question

Status
Not open for further replies.

zeb

Member
I hope I'm posting this in the right section.

I'm trying to make a virtual pinball keyboard encoder from the teensy 2 and was wondering if there is any way to send the actual key press of the left and right SHIFT keys and the left and right CTRL keys as individual and recognizable key presses or are they only able to be used as modifiers?

I know I could work around it by reassigning the keys in the game software, but I was hoping to use the defaults as they seem to be the same defaults across the different platforms.

Go easy on me, coding is still 90% voodoo and 10% knowledge to me...:)

Thanks,
zeb
 
Opps, missed this one....

This is pretty simple stuff really, but you will need to use the more complex "micro manager way".

http://www.pjrc.com/teensy/td_keyboard.html

To press the left shift:

Code:
Keyboard.set_modifier(MODIFIERKEY_LEFT_SHIFT);
Keyboard.send_now();

To release it:

Code:
Keyboard.set_modifier(0);
Keyboard.send_now();
 
Paul, I'm not sure that is correct. There are separate Usage IDs for the modifier keys when used as standalone as keys in their own right. See HID Usage Tables v.1.12, chapter 10 "Keyboard/Keypad Page (0x07)", usage IDs E0 to E7 respectively.
 
Hmmm.... I've added this to my list of things to investigate.

Do you have any recommendation for a PC-side program that can show when those keys are pressed? Ideally, for Mac, Windows and Linux?
 
Great so it is possible, thanks guys.

The intended use is solely for pc based software, specifically visual pinball (pinmame) and future pinball. Cross platform functionality would definitely be an asset but not mandatory for this project.

I'll give the suggestion a shot and report back.
 
Do you have any recommendation for a PC-side program that can show when those keys are pressed? Ideally, for Mac, Windows and Linux?

For specific keys, it would vary (games, such as the pinball example mentioned by the original poster, may well treat left and right shift keys distinctly. A calculator that had hex, octal, and decimal modes might tie those to specific keyys. Some of the later ones seem specific to 'extended numeric pad' applications - perhaps spreadsheets support them? Usage ID 0x88 (Keyboard International2) is the standard "Input Mode Editor" key for Japanese.)

I came across this, have not tested it but the mention of tri-platform support sounded promising:
http://engineer-dan.tumblr.com/post/45749016127/keyboardstatus-multiplatform-n-key-rollover-test
linked from the also relevant
http://engineer-dan.tumblr.com/post/62541581084/keyboard-project-conclusion
 
Last edited:
Well after 2 days of reading I can safely say that I'm not lost but rather deep in the woods...:)

I get the gist of what you are suggesting, send the modifier key as basically a modifier with a null (), send it now (when pressed), and send a release (0) when the key is released.

I'm just not sure where and how I should implement this. Is this a case of "if" "else" or should this go in its own subroutine? Sorry if this question seems inane, but I've searched and searched and can't seem to find an example of code that isn't using the modifier as just that, a modifier.

I wrote a very quick and basic sketch last night of a loop with what you suggested in the above post in it. For what it's worth Paul, I can confirm that the above command does send a pulse for the Left_shift key only. I managed to get the left flipper to work twice before the computer locked up.

Using the keyboard test suggested by Nantonos, I see that the code for the left shift key from the teensy does match the entry from my usb keyboard.
 
Last edited:
Could you post your quick sketch? Its easier to discuss if we can see it rather than guessing.
When doing so, click the 'Go Advanced' and then the # icon which generates code tags for your sketch. That prevents the forum mangling the code, makes it easier to read too.
 
Using the keyboard test suggested by Nantonos, I see that the code for the left shift key from the teensy does match the entry from my usb keyboard.
In that case, it seems like the separate codes for 'shift not as a modifier' are not being used by your pinball software.
 
Code:
#include <Bounce.h>
 

Bounce button0 = Bounce(0, 10);


void setup()
{
  pinMode(0, INPUT_PULLUP);
}
 
void loop()
{
  button0.update();
 
  
   if (button0.fallingEdge())
  {
    Keyboard.set_modifier(MODIFIERKEY_LEFT_SHIFT);
    Keyboard.send_now();
  }
  delay(50);
  {
    Keyboard.set_modifier(0);
    Keyboard.send_now();
  }
  
}

I did some fiddling with it and got it to stop locking the computer so it works as I would expect it to. I push the button, the flipper jumps up and 50ms later drops down.

I guess what I'm asking is, if I micromanage these buttons (shift left, shift right, left ctrl, right ctrl) do I need to micromange all of the other button that just work?

BTW: the hex value being sent by the left shift key is 0x2A, the same value that is being sent by the left shift key on my actual keyboard.
 
Last edited:
This code looks like it will always sends the off message 20 times per second. Maybe the delay and off transmission was meant to be within the if { } block?
 
Yeah, this was just a test code I did up to see if I could even get a response like I needed (which I did).

I'm just asking if I need to independently manage all of my buttons when I use the modifier keys or if I can still loop the keys that work easily (1, 5, ESC, etc) in a for (i < 4) i++ type loop and then deal with each of the modifier buttons after that rotine in the main loop.
 
So I took the suggestions that you made and revised the code to this:

Code:
#include <Bounce.h>
 
Bounce button0 = Bounce(0, 10);


void setup()
{
  pinMode(0, INPUT_PULLUP);
 
}
 
void loop()
{
  
  
  button0.update();
    
   if (button0.fallingEdge())
  {
    Keyboard.set_modifier(MODIFIERKEY_LEFT_SHIFT);
   // Keyboard.send_now();
  }
  if (button0.risingEdge())
  {
    Keyboard.set_modifier(0);
    //Keyboard.send_now();
  }
  Keyboard.send_now();
 //delay(50);
}


and it works exactly as I want. Hopefully I can figure out how to duplicate it for the rest of the keys and integrate it somehow into the main code that I have to date.

edit*** I figured it out and now have what I think is a working code. I used the .press and .release commands and they seem to do what I want.

Thanks very much for your help.
 
Last edited:
Code:
 [...]
void loop()
{
    button0.update();
    if (button0.fallingEdge())
    {
        Keyboard.set_modifier(MODIFIERKEY_LEFT_SHIFT);
        // Keyboard.send_now();
    }
    
    if (button0.risingEdge())
    {
        Keyboard.set_modifier(0);
        //Keyboard.send_now();
    }
    
    Keyboard.send_now();
    //delay(50);
}
Maybe you've improved it, but the above sends updates to the host continuously (up to 500Hz) even when the button's state hasn't changed, unless send_now() detects the lack of any changes and optimizes out the USB update (I can't find Keyboard's source to confirm this). Usually you'd do as your commented-out send_now() calls do, only sending an update when you've changed something in the Keyboard.
 
I know that this thread is a bit old but I found a solution and it's working with visual pinball and steam pinball fx2. The code posted above was a great inspiration, thank you guys!

Here's my solution:

Code:
#include <Bounce.h>

Bounce button0 = Bounce(0, 10);
Bounce button1 = Bounce(1, 10);  // 10 ms debounce time is appropriate
Bounce button2 = Bounce(2, 10);  // for most mechanical pushbuttons

boolean to_send = false;
boolean l_shift = false;
boolean r_shift = false;
boolean enter = false;

int modifier;

void setup() {
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
}

void loop() {
  button0.update();
  button1.update();
  button2.update();

  if (button0.fallingEdge()) {
    l_shift = true;
    to_send = true;
  }
  if (button0.risingEdge()) {
    l_shift = false;
    to_send= true;
  }
  if (button1.fallingEdge()) {
    r_shift = true;
    to_send= true;
  }
  if (button1.risingEdge()) {
    r_shift = false;
    to_send= true;
  }
  if (button2.fallingEdge()) {
    enter = true;
    to_send= true;
  }
  if (button2.risingEdge()) {
    enter = false;
    to_send= true;
  }

  if (to_send) {
    to_send = false;

    modifier = 0;
    if (l_shift) modifier = MODIFIERKEY_LEFT_SHIFT;
    if (r_shift) modifier |= MODIFIERKEY_RIGHT_SHIFT;
    if (enter) {
      Keyboard.set_key1(KEY_ENTER);
    } 
    else { 
      Keyboard.set_key1(0);
    }
    Keyboard.set_modifier(modifier); 
    Keyboard.send_now();
  }
}
 
Last edited:
Status
Not open for further replies.
Back
Top