HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Keyboard Printing with Teensy

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withkeyboardprintingteensy

Problem

I'm trying to write a piece of code that will mimic ASCII keyboard output. It uses the keyboard library from pjrc, but the application I'm working on requires outputting string sequences rather than individual keys (the C++ interface exposes Keyboard.print, which does exactly what I want, except that I'm trying to stick to C for learning purposes).

Here's a kick at it;

[snip]
#include 
#include "usb_keyboard.h" // definitions for the /KEY_\w+/ symbols

int key_from_char(char c){
  if (c >= 'a' && c = 'A' && c = '1' && c ': return KEY_PERIOD; break;
  case '?': return KEY_SLASH; break;
  case '@': return KEY_2; break;

  case '[': return KEY_LEFT_BRACE; break;
  case '\\': return KEY_BACKSLASH; break;
  case ']': return KEY_RIGHT_BRACE; break;
  case '^': return KEY_6; break;
  case '_': return KEY_MINUS; break;
  case '`': return KEY_TILDE; break;

  case '{': return KEY_LEFT_BRACE; break;
  case '|': return KEY_BACKSLASH; break;
  case '}': return KEY_RIGHT_BRACE; break;
  case '~': return KEY_TILDE; break;

  default: return 0;
  }
}

int modifier_from_char(char c){
  if ((c >= 'A' && c = '

It seems to work, when I do

int main(void) {
   ...
   usb_keyboard_print("abcdABCD1234!@#$%^&*()_+|~{}:\">?<-=\\`[];',./");
   ...
}


the character sequence

abcdABCD1234!@\$%^&*()_+|~{}:">?<-=\`[];',./


is output as if by keyboard.

All comments welcome, but I also have specific points/questions

  • It seems like there should be an easier way to do this. I mention above that the C++ version of the usb_keyboard library provides a Keyboard.print which does essentially the same thing, but I haven't found anything similar for plain C.



  • Are there any issues I'm missing about USB key codes that would

&& c = '>' && c = '{' && c <= '~')) return KEY_SHIFT; return 0; } int8_t usb_keyboard_print(char *s){ int s_len = strlen(s); int i; for(i = 0; i < s_len; i++){ usb_keyboard_press(key_from_char(s[i]), modifier_from_char(s[i])); } }


It seems to work, when I do

%%CODEBLOCK_1%%

the character sequence

%%CODEBLOCK_2%%

is output as if by keyboard.

All comments welcome, but I also have specific points/questions

  • It seems like there should be an easier way to do this. I mention above that the C++ version of the usb_keyboard library provides a Keyboard.print which does essentially the same thing, but I haven't found anything similar for plain C.



  • Are there any issues I'm missing about USB key codes that would

Solution

Don't subtract absolute values:

if (c >= 'a' && c <= 'z') return c - 93;


It makes it hard to understand what you are doing when you subtract integer literals from character codes. I would normally expect some form of value that conveys some meaning. For example lets assume ASCII (You probably want your keyboard thing but I don't know the appropriate macro).

if (c >= 'a' && c  96 

 if (c >= 'A' && c  65


Either you have some other requirement that is not ASCII (very possible), you want 'a'/'A' to map to some non zero number or you have a bug. But it is hard to tell with the way you have written your code as the literal values 93 and 61 have no real meaning.

Code Snippets

if (c >= 'a' && c <= 'z') return c - 93;
if (c >= 'a' && c <= 'z') return c + 3 - 'a';  // For some reason you want 'a' to map to 3
                                                // If we assume ASCII 'a' => 96 


 if (c >= 'A' && c <= 'Z') return c + 4 - 'A';  // For some reason you want 'A' to map to 4
                                                // If we assume ASCII 'A' => 65

Context

StackExchange Code Review Q#6796, answer score: 2

Revisions (0)

No revisions yet.