For some time I have been playing with different sensors on the Raspbarry Pi. While it is still fun (and gives me the playground for different programming tasks), I now felt it was time to see some output not only on my remote screen, but directly on the breadboard. So, I ordered a 1.8 inch display with the famous SPI ST7735 chip controller.
Unfortunately the documentation is very thin and most of the setups only target Arduino. So, what follows is the result of my little journey to hook up the 1.8 TFT display with my Raspberry Pi.
Pinout
First, it might help to see what board I have. Here is what the command pinout
gave me for my system:
,--------------------------------.
| oooooooooooooooooooo J8 +====
| 1ooooooooooooooooooo | USB
| +====
| Pi Model 3B V1.2 |
| +----+ +====
| |D| |SoC | | USB
| |S| | | +====
| |I| +----+ |
| |C| +======
| |S| | Net
| pwr |HDMI| |I||A| +======
`-| |--------| |----|V|-------'
Revision : a02082
SoC : BCM2837
RAM : 1024Mb
Storage : MicroSD
USB ports : 4 (excluding power)
Ethernet ports : 1
Wi-fi : True
Bluetooth : True
Camera ports (CSI) : 1
Display ports (DSI): 1
J8:
3V3 (1) (2) 5V
GPIO2 (3) (4) 5V
GPIO3 (5) (6) GND
GPIO4 (7) (8) GPIO14
GND (9) (10) GPIO15
GPIO17 (11) (12) GPIO18
GPIO27 (13) (14) GND
GPIO22 (15) (16) GPIO23
3V3 (17) (18) GPIO24
GPIO10 (19) (20) GND
GPIO9 (21) (22) GPIO25
GPIO11 (23) (24) GPIO8
GND (25) (26) GPIO7
GPIO0 (27) (28) GPIO1
GPIO5 (29) (30) GND
GPIO6 (31) (32) GPIO12
GPIO13 (33) (34) GND
GPIO19 (35) (36) GPIO16
GPIO26 (37) (38) GPIO20
GND (39) (40) GPIO21
Wireing
The TFT display I use has 8 connectors. Here is a table with their names, mapped GPIO and some additional infos:
ID | Pin name | GPIO | SPI0 | FB |
---|---|---|---|---|
1 | VCC | 5V | ||
2 | GND | GND | ||
3 | CS | 8 | CE0 | |
4 | RESET | 25 | reset | |
5 | A0 / RS | 24 | dc | |
6 | SDA | 10 | MOSI | |
7 | SCK | 11 | SCLK | |
8 | LED | 23 | led |
Pins 2,3 and 6 will be used by SPI. Pins 1,4 and 5 will be used by the frame buffer (fb) driver. Finally, pins 7 and 8 will be used for the power supply.
Note that pin 5 may have different labels. On one TFT display it was labeled as A0
, on another it is labeled RS
.
Make sure you connect all SPI pins to the same bus (in this example 0). If you check the GPIO layout on https://pinout.xyz/pinout/spi you will see that there are actually two SPI channels available. With the mapping above, all will be connected to SPI0.
When you have wired your display, you will also have to enable SPI through raspi-config
. Then restart your system.
Driver setup
Finally you have to load the driver as a kernel module. According to the above mapping, you have to load the kernel module like this:
sudo modprobe fbtft_device name=adafruit18 gpios=reset:25,dc:24,led:23
There are a lot more parameters available to fbtft_device
. To see all of them, run: modinfo fbtft_device
. For additional information check https://github.com/notro/fbtft/wiki/fbtft_device#parameters. For instance the requiredled
part in the gpios
parameter is missing from the module description of fbtft_device
.
Now, run dmsg
and check the last line. It should look something like this:
[ 7956.283381] graphics fb1: fb_st7735r frame buffer, 160x128, 40 KiB video memory, 4 KiB buffer memory, fps=20, spi0.0 at 32 MHz
graphics fb1
tells you that you will have to use /dev/fb1
to access the display.
If you have a Pi 3 run the following command to try it out:
con2fbmap 1 1
The first number denotes the console, e.g. tty1
. The second number denotes the frame buffer. If all works well, you should now see a login screen on your little TFT display.
On a Pi 4 it should automatically connect the console.
Running JavaFX
I’ve also tried to run a simple JavaFX application on the display with OpenJFX. Here is what I had to run:
java -Dprism.order=sw -Dmonocle.screen.fb=/dev/fb1 -jar testapp.jar
Because we cannot use hardware acceleration, we have to fallback to the software rendering pipeline. JavaFX will always give precedence to hardware acceleration. And though I’ve explicitly specified to use /de/fb1
, without -Dprism.order=sw
any output would still be routed to /dev/fb0
. So, we either have to mirror fb0 or explicitly use software rendering.
On the Pi 4 you can also disable the dtoverlay vc4-fkms-v3d
in /boot/config.txt
and drop -Dprism.order=sw
.
If you ran con2fbmap 1 1
prior to the execution of your JavaFX application (or when using a Pi 4), you might see a blinking cursor on your display. That is because the console and your JavaFX application now share the same frame buffer. Assuming console 1 is mapped to frame buffer 1, executing the command con2fmap 1
should display:
console 1 is mapped to framebuffer 1
To disconnect console 1 from framebuffer 1 run the following command:
echo 0 > /sys/class/vtconsole/vtcon1/bind
This should disable the console. You can verify this with con2fmap 1
which should now display:
console 1 is mapped to framebuffer -1
More information can be found in the kernel documentation: