Equivalent to a common keyboard using Arduino Leonardo

I am trying to use Arduino Leonardo to emulate a keyboard, as this is one of its advertised features. I played with Leonardo and wrote a very simple sketch based on the Blink example.

// Pin 13 has an LED connected on most Arduino boards. int led = 13; // The setup routine runs once when you press reset: void setup() { // Initialize the digital pin as an output. pinMode(led, OUTPUT); } // The loop routine runs over and over again forever: void loop() { delay(5000); // Wait for five seconds digitalWrite(led, HIGH); // Turn the LED on (HIGH is the voltage level) delay(100); // Wait for a secondA digitalWrite(led, LOW); // Turn the LED off by making the voltage LOW Keyboard.write('A'); // Write an A using keyboard emulator } 

Now this example works fine on my computer running Windows XP. It is recognized as a shared HID keyboard and dials β€œA” every five seconds.

The target environment launches DOS, as far as I know, I need Arduino Leonardo to recognize the BIOS on this machine, but it is not, and it does not enter β€œA” in DOS.

I made changes to the Leonardo USB device descriptor, trying to get it as close as possible to the Dell L100. The modifications I made did not help, and I suspect that this is because Leonardo is a composite device that provides serial communication, keyboard emulation, and mouse emulation on the same USB port. The descriptor / USB configuration source code is editable and located at:

  • Arduino_Installation \ HARDWARE \ Arduino \ cores \ Arduino \ HID.cpp
  • Arduino_Installation \ HARDWARE \ Arduino \ cores \ Arduino \ USBDesc.h
  • Arduino_Installation \ HARDWARE \ Arduino \ cores \ Arduino \ USBCore.h
  • Arduino_Installation \ HARDWARE \ Arduino \ cores \ Arduino \ USBCore.cpp

