Running Volumio 2 on a Raspberry Pi 2 model B with a 3.5" Touchscreen

I was pleasantly surprised with how well Volumio 2 runs out of the box on my old Raspberry Pi 2 model B using an external USB DAC (in my case, Behringer UCA222). As a next step, I wanted to add a small 3.5 inch display that connects to the 26 GPIO pins of my Pi 2 B.

The setup of the 3.5" LCD screen is a bit tougher than expected, but after a lot of googling and trial and error I got the LCD touchscreen fully working with Volumio 2. It seems like the same display is sold under different brands.

These are the steps to get the display working:
  • connect to your Raspberry Pi CLI through ssh (username: volumio; password: volumio) and execute the following commands
    • download the display driver:
      git clone https://github.com/goodtft/LCD-show
    • run these few commands (handpicked from the LCD35-show script -- do NOT run the script!):
      cd LCD-show/
      sudo mkdir /etc/X11/xorg.conf.d
      sudo cp ./usr/tft35a-overlay.dtb /boot/overlays/
      sudo cp ./usr/tft35a-overlay.dtb /boot/overlays/tft35a.dtbo
      sudo cp -rf ./usr/99-calibration.conf-35-90  /etc/X11/xorg.conf.d/99-calibration.conf
      sudo mkdir -p /usr/share/X11/xorg.conf.d/
      sudo cp -rf ./usr/99-fbturbo.conf  /usr/share/X11/xorg.conf.d/
    • modify the 99-calibration.conf file and add the Driver "evdev" option
      • sudo nano /etc/X11/xorg.conf.d/99-calibration.conf
      • the file should be:
        Section "InputClass"
          Identifier "calibration"
          MatchProduct "ADS7846 Touchscreen"
          Option "Calibration" "3936 227 268 3880"
          Option "SwapAxes" "1"
          Driver "evdev"
      • save the file (Control-X)
    • create a new /boot/userconfig.txt (2020-05 update: this file is automatically included in  /boot/config.txt by Volumio)
      • sudo nano /boot/userconfig.txt
      • add the single line:
      • save the file (Control-X)
    • install missing packages:
      • sudo apt update
      • sudo apt install lightdm
      • sudo apt install xserver-xorg-input-evdev
    • fix the autologin user for lightdm (updated 2020-05)
      • sudo nano /etc/lightdm/lightdm.conf
      • modify the "autologin" user from "pi" to "volumio":
      • save the file (Control-X)
After a reboot, everything works fine :). 

The final product is functional, but not perfect: the boot time takes a few minutes and chromium in kiosk mode is not very snappy. This might be a limitation of the older Raspberry Pi hardware. But as a simple display and for basic pause/play interaction, it works.

You can optionally disable the sleep mode and change the orientation of display in the Touch Display Plugin settings:

The "classic" layout (settings > appearance) seems to work out a bit cleaner on a small display:



Zach said...

I used this method of yours last month and it was working fine.

I attempted to follow your updated instructions and use the previous Volumio image, unfortunately it no longer works.

Michaël said...

some ideas:
- make sure to backup your sd-card before any change / update
- before applying the LCD-specific config, validate that Volumio is fully working with an hdmi screen plugged in.
- I added the full /boot/config.txt contents
- compare the output from your working setup and the broken one:
- sudo lsmod
fb_ili9486 3213 1
fbtft 32647 1 fb_ili9486
ads7846 13075 0
syscopyarea 3161 1 fbtft
sysfillrect 3716 1 fbtft
sysimgblt 2422 1 fbtft
fb_sys_fops 1677 1 fbtft
- dmesg
[ 19.777376] ads7846 spi0.1: touchscreen, irq 177
[ 19.787946] input: ADS7846 Touchscreen as /devices/platform/soc/20204000.spi/spi_master/spi0/spi0.1/input/input3
[ 19.971009] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[ 20.352359] fb_ili9486: module is from the staging directory, the quality is unknown, you have been warned.
[ 20.353534] fbtft_of_value: regwidth = 16
[ 20.353551] fbtft_of_value: buswidth = 8
[ 20.353564] fbtft_of_value: debug = 0
[ 20.353571] fbtft_of_value: rotate = 90
[ 20.353578] fbtft_of_value: fps = 30
[ 20.353586] fbtft_of_value: txbuflen = 32768
- contents /var/log/Xorg*log should contain:
[ 78.217] (II) FBTURBO(0): hardware: fb_ili9486 (video memory: 300kB)
[ 78.217] (**) FBTURBO(0): Option "fbdev" "/dev/fb1"

