Author Topic: Problem with DigiKeyboard on Linux  (Read 6373 times)

zuixro

  • Newbie
  • *
  • Posts: 3
Problem with DigiKeyboard on Linux
« on: February 11, 2013, 01:26:09 pm »
Hey, guys. I'm working on an infrared to USB Keyboard bridge. It looks for infrared remote signals from a Sony remote (or universal remote programmed to Sony codes), and send keystrokes based on the code received. I'm using the IR backpack.


It works great on my Windows box, but when I plug it into a Linux box (Mythbuntu 12.04), it either doesn't work at all, or only works for a few minutes. Most of the time, it doesn't even show up in "lsusb", and even when it does, it's no guarantee that it's going to work.


Here's my code:


Code: [Select]
#include <DigiKeyboard.h>


#define irPin 2  //IR Receiver Pin
#define led 1    //LED Pin


#define keyDelay 250  //Delay between key presses


byte powers[8] = {
  B10000000, B01000000, B00100000, B00010000, B00001000, B00000100, B00000010, B00000001};


void setup()
{
  pinMode(irPin,INPUT);  //Key Configs
  pinMode(led,OUTPUT);
  digitalWrite(led,LOW);


  DigiKeyboard.update();
}


void loop()
{
  DigiKeyboard.update();
  if(pulseIn(irPin,LOW)>2000){   //If we get a long start pulse (over 2000 uSeconds)
    byte code;         //Array to store the binary code
    for(int i;i<8;i++){          //Get input from the receiver
      if(pulseIn(irPin,LOW)>1000)//If it's over 1000 uS
        code += powers[i];
    }




    DigiKeyboard.update();
    pressKey(code);              //Take the code from the IR Receiver, and generate a keypress
    digitalWrite(led, LOW);
    delay(keyDelay);             //Delay before the next keypress to prevent doubles
  }
}


void pressKey(byte input){
  digitalWrite(led,HIGH);
  int key;                       //Variable to store the key code
  switch (input){
  case B01101100:  //Power Button
    DigiKeyboard.sendKeyStroke(KEY_ESC);  // Escape Key
    break;
  case B11000100:  //1
    DigiKeyboard.sendKeyStroke(KEY_1);  //1 Key
    break;
  case B01000100:  //2
    DigiKeyboard.sendKeyStroke(KEY_2);  //2 Key
    break;
  case B00000100:  //3
    DigiKeyboard.sendKeyStroke(KEY_3);  //3 Key
    break;
  case B10000100:  //4
    DigiKeyboard.sendKeyStroke(KEY_4);  //4 Key
    break;
  case B11100100:  //5
    DigiKeyboard.sendKeyStroke(KEY_5);  //5 Key
    break;
  case B01100100:  //6
    DigiKeyboard.sendKeyStroke(KEY_6);  //6 Key
    break;
  case B00100100:  //7
    DigiKeyboard.sendKeyStroke(KEY_7);  //7 Key
    break;
  case B10100100:  //8
    DigiKeyboard.sendKeyStroke(KEY_8);  //8 Key
    break;
  case B11010100:  //9
    DigiKeyboard.sendKeyStroke(KEY_9);  //9 Key
    break;
  case B01010100:  //0
    DigiKeyboard.sendKeyStroke(KEY_0);  //0 Key
    break;
  case B10011110:  //PIP Key
    //DigiKeyboard.sendKeyStroke(0);  // No Key
    break;
  case B10010100:  //Ent Key
    DigiKeyboard.sendKeyStroke(KEY_ENTER);  //Enter Key
    break;
  case B00001100:  //Vol+ Key
    DigiKeyboard.sendKeyStroke(KEY_RBRACE);  // ] Key (Right Brace)
    break;
  case B10001100:  //Vol- Key
    DigiKeyboard.sendKeyStroke(KEY_LBRACE);  // [ Key (Left Brace)
    break;
  case B11001100:  //Ch+ Key
    DigiKeyboard.sendKeyStroke(KEY_PAGEUP);  // Up Key
    break;
  case B01001100:  //Ch- Key
    DigiKeyboard.sendKeyStroke(KEY_PAGEDOWN);  // Down Key
    break;
  case B01101000:  //TV/Vid Key
    //DigiKeyboard.sendKeyStroke(0);  //No Key
    break;
  case B00100000:  //Display Key
    DigiKeyboard.sendKeyStroke(KEY_I);  // I Key
    break;
  case B00110000:  //Sleep Key
    //DigiKeyboard.sendKeyStroke(0);  // No Key
    break;
  case B11101100:  //Mute Key
    DigiKeyboard.sendKeyStroke(KEY_BACKSLASH);  // No Key
    break;
  case B10100000:  //Recall Key
    //DigiKeyboard.sendKeyStroke(0);  // No Key
    break;
  case B11110010:  //Up Key
    DigiKeyboard.sendKeyStroke(KEY_ARROW_UP);  // Up Key
    break;
  case B01110010:  //Down Key
    DigiKeyboard.sendKeyStroke(KEY_ARROW_DOWN);  // Down Key
    break;
  case B11110000:  //Left Key
    DigiKeyboard.sendKeyStroke(KEY_ARROW_LEFT);  // Left Key
    break;
  case B10010000:  //Right Key
    DigiKeyboard.sendKeyStroke(KEY_ARROW_RIGHT);  // Right Key
    break;
  case B11001010:  //Menu Key
    DigiKeyboard.sendKeyStroke(KEY_M);  // M Key
    break;
  case B00111001:  //Guide Key
    DigiKeyboard.sendKeyStroke(KEY_S);  // S Key
    break;
  case B01101010:  //OK Key
    DigiKeyboard.sendKeyStroke(KEY_ENTER);  // ENTER Key
    break;
  case B01011110:  //Rew Key
    DigiKeyboard.sendKeyStroke(KEY_COMMA);  // Comma Key
    break;
  case B10111110:  //Play Key
    DigiKeyboard.sendKeyStroke(KEY_P);  // P Key
    break;
  case B11011110:  //FF Key
    DigiKeyboard.sendKeyStroke(KEY_PERIOD);  // Period Key
    break;
  case B00011110:  //Rec Key
    DigiKeyboard.sendKeyStroke(KEY_R);  // R Key
    break;
  case B00111110:  //Stop Key
    DigiKeyboard.sendKeyStroke(KEY_ESC);  // Escape Key
    break;
  case B11111110:  //Pause Key
    DigiKeyboard.sendKeyStroke(KEY_P);  // P Key
    break;


  }
}