The following is a dump from a USB Device Viewer for Leonardo:

 [Port3] : USB Composite Device ---===>Device Information<===--- English product name: "Arduino Leonardo" ConnectionStatus: Current Config Value: 0x01 -> Device Bus Speed: Full Device Address: 0x03 Open Pipes: 4 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x81 -> Direction: IN - EndpointID: 1 bmAttributes: 0x03 -> Interrupt Transfer Type wMaxPacketSize: 0x0010 = 0x10 bytes bInterval: 0x40 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x02 -> Direction: OUT - EndpointID: 2 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x84 -> Direction: IN - EndpointID: 4 bmAttributes: 0x03 -> Interrupt Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x01 ===>Device Descriptor<=== bLength: 0x12 bDescriptorType: 0x01 bcdUSB: 0x0110 bDeviceClass: 0x00 *!*ERROR: device class should be Multi-interface Function 0xEF When IAD descriptor is used bDeviceSubClass: 0x00 *!*ERROR: device SubClass should be USB Common Sub Class 2 When IAD descriptor is used bDeviceProtocol: 0x00 *!*ERROR: device Protocol should be USB IAD Protocol 1 When IAD descriptor is used bMaxPacketSize0: 0x40 = (64) Bytes idVendor: 0x2341 = Vendor ID not listed with USB.org as of 03-19-2008 idProduct: 0x8036 bcdDevice: 0x0100 iManufacturer: 0x01 English (United States) "Arduino LLC" iProduct: 0x02 English (United States) "Arduino Leonardo" iSerialNumber: 0x00 bNumConfigurations: 0x01 ===>Configuration Descriptor<=== bLength: 0x09 bDescriptorType: 0x02 wTotalLength: 0x0064 -> Validated bNumInterfaces: 0x03 bConfigurationValue: 0x01 iConfiguration: 0x00 bmAttributes: 0x80 -> Bus Powered MaxPower: 0xFA = 500 mA ===>IAD Descriptor<=== bLength: 0x08 bDescriptorType: 0x0B bFirstInterface: 0x00 bInterfaceCount: 0x02 bFunctionClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class bFunctionSubClass: 0x01 bFunctionProtocol: 0x01 iFunction: 0x00 ===>Interface Descriptor<=== bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x00 bAlternateSetting: 0x00 bNumEndpoints: 0x01 bInterfaceClass: 0x02 -> This is Communications (CDC Control) USB Device Interface Class bInterfaceSubClass: 0x01 bInterfaceProtocol: 0x00 CAUTION: This may be an invalid bInterfaceProtocol iInterface: 0x00 -> This is a Communications (CDC Control) USB Device Interface Class ===>Descriptor Hex Dump<=== bLength: 0x05 bDescriptorType: 0x24 05 24 00 10 01 -> This is a Communications (CDC Control) USB Device Interface Class ===>Descriptor Hex Dump<=== bLength: 0x05 bDescriptorType: 0x24 05 24 01 01 01 -> This is a Communications (CDC Control) USB Device Interface Class ===>Descriptor Hex Dump<=== bLength: 0x04 bDescriptorType: 0x24 04 24 02 06 -> This is a Communications (CDC Control) USB Device Interface Class ===>Descriptor Hex Dump<=== bLength: 0x05 bDescriptorType: 0x24 05 24 06 00 01 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x81 -> Direction: IN - EndpointID: 1 bmAttributes: 0x03 -> Interrupt Transfer Type wMaxPacketSize: 0x0010 = 0x10 bytes bInterval: 0x40 ===>Interface Descriptor<=== bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x01 bAlternateSetting: 0x00 bNumEndpoints: 0x02 bInterfaceClass: 0x0A -> This is a CDC Data USB Device Interface Class bInterfaceSubClass: 0x01 bInterfaceProtocol: 0x00 CAUTION: This may be an invalid bInterfaceProtocol iInterface: 0x00 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x02 -> Direction: OUT - EndpointID: 2 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3 bmAttributes: 0x02 -> Bulk Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x00 ===>Interface Descriptor<=== bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x02 bAlternateSetting: 0x00 bNumEndpoints: 0x01 bInterfaceClass: 0x03 -> HID Interface Class bInterfaceSubClass: 0x01 bInterfaceProtocol: 0x00 CAUTION: This may be an invalid bInterfaceProtocol iInterface: 0x00 ===>HID Descriptor<=== bLength: 0x09 bDescriptorType: 0x21 bcdHID: 0x0101 bCountryCode: 0x00 bNumDescriptors: 0x01 bDescriptorType: 0x22 wDescriptorLength: 0x0065 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x84 -> Direction: IN - EndpointID: 4 bmAttributes: 0x03 -> Interrupt Transfer Type wMaxPacketSize: 0x0040 = 0x40 bytes bInterval: 0x01 

How can I get this Leonardo recognized BIOS as a shared keyboard?

+6
source share
2 answers

Arduino does not support boot protocol. I started using Teensy (which is compatible with Arduino) and it works very well.

+2
source

Maybe I'm wrong, but if you want your device to be recognized at boot time, it should be bInterfaceSubClass 0x01 (subclass of Boot device). In the source files you mentioned, everywhere there is a subclass set to 0x00.

You can try to subclass all modes of using the D_INTERFACE macro from USBCore.h to 0x01.

I am not an Arduino user, I only once played with HID keyboard emulation on AVR using V-USB . You can find detailed information about usb descriptors in USB.org in the documentation. But this is quite a bunch of pages to read.

Here is a part of the descriptor descriptor descriptor of my keyboard, pay attention to the values ​​in the interface descriptor:

 Bus 005 Device 002: ID 046d:c30e Logitech, Inc. UltraX Keyboard (Y-BL49) Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x046d Logitech, Inc. idProduct 0xc30e UltraX Keyboard (Y-BL49) bcdDevice 1.80 iManufacturer 1 Logitech iProduct 2 HID compliant keyboard iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 59 bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 1 Keyboard iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.10 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 62 

The dump was created using "lsusb -v" as root under linux.

+1
source

Source: https://habr.com/ru/post/926711/


All Articles