Zach said...

Thanks Michael for your quick response:

Here are my outputs:

evdev 24576 1
ads7846 20480 0
fb_ili9486 16384 2
fbtft 45056 1 fb_ili9486
syscopyarea 16384 1 fbtft
sysfillrect 16384 1 fbtft
sysimgblt 16384 1 fbtft
hwmon 16384 1 ads7846
fb_sys_fops 16384 1 fbtft

[ 10.826388] snd_bcm2835: module is from the staging directory, the quality is unknown, you have been warned.
[ 10.827632] snd_bcm2835: unknown parameter 'index' ignored
[ 10.834071] bcm2835_alsa bcm2835_alsa: card created with 8 channels
[ 11.043016] snd-rpi-hifiberry-dacplus soc:sound: ASoC: CODEC DAI pcm512x-hifi not registered - will retry
[ 11.221343] fbtft: module is from the staging directory, the quality is unknown, you have been warned.
[ 11.231581] snd-rpi-hifiberry-dacplus soc:sound: ASoC: CODEC DAI pcm512x-hifi not registered - will retry
[ 11.232023] brcmfmac: F1 signature read @0x18000000=0x15264345
[ 11.243028] fb_ili9486: module is from the staging directory, the quality is unknown, you have been warned.
[ 11.243905] fbtft_of_value: regwidth = 16
[ 11.243917] fbtft_of_value: buswidth = 8
[ 11.243925] fbtft_of_value: debug = 0
[ 11.243932] fbtft_of_value: rotate = 90
[ 11.243939] fbtft_of_value: fps = 30
[ 11.243946] fbtft_of_value: txbuflen = 32768
[ 11.252139] brcmfmac: brcmf_fw_map_chip_to_name: using brcm/brcmfmac43455-sdio.bin for chip 0x004345(17221) rev 0x000006
[ 11.252567] usbcore: registered new interface driver brcmfmac
[ 11.254386] snd-rpi-hifiberry-dacplus soc:sound: ASoC: CODEC DAI pcm512x-hifi not registered - will retry
[ 11.443050] snd-rpi-hifiberry-dacplus soc:sound: pcm512x-hifi <-> 3f203000.i2s mapping ok
[ 11.725752] random: crng init done
[ 11.725774] random: 7 urandom warning(s) missed due to ratelimiting
[ 11.802078] brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: Feb 27 2018 03:15:32 version 7.45.154 (r684107 CY) FWID 01-4fbe0b04
[ 11.802699] brcmfmac: brcmf_c_preinit_dcmds: CLM version = API: 12.2 Data: 9.10.105 Compiler: 1.29.4 ClmImport: 1.36.3 Creation: 2018-03-09 18:56:28
[ 11.808184] systemd-journald[167]: Received request to flush runtime journal from PID 1
[ 11.935844] graphics fb1: fb_ili9486 frame buffer, 480x320, 300 KiB video memory, 32 KiB buffer memory, fps=33, spi0.0 at 16 MHz
[ 11.936812] ads7846 spi0.1: spi0.1 supply vcc not found, using dummy regulator
[ 11.937400] ads7846 spi0.1: touchscreen, irq 170
[ 11.937990] input: ADS7846 Touchscreen as /devices/platform/soc/3f204000.spi/spi_master/spi0/spi0.1/input/input0
[ 12.178539] brcmfmac: power management disabled
[ 13.114607] brcmfmac: power management disabled
[ 13.921990] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).
[ 14.384618] ip_tables: (C) 2000-2006 Netfilter Core Team
[ 14.515992] nf_conntrack version 0.5.0 (14336 buckets, 57344 max)
[ 20.891589] brcmfmac: power management disabled
[ 35.351953] Under-voltage detected! (0x00050005)
[ 43.671805] Voltage normalised (0x00000000)

