Using an Android device with KlipperScreen

By | October 30, 2021

I've been fascinated with the prospect of having a beautiful screen for my 3D printers using Klipper by way of the KlipperScreen project. My only delay has been getting screens... for whatever reason, I haven't been able to decide what I want and how I want to implement it.

I had a spare old Google Nexus (circa 2012) laying around and ran into JHS' [How To] KlipperScreen on Android Smart Phones on Discourse so I decided to give a go at it. JHS did a good job pointing to the right components and what needed to be done so I'd like to build on that by providing some additional details for those who may not be familiar.

Here's the overall process (and I'll update it with more details once I've had a chance to do the other builds):

  1. Install KlipperScreen using KIAUH (or manually, if you're not lazy like me)
  2. Install ADB on the Raspberry Pi
  3. Place your Android phone in Debug mode
  4. Plug in the phone
  5. Create a UDEV rule for the device:
    https://stackoverflow.com/questions/53887322/adb-devices-no-permissions-user-in-plugdev-group-are-your-udev-rules-wrong
  6. Download version 1.11.40 of XSDL (if you're using an older phone) and place the APK file on your Raspberry Pi:
    https://sourceforge.net/projects/libsdl-android/files/apk/XServer-XSDL/
  7. Install the file on your Android:
    adb install XServer-XSDL-1.11.40.apk
  8. Create a launch script for your service, I called mine launch_klipperscreen.sh and placed it in the same directory as KlipperScreen:
    #!/bin/bash
    # forward local display :100 to remote display :0
    adb forward tcp:6100 tcp:6000
    
    adb shell dumpsys nfc | grep 'mScreenState=' | grep OFF_LOCKED > /dev/null 2>&1
    if [ $? -lt 1 ]
    then
    echo "Screen is OFF and Locked. Turning screen on..."
    adb shell input keyevent 26
    fi
    
    adb shell dumpsys nfc | grep 'mScreenState=' | grep ON_LOCKED> /dev/null 2>&1
    if [ $? -lt 1 ]
    then
    echo "Screen is Locked. Unlocking..."
    adb shell input keyevent 82
    fi
    
    # start xsdl
    adb shell am start x.org.server/.MainActivity
    
    ret=1
    timeout=0
    echo -n "Waiting for x-server to be ready "
    while [ $ret -gt 0 ] && [ $timeout -lt 60 ]
    do
    xset -display :100 -dpms s off -q > /dev/null 2>&1
    ret=$?
    timeout=$( expr $timeout + 1 )
    echo -n "."
    sleep 1
    done
    echo ""
    if [ $timeout -lt 60 ]
    then
    DISPLAY=:100 /home/pi/.KlipperScreen-env/bin/python screen.py
    exit 0
    else
    exit 1
    fi
  9. Make it executable:
    chmod 755 launch_klipperscreen.sh
  10. Modify your service startup script:
    sudo nano /etc/systemd/system/KlipperScreen.service

    It should read:

    [Unit]
    Description=KlipperScreen
    After=moonraker.service
    StartLimitIntervalSec=0
    
    [Service]
    Type=simple
    Restart=always
    RestartSec=1
    User=pi
    WorkingDirectory=/home/pi/KlipperScreen
    ExecStart=/home/pi/KlipperScreen/launch_klipperscreen.sh
    
    [Install]
    WantedBy=multi-user.target
  11. Reload the daemons:
    sudo systemctl daemon-reload
  12. Start the service:
    sudo service KlipperScreen start
  13. Reboot the Android (you don't have to but I like to just to clean things up):
    adb reboot
  14. Now, you may have to play with some of the configuration in XSDL (done on startup of the app) to tweak things to your liking. If you want touch to work, you'll need to use Desktop emulation for the mouse.