This is a little program I threw together to help evaluate different OLED displays and GUI layouts for them. Internally, it's comprised of 1 external widget and 3 of my own:
- QLedMatrix: I briefly contemplated writing my own widget to emulate the actual LED display, but thanks to a quick search I found one already written for me. Actually, I think the author, Pierre-Etienne Messier, did an amazing job! :-)
- SSD1306: A simulation of the OLED controller by the same name. This wraps Pierre-Etienne's QLedMatrix with the same interface as the real thing (see lines 46 thru 48). Unlike the real thing, you can resize the display dynamically at run-time. In the future I'd actually extend this model to include various timing and output features of the real controller, such as updating the pixels at the actual "clock-rate" and generating the "frame" signal for synchronizing writes to the device. (Hrm... I suppose I could even simulate the clock-rate of the SPI bus... hehe ;-)
- Graphics: Not wanting to draw just a single static bitmap to the display, I chose to implement a very basic (and very inefficient) graphics library. The library works directly on the same image format as the SSD1306's internal GDDRAM: each byte of a page corresponds to the 8 bit rows at that particular column. I implement the minimum set of operations I felt I would need to make a useful UI: Fill, Rect, Line, Arc and a convenience "Tab" function.
- Font_info: Shortly after completing the Tab function, I realized my UI would useless without some kind of font support ;-) I used Font Builder to convert some free fonts into rasterized images. This also generates an XML description file that lists all of the important metrics for each character of the font. I wrote a quick program to convert the png and XML of each font into a C source/header pair (encoded in the same format the graphics lib works on).
I'd really like to make the SSD1306 simulation a bit more realistic, and most importantly make it work asynchronously from the main Qt thread. Right now the entire interface locks up while the fairly lengthy process of rendering the scene entirely through setPixel() calls, then transfering the 1k (8 pages of 128 columns) of memory, 1 byte at a time, and finally rendering the individual pixels one at a time. On my reasonably powerful laptop (2x Core-i7), this takes a noticeable amount of time. Another thought I had, was to maybe split the display and user-inter code in to separate processes connected via IPC mechanism. I could then re-compile and re-run the user logic while keeping the display on and active.
Certainly, the next thing I'll probably actually work on is getting the MainWindow class to remember the selected options when you restart the program. ;-)
Building it yourself
- Git: Version 1.8.4 or newer (possibly older, when ever they introduced submodule support)
- Qt: Version 4.8 or newer (AFIK, I've done nothing incompatible with 5.x)
git clone https://github.com/jnwatts/QtLedTest.git cd QtLedTest git submodule init git submodule update cd QLedMatrix qmake && make -j4 cd ../ qmake && make -j4
Running the program
Unless you manually copy QLedMatrix/build/libqledmatrix.so to somewhere in your library path (/usr/local/lib perhaps?), you'll need to prefix the command with LD_LIBRARY_PATH: