ashley.geek.nz

This article was on my old WordPress blog (and I linked to it in the GoodTFT repo), which died a horrible death when my Azure subscription was deleted. That's a story for another time, but while I figure out what I'm going to do for my website moving forward, I thought I'd quickly spin this article back up to help those who might need it.

Thanks to the web.archive.org for being the easiest way for me to do that. Nobody wants to be messing around with WordPress backups...

Happy tinkering!

Dual screen on a Raspberry Pi with HDMI and GoodTFT GPIO touchscreens

Posted May 2, 2020 by in technical resources


The standard installer for the GoodTFT touchscreens steamrolls any existing configurations you have, and perfectly sets you up for only itself. And in a pretty hack way, too: it modifies all sorts of system files without any care for existing system configuration. If all you’d like to do is add the screen to an existing screen topology, then the provided installation script isn’t for you.

Through fiddling, I’ve managed to get the RPi to continue to output over HDMI whilst also powering up this cheap little screen. I pulled apart their installation script line-by-line to see what it did. That left me with the below steps, which hopefully should help you to getting dual screen with a Raspberry Pi 3 B+ (I haven’t tested any other model, but I imagine it should work).

I’m by no means a Linux Admin, nor do I understand Raspberry Pi hardware or the ‘overlays’. I’ve simply taken concepts I do know, and extrapolated them to reverse engineering their installation script for the useful parts.

 

Here be dragons, etc. Please make sure you have a backup of your Raspberry Pi should the steps not work out well for you.

 

Copying files and preparing

  1. Hopefully you’re not running an old copy of Raspbian, but update just in case:
    sudo apt update && sudo apt upgrade -VV
  2. Clone the GoodTFT repo
    We will still need some files from the original GoodTFT code, so make sure to clone their repository to a useful place. I normally use a non-convential ‘shared’ directory in root, coz I’m a rebel:

    1. sudo mkdir -p /shared/
    2. sudo chown :adm /shared
    3. sudo chmod g+w /shared
    4. cd /shared/
    5. git clone https://github.com/goodtft/LCD-show.git
    6. cd LCD-show
  3. Copy screen overlay files
    Now we need to copy the overlay files. The below steps are for the LCD35 or TFT35a, which is what I have. If you don’t have this screen and you don’t know which file(s) to copy, open up the .sh installation script for your screen, and search for ‘dtb’; or post a comment and I’ll see if I can find it

    1. Copy the relevant ‘-overlay.dtb’ file for your screen (mine is ‘LCD35’ or ‘TFT35a’ into /boot/overlays/
      1. For example: sudo cp ./usr/tft35a-overlay.dtb /boot/overlays/
    2. I’m uncertain if this bit is necessary, but it didn’t seem to cause issues to do so; copy the same file again but with a different filename; I only know what this is supposed to be for the tft35 screen, but I would assume the format will be the same; take the -overlay off, and add an ‘o’ to the filename
      1. For example: sudo cp ./usr/tft35a-overlay.dtb /boot/overlays/tft35a.dtbo
  4. Calculate the rotation that the add-on screen will need
    Here is a bash script formula for the LCD35 screen which will orient the screen such that the GPIO pins are along the bottom edge.
    LCD35_default_rotation=90
    desired_rotation=180
    new_rotate_value=$((($LCD35_default_rotation + $desired_rotation) % 360))

    1. You may instead just need to do trial and error if your screen isn’t this variety
  5. Install evdev library
    The touchscreen doesn’t work properly with the already installed libraries, so we need to install ‘evdev’

    sudo apt-get install xserver-xorg-input-evdev
  6. Touchscreen calibration file
    In order for the touchscreen to be calibrated properly, you need to copy the ‘calibration’ configuration file into the Xorg directory. Which configuration you copy depends on the rotation value you calculated above.

    1. For example: My new_rotate_value comes out as 270, so I need to copy the 99-calibration file for the ’35’ tft which equates to:
      sudo cp -rf ./usr/99-calibration.conf-35-270 /usr/share/X11/xorg.conf.d/99-calibration.conf
  7. Override the default InputClass driver, with evdev
    Now open that file (eg, /usr/share/X11/xorg.conf.d/99-calibration.conf) and add:
    Driver          “evdev”
    …somewhere within the InputClass Section
  8. At this point we’ve done all we can before actually changing settings on the Raspberry Pi to start taking advantage of the new hardware

Configure Raspberry Pi boot process and X server

  1. Run raspi-config to enable I2C and SPI from the Interfaces menu, if you haven’t already
  2. Edit /boot/cmdline.txt and remove:
    console=serial0,115200

    This is so the Raspberry Pi isn’t trying to start a serial console on some of the GPIO pins used by the screen

  3. Edit /boot/config.txt
    The following needs to match the name of the overlay file you added in the prep (without the -overlay part) and the rotation value you calculated earlier; edit the comment to match the model of your screen, so that you know what this is all about in the future. Finally, we enable UART for communication with the screen over GPIO.

    # Added for goodtft MPI3501 / LCD35
        dtoverlay=tft35a:rotate=270
        enable_uart=1
  4. Restart the Raspberry Pi
    This will load up the overlay and enable us to connect to the screen, but not actually use it yet
  5. Check if there is now another framebuffer device
    ls /dev/fb*

    You should now have a /dev/fb0 (HDMI) and /dev/fb1 (touchscreen)

  6. Update 99-fbturbo.conf to add the framebuffer output device
    Add this, below the existing Device section:

    Section "Device"
        Identifier "Goodtft"
        Driver "fbturbo"
        Option "fbdev" "/dev/fb1"
        Option "SwapbuffersWait" "true"
        EndSection
  7. Update 99-fbturbo.conf to depict your screen layout
        I positioned my Raspberry Pi screen physically below the TV on the HDMI, so the following configuration file takes that into account. You'll need to take a look at the documentation if you want something else
        Section "Screen"
        Identifier "TV"
        Device "Allwinner A10/A13 FBDEV"
        Monitor "Monitor name 0"
        EndSection
        
        Section "Screen"
        Identifier "TouchScreen"
        Device "Goodtft"
        Monitor "Monitor name 1"
        EndSection
        
        Section "ServerLayout"
        Identifier "Default Layout"
        Screen 0 "TV"
        Screen 1 "TouchScreen" Below "TV"
        EndSection
  8. Calculate the Transformation Matrix for the touchscreen that takes into account your existing screens.
    You can use this Google Sheet (which I can’t find the original source that I pilfered it from, sorry!). I ended up with the following. All I need is the string of numbers at the end:

    xinput set-prop 'ADS7846 Touchscreen' --type=float 'Coordinate Transformation Matrix' 0.444444444444444 0 0 0 0.142857142857143 0.857142857142857 0 0 1
  9. Add the transformation matrix to the calibration configuration file (/usr/share/X11/xorg.conf.d/99-calibration.conf)
    I added the following for mine in the Section InputClass, based on the output from the last step

    Option "TransformationMatrix "0.444444444444444 0 0 0 0.142857142857143 0.857142857142857 0 0 1"
  10. Now, you should just be able to restart your window manager, and boom; two screens!
    sudo systemctl restart lightdm

 

I found that I couldn’t easily move windows between each screen, I had to explicitly start them where I wanted them. You can do that from the terminal using:

DISPLAY=:0.1 chromium-browser https://ashley.geek.nz

Where the number after the dot, designates the second screen, which for my configuration is the touchscreen, since it is ‘Below’ the TV.