The driver makes use of a modified copy of Blake Felt's ESP32 Websocket to provide a bare bones web server and websocket implementation running on top of the lwip netconn API. I rewrote the websocket send function eliminating a pair of data copies to improve performance. The driver serves a simple HTML page that is a wrapper for a canvas and a javascript program that manages the websocket.
The browser connects to the ESP32 and requests a webpage at "/". The html web page file is stored as a binary section in the program code and returned to the browser by the web driver. The web driver is also capable of uploading a stored favicon file (not shown) and transferring communication to the websocket driver when the web page starts running and requests a websocket connection.
LittlevGL's driver architecture is very simple. To render it hands the driver a region of pixels (width, height and 2-d pixel array). To get input it requests pointer location (x, y) and a flag indicating if the pointer is down/touching or has just been released. The lvgl driver simply packages outgoing data for rendering by the javascript on the webpage and receives incoming data from the javascript with pointer information. It supports 8-, 16- and 32-bit pixels (RGB332, RGB565 or RGBA8888).
It makes use of the old javascript mouse events as well as the newer pointer events that are supposed to handle touch on mobile devices. However the current javascript implementation has some issues on mobile because the mobil browser is also interpreting touch for things like scrolling and zoom. They manifest when trying to pass gestures back to LittlevGL. Things like button presses work just fine. It sometimes works to hold a touch for 0.3 second before moving. Clearly more work has to be done here.
The driver can support multiple simultaneous connections (currently 4) with some performance loss as it has to send the same data to multiple browsers.
Speaking of performance...
As one might image, it depends completely on how much of the screen has to be updated. LittlevGL is good about only requesting updates for regions that have changed (for example a button pressed or text added somewhere). Performance for small updates like this is great. The interface feels very responsive.
Eight-bit pixels require one byte per pixel while 32-bit pixels require 4, a factor of 4 slow-down. This means that updating large areas, for example if there is a background image or if an animation is moving a control across the screen, can get very slow, especially for larger pixel depths. The LittlevGL demo application has the option of including a background image. That really slowed things down. I found that turning it off and limiting the pixel depth to 16-bits resulted in reasonable performance, with slowdown as the animator slid the entire display right or left between tabs (turning this off is better).
I think this driver would be very useful for GUIs that didn't do a lot of animation. Typical control panels with buttons, sliders, text areas and the like should be fine. Sixteen-bit pixels result in good images but if you can constrain yourself to the 256 afforded by 8-bit pixels then you can improve performance quite a bit.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.