Keyboard function inconsistencies

Just when I thought I figured this keyboard stuff out, really strange inconsistencies in functionally from my test program to my other test program pop up and I'm figuring out allot of the problems that I was bringing up in an earlier thread were probably do to this.

This code works as expected

//testMacro
#include<avr/pgmspace.h>

prog_char super= KEY_LEFT_GUI;
prog_char supeRight= KEY_RIGHT_GUI;
prog_char lctrl= KEY_LEFT_CTRL;
prog_char rctrl= KEY_RIGHT_CTRL;
prog_char lshift= KEY_LEFT_SHIFT;
prog_char rshift= KEY_RIGHT_SHIFT;
prog_char lalt= KEY_LEFT_ALT;
prog_char ralt= KEY_RIGHT_ALT;
prog_char up=KEY_UP_ARROW;
prog_char down=KEY_DOWN_ARROW;
prog_char right=KEY_RIGHT_ARROW;
prog_char left=KEY_LEFT_ARROW;
prog_char HOME= KEY_HOME;
prog_char END= KEY_END;
prog_char f2= KEY_F2;
prog_char f4= KEY_F4;//close!
prog_char f5= KEY_F5;//reload!
prog_char f10= KEY_F10;
prog_char f12= KEY_F12;
prog_char tab= KEY_TAB;

void setup()
{
  delay(200);
  Keyboard.begin();
  delay(5000);
  combo(lalt, lshift);//change layout
  combo(lalt, f2);//run
  delay(200);
  Keyboard.println("mate-terminal");//terminal
  combo(lalt, lshift);//change layout back

}

void loop()
{
}

//---------------------------------Keyboard functions

void sKey(int presses, int key)
{
  for(int i=0;i<presses;i++)
  {
    Keyboard.write(key);
  }
}

void combo(byte key1, byte key2)
{
  Keyboard.press(key1);
  Keyboard.press(key2);
  delay(100);
  Keyboard.releaseAll();
}

void combo(byte key1, byte key2, byte key3)
{
  Keyboard.press(key1);
  Keyboard.press(key2);
  Keyboard.press(key3);
  delay(100);
  Keyboard.releaseAll();
}

And this code will print letters but the modifiers don't work even though the setup is basically the same, keep in mind, I'm focusing in on the combo() function in the setup. I've rerun this under different situations over and over thinking that this was some sort of a fluke or maybe had to do with multiple IDEs open or my system but no.

//usbResponse2
//using the arduino micro
#include<avr/pgmspace.h>
//-----------------------------------------------------------------define buttons
byte buttons[]={
  2,3,4,5};//first attempt is without interupts *probably not nessisarry
#define NUMBUTTONS sizeof(buttons)

#define LINESIZE 80//just needs to be under 255
//------set yes and no counters
boolean capflag;
int yesCount=0;
int noCount=0;
//word building
byte printCount=0;
int wordCount=0;;
int lastWordCount=0;
int sentenceCount=0;
int lastSentenceCount=0;
byte lastLetter=99;//99 for testing purposes

//-------------modifier
prog_char super= KEY_LEFT_GUI;
prog_char supeRight= KEY_RIGHT_GUI;
prog_char lctrl= KEY_LEFT_CTRL;
prog_char rctrl= KEY_RIGHT_CTRL;
prog_char lshift= KEY_LEFT_SHIFT;
prog_char rshift= KEY_RIGHT_SHIFT;
prog_char lalt= KEY_LEFT_ALT;
prog_char ralt= KEY_RIGHT_ALT;
prog_char up=KEY_UP_ARROW;
prog_char down=KEY_DOWN_ARROW;
prog_char right=KEY_RIGHT_ARROW;
prog_char left=KEY_LEFT_ARROW;
prog_char HOME= KEY_HOME;
prog_char END= KEY_END;
prog_char f2= KEY_F2;
prog_char f4= KEY_F4;//close!
prog_char f5= KEY_F5;//reload!
prog_char f10= KEY_F10;
prog_char f12= KEY_F12;
prog_char tab= KEY_TAB;

#define BACK 178
#define TAB 179

//substitutes
char compSug[]="suggestion ";

void setup()
{
  delay(200);
  Keyboard.begin();//to output assignment
  delay(5000);
  combo(lalt, lshift);
  combo(lalt, f2);
  delay(200);
  Keyboard.println("mate-terminal");//terminal
  delay(500);
  //------------input setting
  for (byte set=0;set<NUMBUTTONS;set++){//sets the button pins
    pinMode(buttons[set],INPUT);
    digitalWrite(buttons[set],HIGH);//this sets pull-up resistor/ie input through 20k to 5v
  }//in this way| input to button/button to ground, is proper and will read as low when pressed
}

//-----------------------------------------------------------------------------------------------------begin main loop
void loop()
{
  delay(200);
  if(printCount>=LINESIZE){
    Keyboard.println("-auto rtn");
    printCount=0;
  }
  for(byte i=0;i<NUMBUTTONS;i++){//Semantic issue multipul events per loop
    //(dButton[i].read()==LOW){// not really sure why the debounce isnt working
    if(digitalRead(buttons[i])==LOW){ 
      switch(i){
        //--------------------------a
      case 0:
        printLetter(97);
        break;
        //-------------------------c
      case 1:
        printLetter(99);
        break;
        //----------------------no case
      case 2:
        noCase();
        break;
        //-----------------------------yes case      
      case 3:
        yesCase();
        break;
      default:
        Keyboard.print("error");
        break;
      }
      break;//prevents multiple instences per loop 
    }
  }
}
//--------------------------------------------------------------------------------------------------------end main loop
//------------------------------------letter printing
void printLetter(int letterNum)
{
  if(sentenceCount==0||capflag==true){
    Keyboard.write(letterNum-32);
    lastLetter=letterNum-32;
    capflag=false;
  }
  else{
    Keyboard.write(letterNum);
    lastLetter=letterNum;
  }
  printCount++;
  wordCount++;
  sentenceCount++;
  yesCount=0;
  noCount=0;
}

//-------------------------------------------------------------------------NO CASE
void noCase()
{
  if(noCount==0)
  {
    //comp suggestion case, no after word complete || first word 
    if(yesCount==1 || sentenceCount==0)
    {
      byte addCount=sizeof(compSug);
      addCount--;//-1 to take care of null
      if(yesCount==1)
      {
        sKey(lastWordCount, BACK);
        lastLetter=compSug[addCount-2];//this is the last letter of the computer suggestion
        printCount-=lastWordCount;
        sentenceCount-=lastWordCount;
      }
      Keyboard.print(compSug);
      printCount+=addCount;
      sentenceCount+=addCount;
      lastWordCount=addCount;
      return;
    }
    if(yesCount==2)
    {
      sKey(2, 178);//backspace twice
      Keyboard.print("? ");
      noCount++;
      return;
    }
    //backspace, no count==0 general behaviour above are exceptions
    sKey(1, BACK);
    printCount--;
    wordCount--;
    sentenceCount--;
    //Pronoun case
    if(wordCount==1 && lastLetter>96)
    {
      capflag=true;
      printLetter(lastLetter);
      return;
    }
    noCount++;
    return;
  }
  //end noCount 0 cases---begin nocount 1, ie double back
  if(noCount==1)
  {
    if(yesCount==2)
    {
      sKey(2, BACK);
      Keyboard.print("! ");
      noCount++;
      return;
    }
    if(wordCount==0 || sentenceCount==0)
    {
      return;
    }
    //double back general behaviour above are exceptions/ delete word
    sKey(wordCount, BACK);
    printCount-=wordCount;
    sentenceCount-=wordCount;
    noCount++;
    return;
  }
}

