For many displays, including SPI based ones, the Linux kernel offers direct support in form of framebuffer devices. Often the displays will be auto-detected without configuration. (Check here for a list of supported displays.)
The devices are named /dev/fbX
and have a unified API. This means you do have to deal with the details of the driver chip. When programming in Python the performance will likely be better too.
A framebuffer
device (/dev/fb0
) is also associated with the Pi’s HDMI port whether a display is attached or not. The first additional displays will hence be accessed as /dev/fb1
.
In order to present a uniform abstraction the framebuffer device will only support a subset of the features of the display, e.g.
Also, the number of ways of connecting the display may be restricted. For SPI based devices usually only a few a standard pin configurations are used (cf. drivers).
Sometimes the system will auto detect the wrong display and then continue to load the wrong kernel driver module. Always check whether the output of
fbset --info ... # see below
matches the description of the display. If there is a mismatch it can often be remedied by loading the proper kernel driver module with this command:
$ sudo modprobe <module> <arg1> <arg2> ..
# e.g.:
# sudo modprobe fbtft_device custom name=fb_sh1106 debug=1 speed=2000000 gpios=reset:25,dc:24
Many tools and games work with framebuffer devices out of the box. Here we highlight a few of them.
$ cat /dev/urandom > /dev/fb1
fbset
1 is a handy tool for display info and changing setting of the framebuffer.
Examples:
$ fbset -fb /dev/fb1 --info
# show current resolution, color depth, etc
This is part of the Pytorinox Python Library
Run it like so
$ ./fbi.py /dev/fb1 <png-jpeg-or-other-image>
The code for fbi.py is very short and worth studying.
using spi pin-config-1
dtparam=spi=on
dtoverlay=sh1106-spi,speed=2000000
Use mplayer2 to view the movie stored in test.mpg like so:
mplayer -nolirc -vo fbdev2:/dev/fb1 test.mpg
Use vlc-nox3 to view the movie stored in test.mpg like so:
TBD
/dev/fb1
The Pi’s GPU can only be used in conjunction with /dev/fb0
. To utilize GPU acceleration for /dev/fb1
a common approach is:
/dev/fb0
to have the same resolution as /dev/fb1
/dev/fb0
/dev/fb0
to /dev/fb1
from PIL import Image, ImageDraw
from framebuffer import Framebuffer # pytorinox
fb = Framebuffer(1) # for /dev/fb1
buffer = Image.new(mode="RGB", size=fb.size)
draw = ImageDraw.Draw(buffer)
cx = fb.size[0] // 2
cy = fb.size[1] // 2
draw.rectangle((cx - 10, cy -10, cx + 10, cy + 10), "white")
fb.show(buffer)
especially useful: fbtft_device.c