Multimedia HID Keyboard Arduino Mega 2560

Hi,

I'm trying to build a keyboard for my android tablet.

I fallowed the guide here

and use this hex .
http://hunt.net.nz/users/darran/weblog/b3029/Arduino_UNO_Keyboard_HID_version_03.html

The only buttons that are working are VOL_UP, VOL_DOWN, MUTE and HOME. I don't know where I'm wrong because I use the android official page to get the HID hex key. The next_song and the page 0x0c HID consumer page are not working.

Any suggestions?
Thanks

This is my ino file:

#define KEY_LEFT_ALT 0x04
uint8_t buf[8] = { 0 };

#define MAPS 1
#define TEL 2
#define MUSIC 3
#define VOL_UP 4
#define VOL_DOWN 5
#define MUTE 6
#define FRW 7
#define BCW 8
#define REAR 9
#define HOME 10

int state = 1;

void setup()
{
  Serial.begin(9600);

  pinMode(MAPS, INPUT);
  pinMode(TEL, INPUT);
  pinMode(MUSIC, INPUT);
  pinMode(VOL_UP, INPUT);
  pinMode(VOL_DOWN, INPUT);
  pinMode(MUTE, INPUT);
  pinMode(FRW, INPUT);
  pinMode(BCW, INPUT);
  pinMode(REAR, INPUT);
  pinMode(HOME, INPUT);

  digitalWrite(MAPS, 1);
  digitalWrite(TEL, 1);
  digitalWrite(MUSIC, 1);
  digitalWrite(VOL_UP, 1);
  digitalWrite(VOL_DOWN, 1);
  digitalWrite(MUTE, 1);
  digitalWrite(FRW, 1);
  digitalWrite(BCW, 1);
  digitalWrite(REAR, 1);
  digitalWrite(HOME, 1);

  delay(200);
}

