Send keycode to android

Hi,
In order to control an android headunit I would like to use a multimedia keyboard such as this one :

The First thing I made was to decode CAN signals from the keyboard, using an arduino leonardo and a can shield.
Then, I need help to send things to the headunit. I wanted to use android Keyevent via USB, that can be found here :

But I have no idea how does it works.

I dont know many about android or about arduino, but I'm able to learn quickly, I just need help to understand how does it works.
Does anybody already made similar things?
Thanks :slight_smile:

Start by studying the documentation. Then if you have questions, post on the developer's forum.

Yea, that’s why I asked if anybody already made something like that. I’m asking for ideas, « project guidance », of course I’m looking to solve it by myself. Your answer is not quite useful, sorry.

You told us that you "just need help to understand how does it works", and I explained what you have to do to gain that understanding.

Feel free to ignore that advice. You will eventually figure that out that copying someone else's project won't get you far.

Can you explain me how it works if you haven’t ever done a similar project? Right, you can’t. I’m not copying, I’m asking help to someone with experience.
So thanks for your advise, now please stop annoying me.

Welcome to my ignore list, and have a nice life!

Do you know what keys the head unit expects?

Perhaps the USB HID specifications will help. A PC-style keyboard and keypad use "code page" 0x07. See page 53.

Some of the "media" keys (VolUp, VolDown, Mute, Stop) are outside the range that the Keyboard library can send. To send them you have to bypass the ASCII-to-Keystroke mapping. You can do that by inserting these functions into the library:

// pressRaw() adds the specified USB raw keycode to the persistent key 
// report and sends the report.
size_t Keyboard_::pressRaw(uint8_t k) 
{
	uint8_t i;
	
	// Add k to the key report only if it's not already present
	// and if there is an empty slot.
	if (_keyReport.keys[0] != k && _keyReport.keys[1] != k && 
		_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
		_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
		
		for (i=0; i<6; i++) {
			if (_keyReport.keys[i] == 0x00) {
				_keyReport.keys[i] = k;
				break;
			}
		}
		if (i == 6) {
			setWriteError();
			return 0;
		}	
	}
	sendReport(&_keyReport);
	return 1;
}


// releaseRaw() takes the specified key out of the persistent key report and
// sends the report.  This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t Keyboard_::releaseRaw(uint8_t k) 
{
	uint8_t i;
	
	// Test the key report to see if k is present.  Clear it if it exists.
	// Check all positions in case the key is present more than once (which it shouldn't be)
	for (i=0; i<6; i++) {
		if (0 != k && _keyReport.keys[i] == k) {
			_keyReport.keys[i] = 0x00;
		}
	}


	sendReport(&_keyReport);
	return 1;
}


size_t Keyboard_::writeRaw(uint8_t c)
{
	uint8_t p = pressRaw(c);  // Keydown
	releaseRaw(c);            // Keyup
	return p;              // just return the result of press() since releaseRaw() almost always returns 1
}

You would add these functions to Keyboard.cpp and modify the Keyboard class in Keyboard.h to add:

  size_t writeRaw(uint8_t k);
  size_t pressRaw(uint8_t k);
  size_t releaseRaw(uint8_t k);

Thanks! Your answer may helps me a lot since I’ll need to use key such as VOLUP/DOWN.
I’ll try to code something in the next week maybe.

But how can I send for example speaker phone (2B). Keyboard.writeRaw(0x2B); doesn't work. Do I have to define the page? In that case 0x0B

Thanks

Yes. The "Keyboard" library only does "Keyboard/Keypad Page (0x07)" and you want the "Telephony Device Page (0x0B)". I would start by taking Keyboard.h and Keyboard.cpp from the Keyboard library and making a new library named Telephony. Everywhere it says "Keyboard", change it to say "Telephony" (including the filenames).

In the new "Telephony.cpp" change these two lines:

    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)

to these two lines:

    0x05, 0x0B,                    //   USAGE_PAGE (Telephony Device)
    0x05, 0x0B,                    //   USAGE_PAGE (Telephony Device)

That should get you part way there.

You don't need the ASCII lookup table and you should probably put in a bunch of defines for the telephony keys.