LUFA USB keyboard

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all.

I make small appliction what emulate USB keyboard and if push button then send string to PC (like type in the keyboard).

For this I use latest version LUFA (lufa-LUFA-151115) , WinAVR and AVR Studio 4.19 .

I use ARduino Leonardo board with ATmega32U4 with 16Mhz speed ..

Now question is :

How to send text very fast .. becasue if send char , one by one ..I must use delay - 4 ms .. , if not then I PC not receive char.. I don't know .. I use this code 

 

Keyboard Task:

/** Keyboard task. This generates the next keyboard HID report for the host, and transmits it via the
 *  keyboard IN endpoint when the host is ready for more data. Additionally, it processes host LED status
 *  reports sent to the device via the keyboard OUT reporting endpoint.
 */
void Keyboard_HID_Task(void)
{
	/* Device must be connected and configured for the task to run */
	if (USB_DeviceState != DEVICE_STATE_Configured)
	  return;

	/* Select the Keyboard Report Endpoint */
	Endpoint_SelectEndpoint(KEYBOARD_IN_EPADDR);

	/* Check if Keyboard Endpoint Ready for Read/Write */
	if (Endpoint_IsReadWriteAllowed())
	{
		/* Write Keyboard Report Data */
		Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData), NULL);

		/* Finalize the stream transfer to send the last packet */
		Endpoint_ClearIN();

		/* Clear the report data afterwards */
		memset(&KeyboardReportData, 0, sizeof(KeyboardReportData));
	}
}

Kpress for press any char .. (I use it from Arduino core)

size_t Kpress(uint8_t k) 
{
	uint8_t i;
	if (k >= 136) {			// it's a non-printing key (not a modifier)
		k = k - 136;
	} else if (k >= 128) {	// it's a modifier key
		KeyboardReportData.Modifier |= (1<<(k-128));
		k = 0;
	} else {				// it's a printing key
		k = pgm_read_byte(_asciimap + k);
		if (!k) {
			//setWriteError();
			return 0;
		}
		if (k & 0x80) {						// it's a capital letter or other character reached with shift
			KeyboardReportData.Modifier |= 0x02;	// the left shift modifier
			k &= 0x7F;
		}
	}
	
	// Add k to the key report only if it's not already present
	// and if there is an empty slot.
	if (KeyboardReportData.KeyCode[0] != k && KeyboardReportData.KeyCode[1] != k && 
		KeyboardReportData.KeyCode[2] != k && KeyboardReportData.KeyCode[3] != k &&
		KeyboardReportData.KeyCode[4] != k && KeyboardReportData.KeyCode[5] != k) 
		{
		
		for (i=0; i<6; i++) 
			{
			if (KeyboardReportData.KeyCode[i] == 0x00) 
				{
				KeyboardReportData.KeyCode[i] = k;
				break;
				}
			}
		}	
	Keyboard_HID_Task();
	return 1;
} 

and Krelease .. (use from Arduino core)

size_t Krelease(uint8_t k) 
{
	uint8_t i;
	if (k >= 136) {			// it's a non-printing key (not a modifier)
		k = k - 136;
	} else if (k >= 128) {	// it's a modifier key
		KeyboardReportData.Modifier &= ~(1<<(k-128));
		k = 0;
	} else {				// it's a printing key
		k = pgm_read_byte(_asciimap + k);
		if (!k) {
			return 0;
		}
		if (k & 0x80) {							// it's a capital letter or other character reached with shift
			KeyboardReportData.Modifier &= ~(0x02);	// the left shift modifier
			k &= 0x7F;
		}
	}
	
	// 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 && KeyboardReportData.KeyCode[i] == k) {
			KeyboardReportData.KeyCode[i] = 0x00;
		}
	}

	Keyboard_HID_Task();
	return 1;
} 

and write small function to send string from my code to PC :

void KSendStr(uint8_t *s)
{
uint8_t	temp;
	while(*s) {
		temp = *s++;
		Kpress(temp);
		_delay_ms(4);
		Krelease(temp);
		_delay_ms(4);
	}
}

Now if want send data do this for example :  

	KSendStr((uint8_t *)"Hello world \n");

Is there any way how to do it faster ??? not wait 4ms every time if send char ??

 

regards..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want high-speed communication, then why are you using a virtual keyboard, i.e. the HID class? It is not designed for high capacity communication.

 

Why not use the CDC class instead?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ehm.. I need virtual keyboard .. HID class .. no driver or somethink else..  I just if this is problem my OS so PC is slow or what ??

ehm.. if make HID bootloader .. then use 64byte buffer .. and then speed is good .. but in emulation keyboard .. char is send one by one .. div 2 .. becase send char .. is pressed .. and send char is release.. then 8ms .. too big .. I can 

use it .. but just try .. if there is not any other way.. 

 

any idea??

 

 

PS> I reduce it .. if send char .. and in buffer is next char then not send release.. release use only after send all char.. then this is possible to use .. 4ms is good time..

Last Edited: Sat. Dec 5, 2015 - 05:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't understand your assumption that 4mS [0.004 seconds] for a character transfer/display is slow.  Human persistence-of-vision doesn't allow our eyes to see changes that are faster than @0.030 seconds {that's how cinema works: still photos that change slightly at 24 per second are seen as moving pictures}.  Normal typing is considered fast at 400 keypresses a minute (80 words/minute) or about 6 per second.