void loop()
{
  //open Google maps
  state = digitalRead(MAPS);
  if (state != 1) {
    buf[2] = 0x0004;   
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //open Phone
  state = digitalRead(TEL);
  if (state != 1) {
    buf[1] = 0x0c;     //HID page
    buf[2] = 0x008c;  //HID key
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //open Play Music
  state = digitalRead(MUSIC);
  if (state != 1) {
    buf[1] = 0x0c;     //HID page
    buf[2] = 0x0183;  
    Serial.write(buf, 8); 
    releaseKey();
    delay(300);
  }

  //volume up
  state = digitalRead(VOL_UP);
  if (state != 1) {
    buf[1] = 0x07;     //HID page
    buf[2] = 0x0080;  
    Serial.write(buf, 8); 
    releaseKey();
    delay(300);
  }

  //volume down
  state = digitalRead(VOL_DOWN);
  if (state != 1) {
    buf[1] = 0x07;     //HID page
    buf[2] = 0x0081;
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //MUTE KEY
  if (digitalRead(VOL_UP) == 0 && digitalRead(VOL_DOWN) == 0) {
    buf[1] = 0x07;     //HID page
    buf[2] = 0x007f;   // Mute key
    Serial.write(buf, 8); // Send keypress
    releaseKey();
    delay(300);
  }

  //next song
  state = digitalRead(FRW);
  if (state != 1) {
    buf[1] = 0x07;     //HID page
    buf[2] = 0x00eb;   
    Serial.write(buf, 8); 
    releaseKey();
    delay(300);
  }

  //previous song
  state = digitalRead(BCW);
  if (state != 1) {
    buf[1] = 0x07;     //HID page
    buf[2] = 0x00ea;   
    Serial.write(buf, 8); 
    releaseKey();
    delay(300);
  }

  //open Camera app
  state = digitalRead(REAR);
  if (state != 1) {
    buf[1] = 0x07;     //HID page
    buf[2] = 0x00fa;
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //go HOME
  state = digitalRead(HOME);
  if (state != 1) {
    buf[0] = KEY_LEFT_ALT;
    buf[1] = 0x07;     //HID page
    buf[2] = 0x0029;
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

}

void releaseKey()
{
  buf[0] = 0;
  buf[1] = 0;
  buf[2] = 0;
  Serial.write(buf, 8);
}
#define MAPS 1
  Serial.begin(9600);
  pinMode(MAPS, INPUT);

You can't use Pin 1 for both Serial and digital input.

uint8_t buf[8] = { 0 };
    buf[2] = 0x0183;

You can't store a 9-bit value in an 8-bit value.

   buf[1] = 0x07;     //HID page

The documentation (http://hunt.net.nz/users/darran/weblog/faf5e/Arduino_UNO_Keyboard_HID_part_2.html) says that byte 1 is NOT USED.

You should only be using Keyboard/Keypad codes as shown in the USB spec:
http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (See section 10 starting on page 53)

Why can't I use the consumer page keys?? If they are there there must be a way to get them work, right? Thanks for you corrections. I'm a newbie.

#define KEY_LEFT_ALT 0x04
uint8_t buf[8] = { 0 };

#define MAPS 2
#define TEL 3
#define MUSIC 4
#define VOL_UP 5
#define VOL_DOWN 6
#define MUTE 7
#define FRW 8
#define BCW 9
#define REAR 10
#define HOME 11

int state = 1;

void setup()
{
  Serial.begin(9600);

  pinMode(MAPS, INPUT);
  pinMode(TEL, INPUT);
  pinMode(MUSIC, INPUT);
  pinMode(VOL_UP, INPUT);
  pinMode(VOL_DOWN, INPUT);
  pinMode(MUTE, INPUT);
  pinMode(FRW, INPUT);
  pinMode(BCW, INPUT);
  pinMode(REAR, INPUT);
  pinMode(HOME, INPUT);

  digitalWrite(MAPS, 1);
  digitalWrite(TEL, 1);
  digitalWrite(MUSIC, 1);
  digitalWrite(VOL_UP, 1);
  digitalWrite(VOL_DOWN, 1);
  digitalWrite(MUTE, 1);
  digitalWrite(FRW, 1);
  digitalWrite(BCW, 1);
  digitalWrite(REAR, 1);
  digitalWrite(HOME, 1);

  delay(200);
}

void loop()
{
  //open Google maps
  state = digitalRead(MAPS);
  if (state != 1) {
    buf[3] = 0x0004;   
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //open Phone
  state = digitalRead(TEL);
  if (state != 1) {
    buf[2] = 0x0c;     //HID page
    buf[3] = 0x008c;  //HID key
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //open Play Music
  state = digitalRead(MUSIC);
  if (state != 1) {
    buf[2] = 0x0c;     //HID page
    buf[3] = 0x01b7;  
    Serial.write(buf, 9); 
    releaseKey();
    delay(300);
  }

  //volume up
  state = digitalRead(VOL_UP);
  if (state != 1) {
    buf[2] = 0x07;     //HID page
    buf[3] = 0x0080;  
    Serial.write(buf, 8); 
    releaseKey();
    delay(300);
  }

  //volume down
  state = digitalRead(VOL_DOWN);
  if (state != 1) {
    buf[2] = 0x07;     //HID page
    buf[3] = 0x0081;
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //MUTE KEY
  if (digitalRead(VOL_UP) == 0 && digitalRead(VOL_DOWN) == 0) {
    buf[2] = 0x07;     //HID page
    buf[3] = 0x007f;   // Mute key
    Serial.write(buf, 8); // Send keypress
    releaseKey();
    delay(300);
  }

  //next song
  state = digitalRead(FRW);
  if (state != 1) {
    buf[2] = 0x07;     //HID page
    buf[3] = 0x00eb;   
    Serial.write(buf, 8); 
    releaseKey();
    delay(300);
  }

  //previous song
  state = digitalRead(BCW);
  if (state != 1) {
    buf[2] = 0x07;     //HID page
    buf[3] = 0x00ea;   
    Serial.write(buf, 8); 
    releaseKey();
    delay(300);
  }

  //open Camera app
  state = digitalRead(REAR);
  if (state != 1) {
    buf[2] = 0x07;     //HID page
    buf[3] = 0x00fa;
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

  //go HOME
  state = digitalRead(HOME);
  if (state != 1) {
    buf[0] = KEY_LEFT_ALT;
    buf[2] = 0x0029;
    Serial.write(buf, 8);
    releaseKey();
    delay(300);
  }

}

void releaseKey()
{
  buf[0] = 0;
  buf[1] = 0;
  buf[2] = 0;
  Serial.write(buf, 8);
}

johnwasser:

   buf[1] = 0x07;     //HID page

The documentation (http://hunt.net.nz/users/darran/weblog/faf5e/Arduino_UNO_Keyboard_HID_part_2.html) says that byte 1 is NOT USED.

You should only be using Keyboard/Keypad codes as shown in the USB spec:
http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (See section 10 starting on page 53)

lung11:
Why can't I use the consumer page keys??

Probably because "Usage Page (Keyboard)" is built into the report descriptor. See Descriptors.c in the sources. I don't know nearly enough about USB to want to tackle adding a consumer HID device.

USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
{
	0x05, 0x01,          /* Usage Page (Generic Desktop)                    */
	0x09, 0x06,          /* Usage (Keyboard)                                */
	0xa1, 0x01,          /* Collection (Application)                        */
	0x75, 0x01,          /*   Report Size (1)                               */
	0x95, 0x08,          /*   Report Count (8)                              */
	0x05, 0x07,          /*   Usage Page (Key Codes)                        */
	0x19, 0xe0,          /*   Usage Minimum (Keyboard LeftControl)          */
	0x29, 0xe7,          /*   Usage Maximum (Keyboard Right GUI)            */
	0x15, 0x00,          /*   Logical Minimum (0)                           */
	0x25, 0x01,          /*   Logical Maximum (1)                           */
	0x81, 0x02,          /*   Input (Data, Variable, Absolute)              */
	0x95, 0x01,          /*   Report Count (1)                              */
	0x75, 0x08,          /*   Report Size (8)                               */
	0x81, 0x03,          /*   Input (Const, Variable, Absolute)             */
	0x95, 0x05,          /*   Report Count (5)                              */
	0x75, 0x01,          /*   Report Size (1)                               */
	0x05, 0x08,          /*   Usage Page (LEDs)                             */
	0x19, 0x01,          /*   Usage Minimum (Num Lock)                      */
	0x29, 0x05,          /*   Usage Maximum (Kana)                          */
	0x91, 0x02,          /*   Output (Data, Variable, Absolute)             */
	0x95, 0x01,          /*   Report Count (1)                              */
	0x75, 0x03,          /*   Report Size (3)                               */
	0x91, 0x03,          /*   Output (Const, Variable, Absolute)            */
	0x95, 0x06,          /*   Report Count (6)                              */
	0x75, 0x08,          /*   Report Size (8)                               */
	0x15, 0x00,          /*   Logical Minimum (0)                           */
	0x25, 0x65,          /*   Logical Maximum (101)                         */
	0x05, 0x07,          /*   Usage Page (Keyboard)                         */
	0x19, 0x00,          /*   Usage Minimum (Reserved (no event indicated)) */
	0x29, 0x65,          /*   Usage Maximum (Keyboard Application)          */
	0x81, 0x00,          /*   Input (Data, Array, Absolute)                 */
	0xc0                 /* End Collection                                  */
};

How about this GitHub - NicoHood/HID: Bring enhanced HID functions to your Arduino!

johnwasser:
Probably because "Usage Page (Keyboard)" is built into the report descriptor. See Descriptors.c in the sources. I don't know nearly enough about USB to want to tackle adding a consumer HID device.

USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =

{
0x05, 0x01,          /* Usage Page (Generic Desktop)                    /
0x09, 0x06,          /
Usage (Keyboard)                                /
0xa1, 0x01,          /
Collection (Application)                        /
0x75, 0x01,          /
  Report Size (1)                              /
0x95, 0x08,          /
  Report Count (8)                              /
0x05, 0x07,          /
  Usage Page (Key Codes)                        /
0x19, 0xe0,          /
  Usage Minimum (Keyboard LeftControl)          /
0x29, 0xe7,          /
  Usage Maximum (Keyboard Right GUI)            /
0x15, 0x00,          /
  Logical Minimum (0)                          /
0x25, 0x01,          /
  Logical Maximum (1)                          /
0x81, 0x02,          /
  Input (Data, Variable, Absolute)              /
0x95, 0x01,          /
  Report Count (1)                              /
0x75, 0x08,          /
  Report Size (8)                              /
0x81, 0x03,          /
  Input (Const, Variable, Absolute)            /
0x95, 0x05,          /
  Report Count (5)                              /
0x75, 0x01,          /
  Report Size (1)                              /
0x05, 0x08,          /
  Usage Page (LEDs)                            /
0x19, 0x01,          /
  Usage Minimum (Num Lock)                      /
0x29, 0x05,          /
  Usage Maximum (Kana)                          /
0x91, 0x02,          /
  Output (Data, Variable, Absolute)            /
0x95, 0x01,          /
  Report Count (1)                              /
0x75, 0x03,          /
  Report Size (3)                              /
0x91, 0x03,          /
  Output (Const, Variable, Absolute)            /
0x95, 0x06,          /
  Report Count (6)                              /
0x75, 0x08,          /
  Report Size (8)                              /
0x15, 0x00,          /
  Logical Minimum (0)                          /
0x25, 0x65,          /
  Logical Maximum (101)                        /
0x05, 0x07,          /
  Usage Page (Keyboard)                        /
0x19, 0x00,          /
  Usage Minimum (Reserved (no event indicated)) /
0x29, 0x65,          /
  Usage Maximum (Keyboard Application)          /
0x81, 0x00,          /
  Input (Data, Array, Absolute)                /
0xc0                /
End Collection                                  */
};