Screen saver advice on Linux with lvgl

Screen saver implementation

What MCU/Processor/Board and compiler are you using?

Ubuntu on Raspberry pi 2

What LVGL version are you using?


What do you want to achieve?

Ability to blank out touch screen on inactivity and wake up on touch

What have you tried so far?

Considering my application is running on Linux directly painting into the framebuffer, so far i have tried implementing my own screen saver mostly on the Linux system level using setterm blanking:

  • Tty using setterm is configured to blank the screen after let’s say 1 min
  • I have a script that monitors events coming from the touch screen that un-blanks the screen when touch is detected

This approach mostly works. The issue is that when screen un-blanks lvgl app does not repaint fully, just some part that was ‘touched’. This also presents a UX issue because the ‘wake up’ touch actually may trigger some action on the screen that user is not intending.

So i thought of few options:

  1. find if there s a way to trigger full repaint of the lvgl app - so far no luck . This would solve the repaint problem but would not solve the unintended click of the user on something. I have also implemented a way to send a signal to the application itself on touch, but again not sure if there is a way to force full repaint.

  2. use lvgl’s inactivity detection and cover the screen with a semi transparent overlay a bit before when the screen gets blanked out. This way, when the screen is touched there is only one action on the screen - click on the overlay, removing which will also repaint the whole screen. ← solves both problems: repaint and unintended actions

Wondering if there are other ways of doing it? Has anyone tried doing screen saver with a similar hardware+ OS setup ? Or may anyone has any other advice.

Thanks in advance

Another (better?) idea I have is to use my app to drive the screensaver.

Something along these lines:

  • use lv_disp_get_inactive_time to detect inactivity
  • when inactivity is detected paint semi-transparent overlay over the screen and note that time
  • in X number of seconds if is still in inactive mode - execute the system call to power down the screen
  • add a hook to evdev touch screen callback to unblank the screen and remove inactivity overlay if already inactive and screen off. If touch happens within those X seconds after inactivity is detected, but the screen is still ON - just remove the overlay.

it’s actually pretty easy to do. You would need to make a custom indev callback routine to capture touch input. This would globally catch any touch input and you would be able to decide if the touch gets forwarded to LVGL or not. That would handle the touch issues. That blanking of the display is pretty easy as well. create an object and set it to have black as the background color. Hide this object. during inactive times unhide the object and set it as the top most object. when touch comes in hide the object and set it as the bottom most object. You would make the size of the object the same size as your display.

Thanks @kdschlosser for your suggestion.

What I ended up doing was to modify my timer loop in the main to check for inactivity and push the semi-transparent overlay screen over my application. Then, in a few seconds, the screen is ‘blanked out’ using setterm - system blanking actually takes care of shutting down the backlight of the LCD which is a great benefit that would not be available with a black screen-large element. On touch, the LVGL automatically detects ‘activity’ and the next loop iteration in main triggers the reverse process for the above.

Works very well. The overlay approach also signals to the user that the device is soon to go to the ‘sleep’ mode, similar to many other devices that behave same way.

Next, I will be adding more to the sleep to stop spinning the timer loop until a new touch event happens and that’s when intercepting the actual touch even will be very useful.

Again, thanks for your prompt response and suggestions.

some touch panels have an interrupt pin. That you would be able to use to reactivate the loop.