Friday, January 17, 2014

Understanding USB HID

In computing, the USB HID / USB Human Interface Device class is a part of the comprehensive USB specification for computer/electronic peripherals that specifies a device class (a type of hardware) for human interface devices such as keyboards, mice, game controllers and display devices.

The USB HID class is defined in a number of documents provided by the USB Implementers Forum's Device Working Group. The primary document used to describe the USB HID class is the Device Class Definition for HID 1.11.

The USB HID class describes devices used with nearly every modern computer and incorporated in many modern "smart" electronic equipment. Since there are many basic communication functions are predefined (abstracted) in the USB HID class, hardware manufacturers should adhere to the USB HID class specifications and expect it to work with any software that also meets these specifications. This allows standardized devices operate interchangeable across wide range of equipment, no matter how different they are in their original nature.

The same HID protocol is used unmodified in Bluetooth Human Interface Devices. The Bluetooth profile specification only points readers to the USB HID documentation. In this sense those devices also belong to the USB HID class.

Examples of such devices:

  • Keyboards
    Keyboards are some of the most popular USB HID class devices. The USB HID class keyboard is normally designed with an IN endpoint that communicates keystrokes to the computer and an OUT endpoint that communicates the status of the keyboard's LEDs from the computer to the keyboard. The PC 97 standard requires that a computer's BIOS must detect and work with USB HID class keyboards that are designed to be used during the boot process.
  • Mice
    Computer mice are almost equally popular USB HID class devices. USB HID mice can range from single-button simple devices to multi-button compound devices. Most modern operating systems ship with drivers for standard HID mice designs (the most common modern mouse design has two dedicated buttons and a mouse wheel that doubles as the third button); mice with extended functionality require custom drivers from the manufacturer.
  • Game controllers
    Modern game controllers and joysticks are often USB HID class devices. Unlike legacy game port devices, USB HID class game devices do not normally require proprietary drivers to function. Nearly all game devices will function using onboard drivers as long as the device is designed around the drivers and the USB HID class specifications.
  • Other devices
    The USB HID class specifications allow for myriad other devices under the USB HID class. Some examples are automobile simulation controllers, exercise machines, telephony devices, thermometers, audio controls and medical instrumentation. Even uninterruptible power supplies and software protection dongles declare themselves under this class, despite the fact they often have no human interface at all. Any device can be a USB HID class device as long as a designer meets the USB HID class logical specifications. This is not to say that there is no need to ship drivers for these devices, nor that an operating system will immediately recognize the device. This only means that the device can declare itself under the human interface device class.
One of the benefits of a well-defined specification like the USB HID class is the abundance of device drivers available in most modern operating systems. The USB HID class devices and their basic functions are defined in USB-IF documentation without any specific software in mind. Because of these generic descriptions, it is easy for operating system designers to include functioning drivers for devices such as keyboards, mice, and other generic human interface devices. The inclusion of these generic drivers allows for faster deployment of devices and easier installation by end-users.

USB HID Logical Specifications


The USB human interface device class can be used to describe both device and interface classes. The interface class is used when a USB device can contain more than one function. It is possible, therefore, to have USB devices with two different interfaces at the same time (for example, a USB telephone may use a keypad covered by the HID class and a speaker covered by the USB audio device class).

The interface devices are also defined with subclass descriptors. The subclass descriptor is used to declare a device bootable. A boot device meets a minimum adherence to a basic protocol and will be recognized by a computer's BIOS.

Each USB HID interface communicates with the host using either a control pipe or an interrupt pipe. Isochronous and bulk pipes are not used in HID class devices. Both IN and OUT control transfers are required for enumeration; only an IN interrupt transfer is required for HID reports. OUT interrupt transfers are optional in HID-class devices.

The USB HID class requires that every device describes how it will communicate with the host device in order to accurately predict and define all current and future human interface devices. During enumeration the device describes how its reports are to be structured so that the host device can properly prepare to receive this information.

