Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

USBhost: additional functions for keyboard appreciated #3630

Open
shiftleftplusone opened this issue Aug 5, 2015 · 6 comments
Open

USBhost: additional functions for keyboard appreciated #3630

shiftleftplusone opened this issue Aug 5, 2015 · 6 comments
Assignees
Labels
feature request A request to make an enhancement (not a bug fix) Library: Other Arduino libraries that don't have their own label

Comments

@shiftleftplusone
Copy link

for USBhost it would be fine to have additional functions to read the USB keyboard:
kbhit()
getch()
getche()
getchar()
gets()
scanf()

@ffissore ffissore added feature request A request to make an enhancement (not a bug fix) Library: Other Arduino libraries that don't have their own label labels Aug 5, 2015
@shiftleftplusone
Copy link
Author

FYI, I already tried this following, but it does not work:

/*
 USBkeyboard Controller Example
 // modified 05-July-2015

 Shows the output of a USB USBkeyboard connected to
 the Native USB port on an Arduino Due Board.

 created 8 Oct 2012
 by Cristian Maglie

 http://www.arduino.cc/en/Tutorial/USBkeyboardController

 This sample code is part of the public domain.
 */


// Require USBkeyboard control library
#include <Scheduler.h>;
#include <KeyboardController.h>
USBHost usb;                         // Initialize USB Controller
KeyboardController keyboard(usb);    // Attach USBkeyboard controller to USB


#define ENTER  40


//=====================================================================================

int  keyPressed() {
  int key =  keyboard.getKey();
  if(key) return 1;
  else return 0;
}   

int  keyReleased() { 
  int key =  keyboard.getKey();
  if(key) return 1;
  else return 0;
}

//=====================================================================================

int getche_() {
  static int16_t oemkey=0, modkey=0, currkey=0, lastkey=0; 

  currkey=-1;
  oemkey=keyboard.getOemKey();
  modkey=keyboard.getModifiers();
  if(oemkey==88) oemkey=40; // ENTER, ENTERnum

  // ESC   = 41
  // Enter = 40, 88
  // Space = 44
  // Tab   = 43
  // TabBack   = mod 2 + 43
  // Backspace = 42 
  // F1    = 58
  // F5    = 62
  // F9    = 66
  // F12   = 69
  // INS   = 73
  // HOME  = 74
  // PgUp  = 75
  // DEL   = 76
  // END   = 77
  // PgDn  = 78
  // RIGHT = 79
  // LEFT  = 80
  // DN    = 81
  // UP    = 82  

  if(oemkey==ENTER)     currkey='\n';    // ENTER
  else  if(oemkey==42)  currkey= 8;      // BACKSPACE
  else  if(oemkey==43)  currkey='\t';    // TAB
  else  if( oemkey==41) currkey=27;      // ESC key
  else  if((modkey==0)&&(oemkey== 50)) currkey='\\';   // BACKSLASH
  else  if((modkey==0)&&(oemkey==100)) currkey='\\';
  else  if((modkey==2)&&(oemkey==50))  currkey='|';    // PIPELINE
  else  if((modkey==2)&&(oemkey==100)) currkey='|';
  else  if((modkey==32)&&(oemkey==50)) currkey='|';
  else  if((modkey==32)&&(oemkey==100)) currkey='|';  

  else  if((oemkey>=58)&&(oemkey<=69)) {;} // Function key F1-F12
  else  if((oemkey>=73)&&(oemkey<=82)) {;} // CURS key INS-PgDn, RIGHT-UP  

  else  currkey=keyboard.getKey();                     // normal letter

  if(currkey>=32) Serial.write(currkey);
  while(!keyReleased());

  return currkey;


}

//=====================================================================================