And I had to add a few extra key definitions to libraries/DigisparkKeyboard/DigiKeyboard.h


Code: [Select]
/* Keyboard usage values, see usb.org's HID-usage-tables document, chapter
 * 10 Keyboard/Keypad Page for more codes.
 */
#define MOD_CONTROL_LEFT    (1<<0)
#define MOD_SHIFT_LEFT      (1<<1)
#define MOD_ALT_LEFT        (1<<2)
#define MOD_GUI_LEFT        (1<<3)
#define MOD_CONTROL_RIGHT   (1<<4)
#define MOD_SHIFT_RIGHT     (1<<5)
#define MOD_ALT_RIGHT       (1<<6)
#define MOD_GUI_RIGHT       (1<<7)


#define KEY_A       4
#define KEY_B       5
#define KEY_C       6
#define KEY_D       7
#define KEY_E       8
#define KEY_F       9
#define KEY_G       10
#define KEY_H       11
#define KEY_I       12
#define KEY_J       13
#define KEY_K       14
#define KEY_L       15
#define KEY_M       16
#define KEY_N       17
#define KEY_O       18
#define KEY_P       19
#define KEY_Q       20
#define KEY_R       21
#define KEY_S       22
#define KEY_T       23
#define KEY_U       24
#define KEY_V       25
#define KEY_W       26
#define KEY_X       27
#define KEY_Y       28
#define KEY_Z       29
#define KEY_1       30
#define KEY_2       31
#define KEY_3       32
#define KEY_4       33
#define KEY_5       34
#define KEY_6       35
#define KEY_7       36
#define KEY_8       37
#define KEY_9       38
#define KEY_0       39


#define KEY_LBRACE   47
#define KEY_RBRACE   48
#define KEY_ESC      41
#define KEY_BACKSLASH   49
#define KEY_PERIOD   55
#define KEY_COMMA   54


#define KEY_ENTER   40


#define KEY_SPACE   44


#define KEY_F1      58
#define KEY_F2      59
#define KEY_F3      60
#define KEY_F4      61
#define KEY_F5      62
#define KEY_F6      63
#define KEY_F7      64
#define KEY_F8      65
#define KEY_F9      66
#define KEY_F10     67
#define KEY_F11     68
#define KEY_F12     69


#define KEY_ARROW_RIGHT 0x4F
#define KEY_ARROW_LEFT 0x50
#define KEY_ARROW_DOWN 0x51
#define KEY_ARROW_UP 0x52


#define KEY_PAGEDOWN   78
#define KEY_PAGEUP   75


These are the default keybindings for MythTV, but it would be trivial to modify it to XBMC.


Does anyone have an experience with that library on Linux? I've tried everything I can think of to try to get it to work.


EDIT: Wouldn't you know it. Immediately after posting this, I plugged it back into the Linux box, and it immediately started working. This time lsusb defines it as "Bus 005 Device 123: ID 16c0:27db VOTI Keyboard" whereas previous times it showed up as "Bus 005 Device 091: ID 16d0:0753 GrauTec" I don't know if that has something to do with it, but it seems to be working now. No telling how consistent it will be. Still seems like there is a bug or something.
« Last Edit: February 11, 2013, 01:35:50 pm by zuixro »

zuixro

  • Newbie
  • *
  • Posts: 3
Re: Problem with DigiKeyboard on Linux
« Reply #1 on: February 12, 2013, 11:17:18 am »
It's now working for about 5 minutes or so at a time on my Linux box.


I've used the onboard LED (in place of the missing Serial port...) and deduced that the problem is in the sendKeyStroke function. The LED should turn on when it starts the pressKey function (takes the code from the remote, and calls sendKeystroke to send the correct key stroke for the button pressed) and the turn off after the function is over. The LED is staying on, which mean something is hanging in the sendKeyStroke function. Is anyone familiar with the DigiKeyboard or V-USB enough to help me find the problem?


PS: Ignore the comments in the original code. I reworked it and optimized it after I had done all the comments, and I haven't had time to go back and fix them.

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: Problem with DigiKeyboard on Linux
« Reply #2 on: February 12, 2013, 01:02:38 pm »
I ran into this on an older Intel Atom machine and solved it by sending DigiKeyboard.sendKeyStroke(0); before each keystroke - if you haven't yet you might want to give that a try.

zuixro

  • Newbie
  • *
  • Posts: 3
Re: Problem with DigiKeyboard on Linux
« Reply #3 on: February 13, 2013, 05:30:23 am »
Sending DigiKeyboard.sendKeyStroke(0) before each keystroke didn't work, but sending it periodically (right now every time the loop runs) did. It's been plugged in for 30 minutes and still running.
« Last Edit: February 13, 2013, 05:34:48 am by zuixro »