When user operates HID device, the device produces a piece of data called report. Computer learns what happened by polling device from time to time, parsing received reports and changes program flow accordingly. Devices operate with many different types of information – for example, keyboard has many buttons and sends key codes, mouse has just a few buttons so it sends just the state of those buttons, but is also capable to report its’ X and Y coordinates, while a steering wheel-type game controller sends wheel and pedal positions along with button presses. At the same time, various data can be sent from a computer to the device – LEDs on a keyboard or force-feedback on joystick or game controller, just to name a few. Simple devices, like mouse or keyboard, usually generate single report, while more complex devices often generate several.

A report is simple data structure, in most cases less than 10 bytes long. Format of this report is contained in much bigger and complex data structure called report descriptor. Report descriptor outlines what is contained in each byte (sometimes even each bit) of the report, type of data, units of measurement, range of values and other good stuff. Therefore, the format of report can be (and often is) determined by parsing report descriptor. The format and contents of report descriptors are well documented. The USB.org website has HID Page containing many useful documents, the main two being Device Class Definition for Human Interface Devices and HID Usage Tables. These two documents give good picture of what kind of information may be expected from HID device. In addition to this, many web resources exist presenting topic of HID formats in more humane way – googling for “HID format”, “HID report”, etc., produces plenty of links to HID-related content.

The host periodically polls the device's interrupt IN endpoint during operation. When the device has data to send it forms a report and sends it as a reply to the poll token. Common devices such as keyboards and mice send reports that are compliant with standards set by the USB Implementers Forum (USB-IF). When a vendor makes a custom USB HID class device, the reports formed by the device need to match the report description given during enumeration and the driver installed on the host system. In this way it is possible for the USB HID class to be extremely flexible.

USB API

There are two levels of APIs related to USB HID: the USB level and the operating system level. At the USB level, there is a protocol for devices to announce their capabilities and the operating system to parse the data it gets. The operating system then offers a higher-level view to applications, which do not need to include support for individual devices but for classes of devices. This abstraction layer allows a game to work with any USB controller, for example, even ones created after the game.

For more information, visit these sites:
For Arduino related content, visit/download:

Saturday, December 7, 2013

Shrinkify Arduino using Cheap ATtiny13A Microcontroller

You can shrinkify your simple Arduino project into ultra tiny ATtiny13A microcontroller as long as your project code size doesn't exceed 1 Kb limit of ATtiny13A, and it doesn't use RAM / EEPROM over 64 bytes . Why would you do that? Because two important reason: it's cheap (vcc2gnd.com sell this microcontroller for as low as $1.5 / Rp17.000,- for Indonesian customer, even tinier and cheaper for SOIC version), and it certainly has much smaller form than your ordinary Arduino, even compared with Arduino smallest form (Arduino Micro).

If you need more power (bigger program code space, bigger RAM), you should consider using bigger version of ATtiny such ATtiny2313, but that's another story. For now let's focus with ATtiny13A (note that "A" suffix means newer version of ATtiny13 series, older version has no such suffix). Also note that for serious design / commercial product, you really should consider using newer series such ATtiny45 or ATtiny85 (same form factor with bunch of new capabilities).

To program any AVR tiny microcontrollers you can use SPI-based programmer such usbASP, or use your existing SPI-enabled board such Arduino (using ArduinoISP sketch, see following picture to see how simple it is to connect ATtiny13A to your Arduino)...


Friday, December 6, 2013

Character LCD I2C Library for Arduino

With I²C Display Module, you can easily connect character LCD (Liquid Crystal Display) to your Arduino via I²C protocol, thus saving a lot of valuable pins usually used for parallel connection (at least 6 pins: 2 control pins - RS and EN - and 4 data pins D7, D6, D5, and D4 for 4-bit mode). With I²C (a.k.a. TWI /  Two Wires Interface), you need only two pins. Even better, those two pins can also be shared with other I2C-based peripherals.

Note: in Arduino Uno, SDA is pin A4, SCL is pin A5. For other models, please check corresponding pin diagram.

