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.
To turn off the backlight:
# using Bullseye raspi-gpio set 34 op raspi-gpio set 34 dl # using Buster or prior OSes gpio mode 34 output gpio write 34 0
To turn on the backlight:
# using Bullseye raspi-gpio set 34 op raspi-gpio set 34 dh # using Buster or prior OSes gpio mode 34 output gpio write 34 1
To turn off the backlight:
# using Bullseye raspi-gpio set 44 op raspi-gpio set 44 dl # using Buster or prior OSes gpio mode 44 output gpio write 44 0
To turn on the backlight:
# using Bullseye raspi-gpio set 44 op raspi-gpio set 44 dh # using Buster or prior OSes gpio mode 44 output gpio write 44 1
The backlight can be controlled in the C programming language using the pigpio library.
#include <pigpiod_if2.h> #define PIN 34 // CPi-A & CPi-B // #define PIN 44 // CPi-C 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); }
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 <cstdlib> #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 // CPi-A & CPi-B // #define PIN 44 // CPi-C 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; }
Add the necessary development packages …
sudo apt install libx11-dev libxext-dev
… then compile.
g++ backlight_service.cpp -lX11 -lXext -lpigpiod_if2 -o backlight_service
The same can be a achieved using the following Bash script:
#!/bin/bash export DISPLAY=":0.0" PIN=34 # CPi-A & CPi-B #PIN=44 # CPi-C raspi-gpio set $PIN op # Loop indefinitely updating backlight in sync with monitor status while true; do # Check the current monitor status current_status=$(xset q | grep "Monitor is" | awk '{print $3}') # Control backlight pin according to the monitor status if [ "$current_status" = "On" ]; then raspi-gpio set $PIN dh else raspi-gpio set $PIN dl fi # Sleep before checking again sleep 0.2s done
Add the line @{/path/to/}backlight_service
to the /etc/xdg/lxsession/LXDE-pi/autostart file or to the file .config/lxsession/LXDE-pi/autostart in the user's home directory to automatically start the backlight_service executable when the desktop starts. See Configure an X Program to Auto-Start for more information.
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.
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 // CPi-A & CPi-B // #define PIN 44 // CPi-C 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; }
g++ main.cpp -lpigpiod_if2 -lpthread -o backlight
To cause the backlight to turn OFF after 60 seconds.
backlight 60
[Unit] Description=backlight service After=pigpio.service [Service] ExecStart={path/to/}backlight 60 Restart=always [Install] WantedBy=multi-user.target
Backlight dimming can be controlled using the PWM on GPIO31 on the CPi-A & CPi-B or GPIO26 on the CPi-C. 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 // CPi-A & CPi-B // #define PIN 26 // CPi-C int main(int argc, char *argv[]) { int value = stoi(argv[1]); auto instance = pigpio_start(NULL, NULL); set_mode(instance, PIN, PI_OUTPUT); 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
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.
Hardware revision v2.1 connects the backlight to GPIO 31 which supports PWM. See Dimming the Backlight.