char * gets_(char * USBstr) {
  static  int16_t  currkey=0, lastkey=0; 
  static  char     chbuf[3];
  char  * strptr = USBstr;

  currkey = getchar();

  if(currkey==8) {                         // BACKSPACE
      if(strlen(USBstr)>0)  USBstr[strlen(USBstr)-1]='\0';
      else strcpy(USBstr,"");
  }
  else { sprintf(chbuf, "%c", currkey); strcat(USBstr, chbuf); }  

  return strptr; 
}   

//=====================================================================================

void setup()
{
  Serial.begin(115200);
  Serial.println("Program started");
  Scheduler.startLoop(USBloop);
  delay(200);
}

//=====================================================================================

void loop() {
   char USBkey; 
   static int32_t i;

   if(keyPressed()) USBkey=getche_();   // failure: unlimited outputs last key repeatedly !!

   // if no  keypress: just proceed...
   Serial.println(i++);     // usb.Task blocks program execution at this moment intermediately 
                            // for many seconds (which is unconscionable in the main loop() )

   yield();

}   

//=====================================================================================

void USBloop()
{
  // Process USB tasks
  usb.Task();  // strangely seems to call keyPressed() and keyReleased() in background
               // but how and when ???
               // and why don't they return anything ???
               // why are they no methods of USB (USB.keyPressed(), USB.keyReleased()) ???
               // and why isn't usb.Task() implemented as a task of Scheduler ???
  delay(5);

}


//=====================================================================================
//=====================================================================================

@shiftleftplusone
Copy link
Author

currently I see no way for using the USB keyboard inside a custom function:

  • how to detect if the user has pressed a key on the keyboard or not
  • only in case a key has been hit, then to assign it to a variable, if not, just skip and proceed with the next command without delay

Both is not possible:

   if(keyPressed()) USBkey=getche_();   // failure: unlimited outputs last key repeatedly !!

   // if no  keypress: just proceed...
   Serial.println(i++);     // usb.Task blocks program execution at this moment intermediately 
                            // for many seconds (which is unconscionable in the main loop() )

and shockingly USB.task also hinders different additional Scheduler multitasking threads

@shiftleftplusone
Copy link
Author

the easiest way of course would be to have USB as stdin and then just read from stream by ANSI C stdio.h functions, just like it simply works on a RaspPi when a keyboard is attached to the USB port.

Anyway, currently the implementation of the USB.task is weird,
keyPressed and keyReleased don't return anything and it's totally osbscured how and when they do either or anything meaningful,
usb.Task has to be called repeatedly but then blocks program execution intermediately and repeatedly for many seconds (which is unconscionable in the main loop() but shockingly also hinders different additional Scheduler multitasking threads ).
All the USB keyboard functionality should have been implemented either by stdin and the ANSI C / GCC stdio.h functions
-- or, alternatively, as a workaround --
at least by a dedicated task of Scheduler, running independently and continuously, producing a ( byte / FILE * ) stream by itself from which one could read keyboard input by customized kbhit, getch, getche, getchar, gets, scanf functions.
The way it's implemented for the moment anyway is not only "experimental" as it's written but actually just unsatisfactory, useless and not providing a simple and basic stdio.h C syntax as one could have expected...

@shiftleftplusone
Copy link
Author

When can we expect an improvement in the Keyboard functions, like e.g.
kbhit()
getch()
getche()
getchar()
gets()
scanf()

?

@shiftleftplusone
Copy link
Author

bump!
when will there be an update for reasonable keyboard stdin C functionality?

@bbx10
Copy link

bbx10 commented Jan 6, 2016

@VogonJ @cmaglie

usb.Task has to be called repeatedly but then blocks program execution intermediately and repeatedly for many seconds

I submitted an issue and PR in the USBHost repo to remove the 5 second usb.Task() delay. This fix makes it much easier to add USB keyboard/mouse support to an existing project.

arduino-libraries/USBHost#2

There is another issue/PR to add control key support for the keyboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request A request to make an enhancement (not a bug fix) Library: Other Arduino libraries that don't have their own label
Projects
None yet
Development

No branches or pull requests

4 participants