zach said...

this is what I got for the xorg log

[ 16.691] (II) FBTURBO(0): if this is wrong and needs to be fixed, please check ./configure log
[ 16.696] (==) RandR enabled
[ 16.731] (II) SELinux: Disabled on system
[ 16.749] (II) AIGLX: Screen 0 is not DRI2 capable
[ 16.749] (EE) AIGLX: reverting to software rendering
[ 18.470] (II) AIGLX: enabled GLX_MESA_copy_sub_buffer
[ 18.471] (II) AIGLX: Loaded and initialized swrast
[ 18.471] (II) GLX: Initialized DRISWRAST GL provider for screen 0
[ 18.853] (II) config/udev: Adding input device ADS7846 Touchscreen (/dev/input/event0)
[ 18.853] (**) ADS7846 Touchscreen: Applying InputClass "evdev touchscreen catchall"
[ 18.853] (**) ADS7846 Touchscreen: Applying InputClass "libinput touchscreen catchall"
[ 18.853] (**) ADS7846 Touchscreen: Applying InputClass "calibration"
[ 18.853] (II) LoadModule: "evdev"
[ 18.854] (II) Loading /usr/lib/xorg/modules/input/evdev_drv.so
[ 18.891] (II) Module evdev: vendor="X.Org Foundation"
[ 18.891] compiled for 1.18.4, module version = 2.10.3
[ 18.891] Module class: X.Org XInput Driver
[ 18.891] ABI class: X.Org XInput driver, version 22.1
[ 18.891] (II) Using input driver 'evdev' for 'ADS7846 Touchscreen'
[ 18.891] (**) ADS7846 Touchscreen: always reports core events
[ 18.891] (**) evdev: ADS7846 Touchscreen: Device: "/dev/input/event0"
[ 18.891] (--) evdev: ADS7846 Touchscreen: Vendor 0 Product 0
[ 18.891] (--) evdev: ADS7846 Touchscreen: Found absolute axes
[ 18.891] (--) evdev: ADS7846 Touchscreen: Found x and y absolute axes
[ 18.892] (--) evdev: ADS7846 Touchscreen: Found absolute touchscreen
[ 18.892] (**) Option "SwapAxes" "1"
[ 18.892] (II) evdev: ADS7846 Touchscreen: Configuring as touchscreen
[ 18.892] (**) evdev: ADS7846 Touchscreen: YAxisMapping: buttons 4 and 5
[ 18.892] (**) evdev: ADS7846 Touchscreen: EmulateWheelButton: 4, EmulateWheelInertia: 10, EmulateWh$
[ 18.892] (**) Option "config_info" "udev:/sys/devices/platform/soc/3f204000.spi/spi_master/spi0/spi$
[ 18.892] (II) XINPUT: Adding extended input device "ADS7846 Touchscreen" (type: TOUCHSCREEN, id 6)
[ 18.892] (II) evdev: ADS7846 Touchscreen: initialized for absolute axes.
[ 18.892] (**) ADS7846 Touchscreen: (accel) keeping acceleration scheme 1
[ 18.892] (**) ADS7846 Touchscreen: (accel) acceleration profile 0
[ 18.892] (**) ADS7846 Touchscreen: (accel) acceleration factor: 2.000
[ 18.892] (**) ADS7846 Touchscreen: (accel) acceleration threshold: 4
[ 18.893] (II) config/udev: Adding input device ADS7846 Touchscreen (/dev/input/mouse0)
[ 18.894] (**) ADS7846 Touchscreen: Applying InputClass "calibration"
[ 18.894] (II) Using input driver 'evdev' for 'ADS7846 Touchscreen'
[ 18.894] (**) ADS7846 Touchscreen: always reports core events
[ 18.894] (**) evdev: ADS7846 Touchscreen: Device: "/dev/input/mouse0"
[ 18.894] (EE) evdev: ADS7846 Touchscreen: Unable to query fd: Inappropriate ioctl for device
[ 19.030] (EE) PreInit returned 2 for "ADS7846 Touchscreen"
[ 19.030] (II) UnloadModule: "evdev"

