Use PTB on raspberry Pi

Author

Ian

Raspberry Pi 4 setup

Compute Module 4

We’ve found these industrial modules https://docs.edatec.cn/cm4-nano that use eMMC and the compute module 4 (CM4), currently cheaper, with a nice case and more features than RPi4. To burn the OS, you can use rpiboot (github) or sudo apt install rpiboot and then run rpiboot to mount the eMMC as a disk via a USB cable (you must join the J55 jumper pins). Then use RPi Imager (snap install rpi-imager) to burn the OS (it can set up password / WiFi etc. very cool). Note for an 8GB EMMC we need to be careful with what we install on the system, and an external SSD is highly recommended.

OS Options

The standard OS is 32bit (armhf) based off of Debian Bullseye 11. It is tiny and light, with Octave at V6.2. There is also a 64bit (aarch64) OS, which works well (and should be faster, utilise RAM better etc.). Ubuntu 22.04 64bit (aarch64) is also available. Both support Neurodebian, but a standard PTB install require a 32bit OS (Mario only builds 32bit mex files), so Raspian 32bit is preferred for this.

At the moment there are no 64bit builds of PTB for RPi, BUT we have a fork where we have the 64bit ARM mex files (see below). So the current setup:

  • Latest Raspberry Pi OS 64bit
  • Octave from Debian (V6.4) and can also install OCtave V8.2 via micromamba
  • Install PTB via github 64bit ARM fork.

Installing PTB

Use sudo apt install octave

Clone https://github.com/iandol/Psychtoolbox-3/tree/arm64 for built mex files you can use and the changes needed to build them.

In a terminal type: sudo raspi-config; Navigate to Advanced Options > Compositor > xcompmgr composition manager; Choose No; Reboot the Raspberry Pi.

Next:

sudo apt install -y liboctave-dev gamemode freeglut3

Create an ~/.octaverc file with the following:

warning('off', 'Octave:shadowed-function');
graphics_toolkit('gnuplot');
more off;
setenv('LC_CTYPE','en_US.UTF-8');setenv('LC_ALL','en_US.UTF-8')
Screen('Preference','VisualDebugLevel',3);

First, it is important to run Octave from command-line via octave --no-gui then cd ~/Code/Psychtoolbox and run SetupPsychToolbox. Then you can use the GUI as normal…

See https://github.com/kleinerm/Psychtoolbox-3/blob/master/Psychtoolbox/PsychDocumentation/RaspberryPiSetup.m for the official details. As we are using our own 64bit fork, use the github repo and branch mentioned above to install the custom 64bit build.

libdc1394

Need a .22 linked to the current .25:

sudo ln -s /usr/lib/arm-linux-gnueabihf/libdc1394.so.25 /usr/lib/arm-linux-gnueabihf/libdc1394.so.22

Up-to-date Octave (currently 8.2) [optional]

Older Octave V6.2 can run PTB as well, so this step is optional!

Octave is really old in Debian, and it is not so easy to build. Using flatpak cannot work with PTB due to the sandbox. However conda, or more specifically microconda can be used to build a custom environment will the latest octave and all dependencies easily. Conda used to be for Python but now is a general and flexible package manager for just about anything! See https://mamba.readthedocs.io/en/latest/installation.html for details, but quickly you can do this:

curl micro.mamba.pm/install.sh | zsh
export MAMBA_ROOT_PREFIX=/some/prefix  # optional, defaults to ~/micromamba
eval "$(~/.local/bin/micromamba shell hook -s posix)"
micromamba create -n octave
micromamba activate octave
micromamba install -c conda-forge octave gstreamer gst-plugins-bad compilers c-compiler cxx-compiler
octave --gui

The compilers are needed for installing octave packages like instrument-control…

Latest MESA [optional]

You can update the GPU drivers. The easiest way is to use precompiled ones, see https://www.raspberrypi.org/forums/viewtopic.php?f=67&t=293361 and https://github.com/smartavionics/Cura/releases in particular.

LD_LIBRARY_PATH=/opt/mesa/lib/aarch64-linux-gnu octave --gui

Or set LD_LIBRARY_PATH in your .zshrc to use as the default…

You can build Mesa yourself from source: https://qengineering.eu/install-vulkan-on-raspberry-pi.html

Building PTB on 64bit (work-in-progress)

Dependencies:

sudo apt install -y freeglut3-dev libglfw3-dev libglu1-mesa-dev libxi-dev freenect \
  libpciaccess-dev libxxf86vm-dev libxcb-dri3-dev libxcb-present-dev \
  libxcomposite-dev libxml2-dev libasound2-dev liboctave-dev \
  libgstreamer1.0-dev libx11-xcb-dev libgstreamer-plugins-base1.0-dev \
  libraw1394-dev libdc1394-dev portaudio19-dev libopenal-dev libopenxr-dev

To build Screen need to add -I/usr/lib/aarch64-linux-gnu/glib-2.0/include/ to mex or:

sudo ln -s /usr/lib/aarch64-linux-gnu/glib-2.0/include/glibconfig.h /usr/include/glib-2.0/

To build/use GPIO, you need this package that is not available anymore in apt: https://github.com/WiringPi/WiringPi/releases

Command is linuxmakeitoctave3(-1); with most mex files rebuilt, performance is at least equivalent (and theoretically better) to 32bit builds!

OLD Option: Neurodebian

You could install PTB via Neurodebian (supports Raspian and Ubuntu) which solves dependencies easily.

Raspian:

