DEV: [PLUGIN] MPD_OLED for x86 based systems

So steps taken for this module to run MPD_OLED on a x86

Install all dependencies:

sudo apt-get update
sudo apt-get install build-essential autoconf make libtool libfftw3-dev libiniparser-dev libmpdclient-dev libi2c-dev lm-sensors libasound2-dev autoconf-archive i2c-tools dkms

Get headers to perform make (will break ATO):

wget https://github.com/volumio/x86-kernel-headers/blob/master/linux-headers-5.10.139-volumio_5.10.139-volumio-1_amd64.deb
sudo dpkg -i linux-headers-5.10.139-volumio_5.10.139-volumio-1_amd64.deb
sudo ln -s /usr/src/linux-headers-5.10.139-volumio /lib/modules/5.10.139-volumio/build

reboot

Get driver:

git clone https://github.com/gschorcht/i2c-ch341-usb.git
cd i2c-ch341-usb
make
sudo make install

Check if loaded:
dmesg | grep i2c-ch341-usb

Add volumio to group:

sudo addgroup volumio i2c
newgrp - i2c

Build and install cava:

git clone https://github.com/karlstav/cava
cd cava
./autogen.sh
./configure --disable-input-portaudio --disable-input-sndio --disable-output-ncurses --disable-input-pulse --program-prefix=mpd_oled_
make
sudo make install-strip
cd ..    # leave cava directory

Build and install mpd_oled:

git clone https://github.com/antiprism/libu8g2arm.git
cd libu8g2arm
./bootstrap
mkdir build
cd build
CPPFLAGS="-W -Wall -Wno-psabi" ../configure --prefix=/usr/local
make
cd ../..  # leave libu8g2arm/build directory

git clone https://github.com/antiprism/mpd_oled_dev
cd mpd_oled_dev
./bootstrap
LIBU8G2_DIR=../libu8g2arm CPPFLAGS="-W -Wall -Wno-psabi" ./configure --prefix=/usr/local
make
sudo make install-strip

Configure MPD to copy its audio output to a named pipe
(Ignore the errors)

wget -N http://pitastic.com/mpd_oled/packages/mpd_oled_volumio_install_latest.sh
sudo bash mpd_oled_volumio_install_latest.sh
sudo mpd_oled_volumio_mpd_conf_install

Run MPD_OLED:
Check for the correct bus:

volumio@volumiox86:~$ dmesg | grep i2c-ch341-usb

[ 4125.761992] i2c-ch341-usb 1-1:1.0: ch341_i2c_probe: created i2c device /dev/i2c-14

Use correct bus number:
mpd_oled -o SSD1306,128X64,I2C,bus_number=14 -f 50

or:
/usr/local/bin/mpd_oled -o SSD1306,128X64,I2C,bus_number=$(dmesg | grep -iE "ch341_i2c_probe: created i2c device" | sed 's/^.*[/]//' | sed 's/.*-//') -f 50

1 Like

@supercrab , @Adrii

Shall I move these last posts to a new topic, to avoid confusion with MPD_OLED for the rPi and development efforts on the x86?

Yes please :slightly_smiling_face:

tried the same on a Dell Wyse 3040, less lucky:

dmesg | grep i2c-ch341-usb
[  370.009593] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio0 gpio=0 irq=0
[  370.009599] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio1 gpio=1 irq=1
[  370.009602] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio2 gpio=2 irq=2
[  370.009605] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: output gpio3 gpio=3 irq=3
[  370.009609] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio4 gpio=4 irq=4 (hwirq)
[  370.009612] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio5 gpio=5 irq=5
[  370.009615] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio6 gpio=6 irq=6
[  370.009618] i2c-ch341-usb 1-2:1.0: ch341_cfg_probe: input  gpio7 gpio=7 irq=7
[  370.010041] i2c-ch341-usb 1-2:1.0: ch341_i2c_probe: created i2c device /dev/i2c-14
[  370.010045] i2c-ch341-usb 1-2:1.0: ch341_i2c_set_speed: Change i2c bus speed to 100 kbps

But keep getting errors:

mpd_oled -o SSD1306,128X64,I2C
Failed to write to the i2c bus.

volumio@volumiox86:~/i2c-ch341-usb$ lsmod | grep i2c
i2c_ch341_usb          24576  0
i2c_algo_bit           16384  1 i915
volumio@volumiox86:~/i2c-ch341-usb$ sudo i2cdetect -y 14
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70: 70 71 72 73 74 75 76 77

