February 4, 2015   Posted by: Dr. Ace Jeangle

How to control LCD backlight (USB HID)

Starting from version 2.0 all firmwares for our LCD and HDMI converters support LCD backlight control through standard USB HID protocol.

HID report descriptor

The following HID report descriptor is used:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    0x05, 0x0C,             //    Usage Page (Consumer)
    0x09, 0x01,             //    Usage (Consumer Control)
    0xA1, 0x01,             //    Collection (Application)
    0x15, 0x00,             //       Logical Minimum (0)
    0x25, 0x01,             //       Logical Maximum (1)
    0x75, 0x01,             //       Report Size (1)
    0x95, 0x07,             //       Report Count (7)
    0x19, 0x6F,             //       Usage Minimim (0x6F)
    0x29, 0x75,             //       Usage Maximum (0x75)    
    0x91, 0x02,             //       * Output (Data, Var, Abs)
    0x95, 0x01,             //       Report Count (1)
    0x91, 0x03,             //       * Output (Const, Var, Abs)
    0x25, 0x23,             //       Logical Maximum (35)
    0x75, 0x08,             //       Report Size (8)
    0x09, 0x71,             //       Usage (0x71 -  Display Brightness)
    0x91, 0x02,             //       * Output (Data, Var, Abs)
    0x09, 0x35,             //       Usage (0x35 - Illumination)
    0x26, 0xFF, 0x00,       //       Logical Maximum (255)
    0x81, 0x02,             //       ** Input (Data, Var, Abs)
    0x05, 0x20,             //       Usage Page (Sensors)
    0x09, 0x41,             //       Usage (0x41 -  Ambient Light Sensor)
    0x81, 0x02,             //       ** Input (Data, Var, Abs)
    0xC0                    //    End Collection

Report usages follow recent changes in official USB HID specification proposed by Microsoft in change request #HUTRR41. Interface # is 0 for HDMI-dualLVDS converter and FullHD+ LCD bundle, Interface # is 1 for open frame/black frame 7″ LCD and for new 10″ integrated LCD. Report ID is 0 for all cases.

Packet format

Firmware accepts 2-bytes packet request from host and reply with 2-bytes packet with information about current backlight mode and ambient light level:
Backlight HID format

Only one bit can be active in command byte of request packet. If bit 5 is active (Set Brightness command), then next byte contains desired brightness level. For others commands second byte is ignored. LCD will reply with current backlight status and ambient light sensor value to any received command. To get current status without performing command you can send request with command byte equal to 0. MAX_BL is 35 for HDMI-dualLVDS converter and FullHD+ LCD bundle, MAX_BL is 18 for open frame/black frame 7″ LCD and for new 10″ integrated LCD.

How to send commands

The simplest way to communicate with HID devices is to to use cross-platform library HIDAPI from Signal11. With HIDAPI it is just several lines of code to control LCD brightness:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>
#include "hidapi.h"

// Try to open HID device and return pointer to opened device
hid_device* openHID() {
    struct hid_device_info *devs, *cur_dev;
    hid_device* device = NULL;
    int iface = 1;  // We use interface# 1 for 7" and 10", and interface# 0 for dualLVDS/FullHD+

    // VID=0x04D8, PID=0xF724 for 7" and 10" multi-touch firmware, interface# is 1
    // VID=0x04D8, PID=0xF723 for 7" and 10" single-touch firmware, interface# is 1
    // VID=0x04D8, PID=0x003F for dualLVDS/FullHD+, interface# is 1
    devs = hid_enumerate(0x04D8, 0xF724);
    if (devs == NULL) {
        devs = hid_enumerate(0x04D8, 0xF723);
        if (devs == NULL) {
            devs = hid_enumerate(0x04D8, 0x003F);
            if (devs == NULL) return NULL;
            else iface = 0;
        }
    }

    // Walk through all enumerated devices to find one with correct interface number
    cur_dev = devs;
    while (cur_dev) {
        if ((cur_dev->interface_number) == iface) {
            device = hid_open_path(cur_dev->path);
            printf("Found Backlight interface at path: %s", cur_dev->path);
            break;
        }
        cur_dev = cur_dev->next;
    }
    hid_free_enumeration(devs);

    return device;
}

int main(int argc, char *argv[]) {
    hid_device* device=NULL;
    unsigned char buf[3];

    buf[0] = 0x0;   // Report ID (0)
    buf[1] = 0x04;  // Command (0x20 - Set Backlight)
    buf[2] = 9;     // Backlight value for command Set Backlight

    hid_init();

    device = openHID();
    if (device == NULL) {
        puts("Can't find USB device with interface for backlight");
        return -1;
    }

    hid_set_nonblocking(device, true);


    printf("Writing bytes: %02X,%02X,%02X\n", buf[0], buf[1], buf[2]);

    if (hid_write(device, buf, 3) == -1) {
        puts("Error writing bytes to device!");
        hid_close(device);
        return -1;
    }

    if (hid_read_timeout(device, buf, 2, 100) == -1) {
        puts("Error reading bytes to device!");
        hid_close(device);
        return -1;
    }

    printf("Received bytes: %02X,%02X\n", buf[0], buf[1]);

    return 0;
}

Above example is universal and will work with all our products with USB backlight control feature.

GUI application for LCD control

Cross-platform GUI application to control different LCD settings including brightness is available here:
LCD control GUI
You will need Qt framework to build it from sources.

See in action

Video with backlight test using our dualLVDS converter FullHD+ LCD is available here: Backlight test video

Follow us on Twitter to get instant notification about updates: h

5 comments posted in: blog   |   How-To
5 comments
  1. […] Ambient light sensor is available as an option, and can measure ambient light level for automatic backlight control. Ambient light sensor should be connected to connector J1, red color wire to pin 1 on connector. Light level is available as a voltage in range 0 (dark) to 2.5V (max. light) on pin RC2 (ADC channel 6) of PIC microcontroller. Backlight brightness can be controlled with help of PWM signal on GPIO_RC5. Additional information about backlight control through USB HID commands is available in this how-to: How to control LCD backlight (USB HID) […]

  2. […] Starting from version 2.0 firmware for our 10″ integrated LCD supports LCD backlight control through standard USB HID protocol and automatic backlight control with optional ambient light sensor. Ambient light sensor should be connected to connector J1, red color wire to pin 1 on connector (pin 1 is marked with white dot). Additional details about backlight control from your host board or PC through USB HID commands are available here: How to control LCD backlight (USB HID). […]

  3. […] Ambient light sensor is available as an option, and can measure ambient light level for automatic brightness control. Ambient light sensor should be connected to connector J1, red color wire to pin 1 on connector. You will need latest firmware in order to get automatic backlight control. Also, with last firmware you can control backlight from your host board or PC through USB HID commands: How to control LCD backlight (USB HID) […]

  4. Kelly
    Feb 14, 2019

    The LCD Control Application is in a zip file that is password protected. What is the password?

    • Dr. Ace Jeangle
      Feb 20, 2019

      It was uploaded by mistake, now it is fixed.

Leave a Reply to Kelly Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Follow us