User Tools

Site Tools

한국어

comfilepi:controlling_the_lcd_backlight:index

Controlling the LCD Backlight

The ComfilePi's LCD backlight is connected to GPIO 34. The backlight can be turned on or off via the command line or via a programming language.

Command Line Interface

To turn off the backlight:

gpio mode 34 output
gpio write 34 0

To turn on the backlight:

gpio mode 34 output
gpio write 34 1

Sample C Program

The backlight can be controlled in the C programming language using the pigpio library.

#include <pigpiod_if2.h>
 
#define PIN 34
 
void backlight_on()
{
    auto instance = pigpio_start(NULL, NULL);
 
    set_mode(instance, PIN, PI_OUTPUT);
    gpio_write(instance, PIN, 1);
 
    pigpio_stop(instance);
}
 
void backlight_off()
{
    auto instance = pigpio_start(NULL, NULL);
 
    set_mode(instance, PIN, PI_OUTPUT);
    gpio_write(instance, PIN, 0);
 
    pigpio_stop(instance);
}

Synchronizing the Backlight with the X11 Screensaver

This program will turn the backlight ON or OFF according to the ON/OFF state of the display as reported by DPMS (run xset q from a terminal to see the DPMS report).

#include <cstdio>
#include <X11/Xlib.h>
#include <X11/extensions/dpms.h>
#include <chrono>
#include <thread>
 
using namespace std;
using namespace std::chrono;
 
#include <pigpiod_if2.h>
 
#define PIN 34
 
void backlight_on()
{
    auto instance = pigpio_start(NULL, NULL);
 
    set_mode(instance, PIN, PI_OUTPUT);
    gpio_write(instance, PIN, 1);
 
    pigpio_stop(instance);
}
 
void backlight_off()
{
    auto instance = pigpio_start(NULL, NULL);
 
    set_mode(instance, PIN, PI_OUTPUT);
    gpio_write(instance, PIN, 0);
 
    pigpio_stop(instance);
}
 
int main(int argc, char *argv[])
{
    Display *dpy;
    dpy = XOpenDisplay(NULL);
    if (dpy == NULL)
    {
        fprintf(stderr, "%s:  unable to open display\n", argv[0]);
        exit(EXIT_FAILURE);
    }
 
    BOOL onoff;
    CARD16 state;
    while(true)
    {
        DPMSInfo(dpy, &state, &onoff);
        if (onoff)
        {
            switch (state)
            {
                case DPMSModeOn:
                    backlight_on();
                    break;
                case DPMSModeOff:
                    backlight_off();
                    break;
                default:
                    break;
            }
        }
        this_thread::sleep_for(milliseconds(200));
    }
 
    XCloseDisplay(dpy);
 
    return 0;
}

Compile

g++ backlight_service.cpp -lX11 -lXext -lpigpiod_if2 -o backlight_service

Automatically Start the Service

Add the line @{/path/to/}backlight_service to the /etc/xdg/lxsession/LXDE-pi/autostart file to automatically start the backlight_service executable when the desktop starts.

To set the timeout to 60 seconds run xset dpms 0 0 60 from a terminal.

Add the line @xset dpms 0 0 {timeout_in_seconds} to the autostart file to set the timeout each time the desktop loads.

Screensaver Functionality In Non-X Programs

To put the backlight on a timer that turns OFF after a specified timeout, and turns back ON when the screen is touched, the following program can be used.

#include <cstdio>
#include <cstdint>
#include <fstream>
#include <unistd.h>
#include <errno.h>
#include <getopt.h>
#include <sys/file.h>
#include <linux/input.h>
#include <chrono>
#include <thread>
 
#include <pigpiod_if2.h>
 
using namespace std;
using namespace std::chrono;
 
static int instance = -1;
 
#define PIN 34
 
void backlight_on()
{
    auto instance = pigpio_start(NULL, NULL);
 
    set_mode(instance, PIN, PI_OUTPUT);
    gpio_write(instance, PIN, 1);
 
    pigpio_stop(instance);
}
 
void backlight_off()
{
    auto instance = pigpio_start(NULL, NULL);
 
    set_mode(instance, PIN, PI_OUTPUT);
    gpio_write(instance, PIN, 0);
 
    pigpio_stop(instance);
}
 
bool backlight_isOn()
{
    auto instance = pigpio_start(NULL, NULL);
 
    set_mode(instance, PIN, PI_INPUT);
    auto isOn = gpio_read(instance, PIN) == 1;
 
    pigpio_stop(instance);
 
    return isOn;
}
 
int main(int argc, char* argv[])
{
    int secs = 60;
 
    if (argc >= 2)
    {
        secs = stoi(argv[1]);
    }
 
    // Touch events happen on event0
    auto input_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
 
    struct input_event ev;
    auto lastTouch = high_resolution_clock::now();
    while (true)
    {
        // get the input event
        auto n = read(input_fd, &ev, sizeof(ev));
 
        // If an input event
        if (n != (ssize_t)-1)
        {
            if (ev.type == EV_KEY && ev.value >= 0 && ev.value <= 2)
            {
                if (ev.value == 1)  // If a touch
                {
                    backlight_on();
                    lastTouch = high_resolution_clock::now();
                }
            }
        }
 
        auto now = chrono::high_resolution_clock::now();
        auto sec = duration_cast<seconds>(now - lastTouch).count();
        if (sec > secs)
        {
            backlight_off();
        }
 
        this_thread::sleep_for(milliseconds(10));
    }
 
    return 0;
}

Compile

g++ main.cpp -lpigpiod_if2 -lpthread -o backlight

Run

To cause the backlight to turn OFF after 60 seconds.

backlight 60

Register as a Background Service

[Unit]
Description=backlight service
After=pigpio.service

[Service]
ExecStart={path/to/}backlight 60
Restart=always

[Install]
WantedBy=multi-user.target

Dimming the Backlight

Hardware revision v2.1 connects the backlight to GPIO 31 which supports PWM. Use the pigpio library to adjust the brightness of the backlight.

#include <pigpiod_if2.h>
#include <iostream>
#include <string>
 
using namespace std;
 
#define PIN 31
 
int main(int argc, char *argv[])
{
   int value = stoi(argv[1]);
 
   auto instance = pigpio_start(NULL, NULL);
 
   set_PWM_frequency(instance, PIN, 200);
 
   set_PWM_dutycycle(instance, PIN, value);
 
   pigpio_stop(instance);
}

Compile and run:

g++ backlight.cpp -lpigpiod_if2 -lpthread -o backlight

./backlight 0    # minimum brightness
./backlight 128  # medium brightness
./backlight 255  # maximum brightness

Hardware Revisions

v2.0+

CPi_A070WR (S/N : A01001-17-7-11 ~ A01001-17-11-91)

CPi_A102WR (S/N : A01003-17-7-1 ~ A01003-17-10-26)

The initial ComfilePi that was produced did not populate R33 on the main board's PCB. On those models, switching the LCD backlight on or off will not work unless R33 is populated. Hardware revision v2.0 populates R33 with a 22 Ohm resistor, so switching the backlight on or off will work out of the box.

To test which hardware revision you have, simply run the commands illustrated above and see if they work.

v2.1+ (Refer to hardware version printed on sticker)

Hardware revision v2.1 connects the backlight to GPIO 31 which supports PWM. See Dimming the Backlight.

comfilepi/controlling_the_lcd_backlight/index.txt · Last modified: 2019/09/19 15:22 by COMFILE Technology