wget -O- http://neuro.debian.net/lists/bullseye.cn-bj1.full | sudo tee /etc/apt/sources.list.d/neurodebian.sources.list
sudo apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com 0xA5D32F012649A5A9
sudo apt-get update

Tsinghua Ubuntu 22.04:

wget -O- http://neuro.debian.net/lists/jammy.cn-bj1.full | sudo tee /etc/apt/sources.list.d/neurodebian.sources.list
sudo apt-key adv --recv-keys --keyserver hkps://keyserver.ubuntu.com 0xA5D32F012649A5A9
sudo apt-get update

Then sudo apt install octave-psychtoolbox-3 which will resolve all dependencies for you. However, this installs an ancient version of PTB.

Gamemode [legacy OS only]

This allows PTB’s Priority command to work better on Linux. Install directly from APT (from Bullseye at least). But for older systems you can build from https://github.com/FeralInteractive/gamemode like so:

sudo apt install meson libsystemd-dev pkg-config ninja-build git libdbus-1-dev libinih-dev
cd ~/Code
git clone https://github.com/FeralInteractive/gamemode.git
cd gamemode
git checkout 1.6.1 # omit to build the master branch
./bootstrap.sh

Problems

32-bit rendering was fixed in a recent PTB update, Mario says fonts work, the only thing broken ATM is HDMI audio.

Low disk space on 8GB EMMC?

You can use the built-in ncdu command (cd /; sudo ncdu), or install QDirStat as a GUI. Snap cache can be cleared with sudo ~/bin/snapcache.sh and you can use sudo apt install bleachbit to clear logs and remove locale files to save ~400MB. You can also use synaptic to sort installed packages by size then try to find ones that seem not essential (pypy, geany and some others).

Interface to GPIO?

https://pinout.xyz/

PTB has a demo: RaspberryPiGPIODemo.m – this uses the WirinngPi library that uses a different pin number scheme, and I can’t get the gpio command to work.

https://github.com/gnu-octave/octave-rpi-gpio

https://www.raspberrypi.org/documentation/usage/gpio/

http://abyz.me.uk/rpi/pigpio/

Octave has a pythonic python bridge and there are several libraries to call GPIO from Python. Or use pigpio and sockets. Octave has several packages that will be useful:

https://octave.sourceforge.io/instrument-control/index.html

Older Config and Workarounds

There is currently a MESA bug, and a current workaround is to make an /etc/X11/xorg.conf file to overrride the bug: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3601

Section "ServerFlags"
  Option "Debug" "None"
EndSection

You should edit \boot\config.txt to make sure it uses the real open-source drivers, and not fake kms one dtoverlay=vc4-fkms-v3d:

[pi4]
# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-kms-v3d-pi4
max_framebuffers=2
gpu_mem=256

[all]
gpu_mem=256

Backing up the SD/eMMC system

Backing up can be dome simply using dd. You can do it live, but better is on a different machine. For live, first insert a USB backup disk, then check the disk names lsblk -p:

cogpi@cogpi-desktop:~$ lsblk -p
NAME             MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
/dev/loop0         7:0    0  48.8M  1 loop /snap/core18/1949
/dev/loop1         7:1    0  57.2M  1 loop /snap/core20/907
/dev/loop2         7:2    0  48.8M  1 loop /snap/core18/1888
/dev/loop3         7:3    0 214.1M  1 loop /snap/gnome-3-34-1804/61
/dev/loop4         7:4    0 197.7M  1 loop /snap/gnome-3-34-1804/68
/dev/loop5         7:5    0  64.8M  1 loop /snap/gtk-common-themes/1514
/dev/loop6         7:6    0  62.1M  1 loop /snap/gtk-common-themes/1506
/dev/loop7         7:7    0  48.3M  1 loop /snap/snap-store/499
/dev/loop8         7:8    0    27M  1 loop /snap/snapd/10709
/dev/loop9         7:9    0 108.5M  1 loop /snap/qv2ray/3910
/dev/loop10        7:10   0  26.9M  1 loop /snap/snapd/9730
/dev/loop11        7:11   0  47.3M  1 loop /snap/snap-store/476
/dev/sda           8:0    1 119.3G  0 disk 
├─/dev/sda1        8:1    1   256M  0 part /media/cogpi/boot
└─/dev/sda2        8:2    1   119G  0 part /media/cogpi/rootfs
/dev/sdb           8:16   0 931.5G  0 disk 
├─/dev/sdb1        8:17   0   489M  0 part /media/cogpi/CLONEZILLA
└─/dev/sdb2        8:18   0   931G  0 part /media/cogpi/Clones
/dev/mmcblk0     179:0    0  14.8G  0 disk 
├─/dev/mmcblk0p1 179:1    0   256M  0 part /boot/firmware
└─/dev/mmcblk0p2 179:2    0  14.6G  0 part /

/dev/mmcblk0 is the booted SD card, /dev/sdb2 mounted as /media/cogpi/Clones is our backup destination.

sudo dd if=/dev/mmcblk0 of=/media/cogpi/Clones/MyImage.img bs=10M  conv=fsync status=progress

Once completed, shrink the image using PiShrink. This can be compressed:

sudo pishrink.sh -v -z -a MyImage.img

To restore it read https://www.pragmaticlinux.com/2020/12/how-to-clone-your-raspberry-pi-sd-card-in-linux/

But basically, reverse the command:

sudo dd if=/media/cogpi/Clones/CM4-2023-05-22.img of=/dev/mmcblk0 bs=10M status=progress
Back to top