Let me know if there is something here that I am not seeing.

Thank you!

Michaël said...

Hi Zach,
In your logs I see the following "error":

Under-voltage detected! (0x00050005)

Might indicate an issue with your USB Power. Definitely try with another power source

Other than that, I'm afraid I'm out of ideas. It seems like you're using a more recent Raspberry Pi (Model 3?). Might be that I'm more lucky with the "Raspberry Pi Model B Rev 2" ?

You could also try to setup a bare bone raspbian with LCD and try to compare what config might make a difference? (e.g. /boot/config.txt).


zach said...

Thank your for your help, but unfortunately after 43 separate installs from scratch, it is a complete failure.

I am starting to believe that there is more to it than the script you have provided, as I have looked elsewhere and have not been able to get it running.

It doesn't even detect the device from the drivers.

Michaël said...

hi zach,

some questions
- did you test with other power adapters?
- are you using a rpi 3?
- did you try plain raspbian
- did you try with another older volumio instance? https://volumio.org/forum/older-volumio-versions-img-files-t7009.html

from your logs (Xorg), it seems like the screen is OK?

Anyway, i'm afraid i'm out of ideas... i can send you my image to test, contact me on mich dot peeters
at gmail

Matthias said...

Thanks for your howto.
I tried to get my 3.5 touchscreen running with my Pi3 and the volumio plugin, but it didn't work.
Using your howto I managed it but there is a little problem I can not solve.

When using the stylus as input the touchscreen seems to be mirrored. When moving to the right the arrow is pointing to the left. Same with up and down.
How ca I fix this? Is there a way to calibrate the screen?

Also I would like to rotate the screen by 180 degree.
I tried to edit
and add this line:
this didn't do anything.

Do you have any idea?


Michaël said...

hi Matthias,

the stylus input is configured in /etc/X11/xorg.conf.d/99-calibration.conf
check the Calibration and SwapAxes options. Start with the original configuration from github for those items instead of mine.

Matthias said...

Hi Michael,
I will try if that work for me.
I hoped there would be a calibration script.


Michaël said...

Hi Matthias,

I did some experiments last year with calibration scripts, but in my case it wasn't needed, the default settings are ok.

Anyway, you can research it further:

- "xinput-calibrator": sudo apt install xinput-calibrator
see: https://www.raspberrypi.org/forums/viewtopic.php?t=78805
- https://github.com/gamelaster/evdev-calibration

Velkro Smaak said...

Has anyone got the same working for the 5" HDMI Waveshare screen?

Nordlicht said...

Hello is there any advice when I use it with an no hdmi waveshare 2.8 touch?
Display works with volumio but no touch not even with the official waveshare rasp image. Linux and consumer freindly do not compute :-)

Michaël said...

Did you check the resources in https://www.waveshare.com/wiki/2.8inch_RPi_LCD_(A) ? The fact that the original waveshare image is not working might indicate a defective device?

I don't have the device, so that's as far I can help unfortunately.


Anonymous said...

cannot stat' sudo cp -rf ./usr/99-calibration.conf-35 /etc/X11/xorg.conf.d/99-calibration.conf

please help

Mikhail said...

Hello Michaël !

I can't go through the tutorial. I get an error:

cp: cannot stat './usr/99-calibration.conf-35': No such file or directory

Please help me to run the damn display on Volumio or Moode

Cotsios said...


If you are using Raspbian image version 2017-03-02 or later, you need to execute these additional 2 commands below to allow calibration of touch screen. Then reboot the system.

$ cd LCD-show
$ sudo dpkg -i -B xserver-xorg-input-evdev_1%3a2.10.3-1_armhf.deb
$ sudo cp -rf /usr/share/X11/xorg.conf.d/10-evdev.conf /usr/share/X11/xorg.conf.d/45-evdev.conf
$ sudo reboot

Reference: https://github.com/CytronTechnologies/xpt2046-LCD-Driver-for-Raspberry-Pi

siva said...
This comment has been removed by the author.
siva said...

Hello Michaël !