The only drawback of using these modules is (beside a little additional cost for purchasing I²C display module) is speed reduction, but it's negligible since you don't need to update lot of data at high speed with such character-based display device (might be different story with graphics LCD, they do need to fetch a lot of bitmap data).

You might want to use new LiquidCrystal_I2C library, please download most recent version (v1.2.1) in zipped file (485 Kb), generously contributed by F. Malpartida. Extract it to your Arduino working folder under library sub-folder (i.e., My Document\Arduino\libraries).

There are several Character LCD I²C modules on the market, you should use correct initialization code which might be slightly different for each device.

Include required library at beginning of your sketch as follow:
#include 'Wire.h'
#include 'LiquidCrystal_I2C.h'

Next step is to instantiate the LCD object by calling LiquidCrystal_I²C class constructor. This constructor accepts parameter in following order: addr, en, rw, rs, d4, d5, d6, d7, bl, blpol
  • addr is I²C address of the module. It's unique for each device, check with your I²C module supplier to get the correct address. Usually, they are set to 0x20, 0x27, or 0x38
  • en is bit index for Enable (EN) pin.
  • rw is bit index for Read/Write Selector (RW) pin.
  • rs is bit index for Register Selector (RS) pin.
  • d4d5d6d7 are bit indexes for upper 4-bit of data pins
  • bl is bit index for backlight pin.
  • blpol polarity of backlight pin, might be differs according to the LCD being used. Value is either POSITIVE or NEGATIVE (enum declared in LCD.h).