//------------------------------------------------------------------------YES CASE
void yesCase()
{
  if(yesCount==0)
  {
    if(printCount==0)
    {
      sfill(4, ' ');//python indent
      return;
    }
    //default, make a word
    Keyboard.print(" ");
    printCount++;
    lastWordCount=wordCount+1;//accounts for space!!!
    wordCount=0;//time for a new word!!
    sentenceCount++;
    yesCount++;
    return;
  }
  if(yesCount==1)
  {
    if(printCount==1)
    {
      sfill(LINESIZE/2-4, ' ');
    }
    sKey(1,BACK);//remove space from last word
    lastWordCount++;
    Keyboard.print(". ");
    printCount++;// only goes up one because a space is removed
    lastSentenceCount=sentenceCount+1;
    sentenceCount=0;
    yesCount++;
    //noCount=0;
    return;
  }
}

//--------------------------------------------fill fuction

void sfill(byte spacing, char Char)
{
  for(int i=0;i<spacing;i++){
    Keyboard.print(Char);
    if(Char==' '){
      printCount++;
    }
  }
}
//---------------------------------Keyboard functions

void sKey(int presses, int key)
{
  for(int i=0;i<presses;i++)
  {
    Keyboard.write(key);
  }
}

void combo(byte key1, byte key2)
{
  Keyboard.write(key1);
  Keyboard.write(key2);
  delay(500);
  Keyboard.releaseAll();
}

void combo(byte key1, byte key2, byte key3)
{
  Keyboard.write(key1);
  Keyboard.write(key2);
  Keyboard.write(key3);
  delay(500);
  Keyboard.releaseAll();
}

notes on things I've tried
-works in the first program with or without the progmem stuff
-I swear combo took chars as arguments a couple of times but this may have been delusion, byte works and its what is supposed to work... even though its taking a char?...
-I restarted my system and the ide
-reset button on micro a few times the second sketch and one the times it changed my layout but it didn't bring up the run prompt

  • the tx lights fire at the right time, but nothing happens
  Keyboard.write(key1);

Try "press" not "write". It seems to do more.

From one of my working sketches:

 for (i = 0; i < 4; i++) 
    {
    Keyboard.press (KEY_DOWN_ARROW);
    Keyboard.releaseAll();
    }

That does 4 down arrows. You shouldn't need the delay.

Try "press" not "write". It seems to do more.

In the source write translates to press+release and It works in the specific applications where I'm using it.

You shouldn't need the delay.

I believe your right about this, however I wanted to make sure my computer had more then enough time to register the key binding

I would like to eliminate my computer's recognizing/communicating with the arduino as being a possible source of the issue. If anyone has a leonardo/micro if you could be as so kind as to test the two sketches I posted and report whether the issue (keyboard.press not working in the second) is true for yourself or not, I would be greatful

Just a note on the contents of the code
the second sketch uses buttons and a whole bunch of other jazz in the main loop, but I'm only really concerned about the functionality of the "combo" function in the setup, that makes keybindings like "alt-f2"
-your might need to put new key arguments in combo to suit an action you can see on your particular computer
-as long as its a binding with modifiers I'm thinking its still within the scope of pointing the finger at something odd with my setup and not the code or vise versa

I saw this in an example

Serial.begin(9600);
while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

is there an equivalent for keyboard initialization? maybe its not waiting long enough for the keyboard to be recognized?

In that case you hardly need the releaseAll here:

void combo(byte key1, byte key2)
{
  Keyboard.write(key1);
  Keyboard.write(key2);
  delay(500);
  Keyboard.releaseAll();
}

In fact, something like this won't behave as you intend, I expect:

combo(lalt, f2);

Since you acknowledge how write works you will get:

  • Press left-Alt. Release left-Alt.
  • Press F2. Release F2.

That isn't the same as pressing Alt+F2

:astonished: you know, I swear looked at this 4 or 5 times and didn't noticed that I hadn't changed the writes back to presses! (thought you where referring to the other function originally...)
Thank god I'm just an idiot and there is nothing wrong with my computer! :smiley:

sorry I wasted your time here Nick but you really helped me out. Sometimes I don't look before I leap.. maybe beneficial in other facets of life but not programming.

solved, short sighted programmer issue