I have successfully installed volumio on RPi 3B+ and 3.5" tft screen on a 16GB sd card.
All works fine.
The only error message I got while installing was

cp: cannot stat './usr/99-calibration.conf-35': No such file or directory

The problem is the file does not exist in the source directory. But I found similar files and copeied one of them and modified in the destination directory.

For the screen to rotate upside down and Touch orientation refer below pdf file :

Everything works as expected.
Now the error im getting on screen is
Error setting screensaver timeout: Error: Command failed: /bin/bash -c "/usr/bin/xset -display :0 s off +dpms 0 0 0" No protocol specified /usr/bin/xset: unable to open display ":0"

We have to find out which is display :0

Thank you Michaël ! You have done a wonderful Job.


vodkacow said...

i have the same display :0 error too.

By the way, thanks for all the work and writing up this guide for everyone!

Michaël said...

can you check out some ideas from: https://www.raspberrypi.org/forums/viewtopic.php?t=180701 ?


Levin said...

First of all, thank you Michael for the nice tutorial!

I was using this little LCD with Volumio before the touch plugin existed, it just needed a bit more work with lightdm and chrome.
Anyway, I had to reinstall my volumio and find your tutorial (shame on me I haven't documented the previous install in a blogpost like you), this makes things easier!

Also faced the error message:
Error setting screensaver timeout: Error: Command failed: /bin/bash -c "/usr/bin/xset -display :0 s off +dpms 0 0 0" No protocol specified /usr/bin/xset: unable to open display ":0"

Where the problem is that lightdm is starting with the user "pi" by default but the touch screen plugin will run on behalf of volumio user who does not have a runing x.
So the solution is to change the autologin user in the lightdm.conf from "pi" to "volumio":
sudo nano /etc/lightdm/lightdm.conf


From this point the xset command called by the plugin will succeed.

Some other remarks:
1. the correct 99calibration.conf copy:
sudo cp -rf ./usr/99-calibration.conf-35-90 /etc/X11/xorg.conf.d/99-calibration.conf
2. After any official update Volumio will overwrite the /boot/config.txt. Or you keep a backup, orr you just add the lines needed again:


Michaël said...

Thanks Levin for your research. I guess volumio / LCD35-show changed since the last time I checked. I'll try to redo a full reconfigure and update the instructions according your tips.


siva said...

Thank you Kevin and Michaël,

Kevin, Your solution for the display:0 error worked very well.

I have tried setting up one more time freshly, but this time without installing lightdm.
And it works well without any error messages.

Also I was using a 250Gb HDD and connected to a local network and it often hanged.
So I made the volumio into hotspot mode and used a pen drive instead of HDD.
Now works without hanging.

Please suggest me any steps to make a player which will have buttons to play/pause, stop, next, previous tracks etc and a rotary encoder to select across tracks and change volume.

Best regards

siva said...

I want to make one like acoosta music player.

Anonymous said...

Wanted to thank you fabulously (!) for posting these details. I have been everywhere (including Volumio, who did a November 2019 post) attempting to get this to work. It all went well, except for one tiny tweak I did because a folder was missing.
In your command:

sudo cp -rf ./usr/99-calibration.conf-35 /etc/X11/xorg.conf.d/99-calibration.conf

I got an error that the /99-calibration.conf-35 folder was missing, but found a 99-calibration.conf-35-0 folder and changed the command to that. Again, thank you; up to this point this was a frustrating experience!

Anonymous said...

FYI, the last comment was run on the latest version of Volumio v.2.729 on a Raspberry Pi 4.

Anonymous said...

@Anonymous (previous post): Which display are you using exactly?
I tried with a Raspberry Pi 4 and Volumio v.2.729 with a "Waveshare 3.5inch RPi LCD (B)". Tried 10 times now without luck.
used "sudo cp -rf ./usr/99-calibration.conf-35-0 /etc/X11/xorg.conf.d/99-calibration.conf" and "sudo cp -rf ./usr/99-calibration.conf-35-90 /etc/X11/xorg.conf.d/99-calibration.conf".

Screen doesn't show anything...

Anonymous said...

Thank you so much for this.

I know you started this thread s-o- long ago, but I am impressed and happy you still come back to it. I truly appreciate it. (Although I have a MHS35 driver and have to be careful to sub mhs35 for tft35 as appropriate).

Of all the guides to getting this to work, I ended up here and it worked for my Pi4B 2GB/Volumio 2.729.

For others late to the game, pay attention to the offhand comment "remove and reinstall plugin". It's not clear as to which plugin, but it's the official Volumio touchscreen one. After following everything else and feeling frustrated, I followed the advice and my screen worked.

Now figuring out rotation was a whole 'nother matter... ;)

Eventually what worked for me was dtoverlay=mhs35:rotate=0 [or 90 or 180 or 270] in /boot/config.txt

Adjust as appropriate for your driver.

Thanks again!

Unknown said...

You have code for tweaking the CSS for a better display on the 3.5" screen.

I have it turned vertical ("portrait") like a phone, and I'm not that worried about the touch aspect, I just want to see the artwork from my seated position across the room.

How would I tweak your CSS to get the album artwork to display full width on the screen, the way it does on my phone? I'm ok with the controls not fully displaying if the artwork gets too big, I'm ok with having to scroll down for controls.

I tried wrapping my head around what your code is doing, but couldn't figure it out.


Michaël said...

This is an excellent start to understand the frontend js/css development: https://volumio.github.io/docs/Development_How_To/Set_up_development_environment_for_UI.html

Then it is a matter of modifying the css locally (I tend to use vscode) and reloading in the browser.

For testing, you can simply resize your browser or use for example https://developer.mozilla.org/en-US/docs/Tools/Responsive_Design_Mode . Volumio uses chromium on the pi, so you might stick to that to keep the development experience consistent.

A good introduction to "responsive design css" is https://www.w3schools.com/css/css_rwd_intro.asp . Volumio uses https://www.w3schools.com/css/css_rwd_mediaqueries.asp to adapt to different screen sizes.

Hope this helps !

Michaël said...

I just did a clean reinstall of my Volumio and updated all the steps accordingly. Thanks for all the helpful comments!

For reference those are the changes / fixes:

(1) the Touch Display Plugin installed just fine, so I had NOT to execute the following fixes:

sudo dpkg --configure -a
sudo apt-get install -y xinit xorg openbox libexif12

try to remove / reinstall the Touch Display Plugin

(2) the driver now uses a different callibration file as noted by some comments. I modified the command (the -90 suffix indicates the orientation, also note that the Touch Display Plugin has an orientation plugin by itself)

sudo cp -rf ./usr/99-calibration.conf-35-90 /etc/X11/xorg.conf.d/99-calibration.conf

(3) I now create a /boot/userconfig.txt instead of modifying /boot/boot.txt. This file should survive volumio updates, but I'll have to test that in the future.

(4) lightdm.conf is fixed in order to use "autologin-user=volumio" instead of the default "pi"

(5) bugs were fixed upstream by Volumio, so no need to apply hotfixes:
- crashed chromium dialog doesn't appear anymore
- statemachine.js is fixed to avoid unwanted stops when executing a playlist
- the cursor is now hidden by default (/lib/systemd/system/volumio-kiosk.service)
ExecStart=/usr/bin/startx /etc/X11/Xsession /opt/volumiokiosk.sh -- -nocursor

(6) I removed the css-hacking as Volumio changed its layout significantly:
for reference, those were the dirty hacks, but do NOT blindly apply them anymore!:
cp /volumio/http/www/styles/app-*.css /volumio/http/www/styles/app-css.orig
sed -i "s/\(\#trackManager{.*\)top:50/\1top:85/g" /volumio/http/www/styles/app-*.css
sed -i "s/\.knobWrapper{position/@media \(max-width:767px\){.knobWrapper{zoom:.40;position:relative;width:210px;height:210px;margin:0 auto 15px}}.knobWrapper{position/g" /volumio/http/www/styles/app-*.css

(7) the Touch Display Plugin has settings to change the sleep timeout (0 = don't sleep) and to change the orientation.

Please also take note of the comments as some are using a different display with slightly different commands from the driver github repo.