The first argument (addr) is mandatory, that means you have to manually specify the address of your I²C device. Other arguments are optional, if not specified they will be set to default values (bit#6 for en, bit#5 for rw, bit#4 for rs, bit#0 for d4, bit#1 for d5, bit#2 for d6, bit#3 for d7). If bl is omitted, backlight state won't be modified (default to value set by the I²C module). Default value for blpol is POSITIVE.

Those bit indexes are required for the library to send correct signal to appropriate pins since different I²C modules has different pin mapping.

Some example of initialization codes (try them to find one that suitable for your device), instantiated on object lcd:
  • LiquidCrystal_I2C lcd (0x20,2,1,0,4,5,6,7,3,POSITIVE);
  • LiquidCrystal_I2C lcd (0x27,2,1,0,4,5,6,7,3,POSITIVE);
  • LiquidCrystal_I2C lcd (0x20,4,5,6,0,1,2,3,7,NEGATIVE);
Finally, initialize the LCD by invoking begin() method which accepts two arguments: column count and row count. Example: for 16x2 display, invoke lcd.begin(16,2); For 20x4 display, invoke lcd.begin(20,4);

I2C LCD Display 20x4 Sample Sketch

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Instantiate lcd object
LiquidCrystal_I2C lcd( 0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE );

// Custom character patterns
const uint8_t charBitmap[][8] = {
   { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
   { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
   { 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
   { 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
   { 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
   { 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
   { 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
   { 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
};

void setup() {
  // initialize the lcd
  lcd.begin( 20, 4 ); 
  
  // create custom chars
  for( uint8_t i = 0; i < 8; i++ ) {
    lcd.createChar ( i, (uint8_t *)charBitmap[ i ] );
  }

  lcd.setCursor( 3, 2 );                  
  lcd.print( "LCD 20x4 DEMO" );
  lcd.setCursor( 0, 3 );
  lcd.print( "azTech @ vcc2gnd.com" );

}

void loop() {
   register uint8_t i;
   // Animate
   lcd.home();   
   for( i = 20; i--; ) lcd.write( random( 8 ) );
   lcd.setCursor( 0, 1 );
   for( i = 20; i--; ) lcd.write( random( 8 ) );   
   delay( 200 );
}
Watch the result on demo video below...

Wednesday, December 4, 2013

Prevent GCC from auto-inline a function

Sometimes GCC goes too "smart" by inlining a function (put entire block of it's code directly in place) rather than assembling it as normal subroutine (block of code invoked by RCALL/CALL instruction and returns with RET instruction).

You can tell GCC not to automatically inline a specific function by declaring noinline attribute modifier before function type declaration. For example:
__attribute__((noinline)) int myStrictFunction() { }

Thursday, November 28, 2013

Online Tool for Easily Write Inline Assembler from Arduino IDE

Inline assembler is practical optimizing technique to speed-up some time-sensitive routines in your program. Unfortunately, it's not as convenience as it should be, for example:
  • You have to enclose asm instructions within quotes
  • You have to manually add hard-coded line separator (and tabs, for making it readable for later debugging)
  • You have to manually describe what register used for input/output, plus you have to report what registers are being clobbered
To help you assembler-inlining, we create this simple tool for you. No software to download / install, it's running right in this blog using embedded javascript. Just type your code below and hit the  Generate Code  button below, an inline assembler code suitable for avr-gcc will be automatically generated.
Enter your plain assembler code below...
Click to generate inline assembler code...

Make Your Arduino Uno Runs 25% Faster

Your Arduino Uno comes with 16 MHz crystal, thus it runs at nearly 16 MIPS (since most of instructions are executed in single cycle). As you might know, Arduino Uno utilize ATmega328 MCU from Atmel. One obvious fact that strangely most of ordinary Arduino users don't know is that the MCU's top speed is actually rated at 20 MHz, not 16 MHz! 16 MHz is official speed limit of MCU used in early version of Arduino, ATmega8 (up to Arduino NG and Severino). Carried on with this obsolete limit, Arduino Uno is still clocked with 16 MHz crystal.

To boost your Arduino Uno's performance up to 25% faster, all you have to do is replace the 16 MHz crystal with 20 MHz crystal, and update the bootloader with one that designed for this upgraded speed (see instruction below).

Please note that this is NOT overclocking, we'll just tuning it to maximum speed allowed by manufacturer as stated in ATmega328 datasheet. So it's 100% safe and guaranteed to run as reliable as before, it's just 25% faster :) up to nearly 20 MIPS!

Step 1: Add following content to your boards.txt (located in hardware/arduino sub-directory of the Arduino application directory, i.e. \Program Files (x86)\Arduino\hardware\arduino in default installation path on 64-bit Windows (or \Program Files\Arduino\hardware\arduino if you're still using the immortal WinXP ;)...

##############################################################

atmega328_20.name=Arduino Uno++ 20MHz

atmega328_20.upload.protocol=stk500
atmega328_20.upload.maximum_size=30720
atmega328_20.upload.speed=57600

atmega328_20.bootloader.low_fuses=0xFF
atmega328_20.bootloader.high_fuses=0xDA
atmega328_20.bootloader.extended_fuses=0x05
atmega328_20.bootloader.path=atmega
atmega328_20.bootloader.file=ATmega328_20MHz.hex
atmega328_20.bootloader.unlock_bits=0x3F
atmega328_20.bootloader.lock_bits=0x0F

atmega328_20.build.mcu=atmega328p
atmega328_20.build.f_cpu=20000000L
atmega328_20.build.core=arduino
Step 2: Create new file with name ATmega328_20MHz.hex under hardware/arduino/bootloaders/atmega sub-directory with following content:
Step 3: desolder the old 16 Mhz crystal from Arduino Uno board. Please note that this action may void your warranty, please proceed on your own risk! If you're unsure with this, perhaps it's better to build a brand new Arduino compatible board by your own from scratch. For example, you can buy Playduino-One kit from Play-Zone — they ship worldwide — for Fr. 19.9 (about USD 21). If you live in Indonesia, you can also purchase Playduino-One Kit from azTech for only Rp150.000,- (less than USD 14).
Step 4: Install a 20 MHz crystal. Soldering should be easy since space on bottom surface is sparse.
Step 5: Burn the bootloader: open Arduino IDE, if you've done step #1 correctly then a new board should be appear under Tools > Board menu with name Arduino Uno++ 20MHz. Select the new board, attach USB cable to Arduino (or ISP programmer if you build Playduino One), and execute Tools > Burn Bootloader command. That's all, now you have a much faster Arduino!