poc:2025:raspberry-pi-vep

This is an old revision of the document!


  • Status: ⏸️ On Hold
  • Duration: February-April 2025
  • Type: Hardware/Possible Product
  • Repository: Code Repo | ADRs
  • Team: Fabricio

What we're exploring: Whether we can reliable measure VEPs on the Raspberry Pi. A Checkerboard stimulus is created using a low-level implementation that synchronizes with the Pi-EEG Shield measurements.

Hardware Used :

  • Raspberry Pi 4 B
  • OS: Raspbian without Desktop
  • Access via SSH in WIFI, directly providing credentials when writing the Image onto the SD card

Software Used :

A few initial key insights about the PiEEG Code:

  • The code uses the BOARD numbering mode for the GPIO pins.
  • Pin 37 is used as the “DRDY” (data ready) pin.
  • A lot of settings are set to the ADS1299, but in an intransparent way via encoding the bit flags via hex codes.

Quite a few things may be set via the ads1299 registers:

  • The sampling rate is set in “config1” and defaults to 250 but can be changed. By default config1 is set to 0x96, which translates to the binary number `10010110`. The last 3 digits denote the sampling rate. You can find the encoding in Table 13 here
  • A small test with the Pi-EEG shield when looking at alpha waves seemed promising in terms of the data quality.
  • The Checkerboard pattern using the libdrm worked well. Synchronization via the screen refreshment rate is possible.
  • Setting a high priority to the process in combination with a preemptible Kernel setting (i.e. Desktop mode- NOT server mode) works well in terms of latency, although it is not a full substitute for the realtime kernel.
  • Using the Video-Display-Glasses with the rPi was no issue at all and worked well, even though the display was a bit small. No software changes were required, as it was simply treated as another display.
  • The low-level graphics interface worked well, but it can get quite complicated very quickly. There is a need to write ahead into the buffer to avoid tearing.

Realtime Linux:

I tried setting up RaspberryPi with the newly provided realtime option for newer linux kernels.

The option for the realtime kernel has to be provided during compile time, and the raspberry pi kernel is not identical to the vanilla linux kernel, so I think that due to this it does (at the current time) not directly support simply setting the RT flag. There is no separate branch that supports realtime linux for the raspberry pi. Theoretically, realtime patches for the raspberry pi should work, but I didn't get it to work, without figuring out the issue.

Directly using the C code from the PiEEG Shield The C code is outdated, and there is essentially no explanation. It was necessary to look at the python code and translate it to C.

Measuring the actual VEPs:

I did not manage to nicely measure the VEP. It's unclear what the cause is, as too many things were changed at once. Possible culprits are:

  • Parallel Processing in C without unit tests (or in general C code, as I'm inexperienced there).
  • The PiEEG / ads1299 interface I used in C. I reused the same GPIO pins and signals as in the python code, but the code translation might have introduced some oversights.
  • Higher Sampling Rate: The initial test was done on a lower (default) sampling rate. The sampling rate was increased by a large factor, and it is unclear to me if this is a.) supported by the shield and b.) if any flags on the ADS1299 shield have to be changed.
  • The PiEEG code is not very helpful, and continuation of the project requires understanding of the underlying ADS1299 chip.
  • Moving to rust would help for a more reliable implementation and easier testing and building.
  • There are a LOT of different ways for low-level interaction with the display. The “displaybuffer” is ancient and should NOT be used. The newer kernel mode setting is absolutely overkill and hard to work with. Libdrm seemed like a nice middleground.

Should we proceed?: Maybe

If yes, what needs to happen?

  • A reimplementation either in rust, or by someone with a better understanding of C.
  • More fine grained practical tests to rule out error sources.

External Ressources

  • Code for PiEEG can be found here, but it is mostly undocumented and barely working out of the box. Key to understanding the code is linking the set registers of the code to its functionalities according to the ads1299 manual.

Papers

Images

  • poc/2025/raspberry-pi-vep.1753711971.txt.gz
  • Last modified: 2025/07/28 14:12
  • by fabricio