An after a reboot of the working one, it gives the same error. So we are not there yet.
After every reboot the probing return different results:
ch341_i2c_probe: created i2c device /dev/i2c-10
ch341_i2c_probe: created i2c device /dev/i2c-0
ch341_i2c_probe: created i2c device /dev/i2c-14

The default I2C bus for md_oled is 1 (/dev/i2c-1). The bus numbers you are getting seem kind of random, but, for example, if the screen is connected on bus 0 then use the command

mpd_oled -o SSD1306,128X64,I2C,bus_number=0

pfff
I did try a lot of options, but combined bus_number with HW_I2C and SW_I2c, which didn’t work.
runing below command, did the trick.

mpd_oled -o SSD1306,128X64,I2C,bus_number=14

MPD_OLED also detect play and stop. Only thing left is cava. Never got the hang of all the pipe stuff.
The frame rate is more than appropriate.

Result!

here is some interesting technical data, that might be use full.

Well done! :partying_face::partying_face::champagne::balloon::confetti_ball:

I think I’m gonna pick up one of these to USB adapters :raised_hands:t4:

Just follow the instruction and it should work.

  • CAVA needs to be sorted out.
  • A way to get the bus address fixed, as currently after every reboot it changes.
1 Like

Thanks! Now I have to pick up a little x86 machine too :laughing:

Well 45 euro, for a Dell Wyse 3040, great little piece of hardware. Still a few left.

I had noticed you were using a Del Wyse! I’ve never used one myself but that’s an excellent price for what you get. Also, the super slim Dell USFF Optiplexs are also pretty good, I’m thinking about getting one for plex and now and another for Volumio :joy:

Also got CAVA running, a bit dirty but it works.
(just ran sudo bash mpd_oled_volumio_install_latest.sh, which took care of the CAVA part.)
The bars run smooth, so no issues with frame rates.

image

image

Seems we have a winner, a working POC :partying_face:

3 Likes

Did helpt me om er toch dicht bij te blijven.
Super job!
Soms denk ik, “69, and why the hell still doing this”…

Yep, and the most annoying part of it, I start thinking who the F is the boss, this 200 cents display or me… So I keep on digging.
And finally 3 days lost for a lousy 35 lines of code…

Some notes:

I built the i2c-ch341-usb module on linux v5.15, rather than on v5.10 that Volumio uses, and this required a code change to the module. Hopefully by the time Volumio uses a later kernel the module code will be updated and will build without any changes.

Although this thread refers to x86, it is more about a general linux solution for running mpd_oled (e.g. the adapter could also be used with mpd_oled on the Raspberry Pi). The short instructions are

The development version of mpd_oled is just a quick modification I made to the current version of mpd_oled in order to test the feasibility of using U8g2. And… the U8g2 library it links with is a combination of U8g2 and a linux port, which I modified to support user specified bus numbers. The U8g2 code is assembled and modified by a flaky script that builds all the code into a single binary (splitting some fonts into separate libraries to avoid licensing issues) so that the OLED driver can be specified at run time, and adds in some extra code to enable this. In other words, while the development version of mpd_oled is functional, it should be considered early development. Also, the project is stalled and “unsupported”, in that I might help out with installation but I probably won’t make code changes (e.g. I notice the loop of the letter g is cut off in the bottom line of the screenshot I posted earlier, but I won’t fix this until I resume development).

Adrian.

Thanks for the update.
The main concern at this point, is the fact that the i2C bus keeps changing per reboot. Haven’t found a way to force it, as it’s generated dynamically.
tried with a rule, but it’s not working.
ACTION==“add”, SUBSYSTEMS==“i2c-dev”, ATTRS{idProduct}==“5512”, ATTRS{idVendor}==“1d6b”, ATTRS{name}==“i2c-ch341-usb at bus 003 device 003”, SYMLINK+=“i2c-14”

So bus_number=x

1 Like

Forcing the bus number would be a good solution if it can be made to work.

A not-so-good alternative is that mpd_oled could be wrapped in a script that adds the bus number. The USB port that the adapter is plugged into is known (in case there is more than one adapter), and so the dmesg output could be parsed to extract the bus number from the last entry for this USB port where the adapter is assigned an I2C bus number, and then the mpd_oled command rewriiten to specify it.

What is your main project at the mo?

1 Like