This software works with the Coral implementation of the Portiloop EEG closed-loop stimulation device.
It enables controlling the Portiloop from a Graphical User Interface (GUI).
You have just got your hands on the hardware for the Portiloop V3 (A Google Coral Dev Board Mini and a Portiloop board). Here are the steps you need to follow to get started using the EEG capture, the Spindle detection software, and the TPU processing.
- A male-to-female jupmer wire (required to reflash if you brick the Coral board)
- Headphones with a jack that has TWO rings (not three)
Find the instructions to update your Coral Dev Board Mini to the latest OS version here.
(We recommend the force-fastboot method, as it works without mdt)
bash flash.sh -H instead of executing bash flash.sh at the end of these instructions.
These first steps will help you set up an SSH connection to the device.
- Power up the board through the USB-C power port.
- Connect another USB cable to the OTG-port on the board and to your Linux host machine. Then connect to the board through serial (or via
mdt) by executingscreen /dev/ttyACM0(ormdt shell)
If you see a message telling you that screen is busy, you can use sudo lsof /dev/ttyACM0 and then retry the screen step.
- Login to the board using the default username and password: mendel
- Once you are logged in, you can now connect to your desired wifi network using
nmtui. - Enable SSH access with password by executing the following command:
sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
(if you get an error message, you can instead execute sudo nano /etc/ssh/sshd_config, find the PasswordAuthentication no line, replace 'no' by 'yes', and save by pressing CTRL + o, then ENTER, then CTRL + x)
- Note your randomly-generated hostname (displayed as
mendel@your-hostname) or define a custom hostname (sudo hostnamectl set-hostname your-hostname) - Shutdown the device (
sudo shutdown nowor press thePowerbutton for 3 seconds) and pull out the OTG-port cable before the Coral board reboots (which otherwise happens automatically after a few seconds as long as this cable is plugged in).
Next time you turn the Coral board on, you should be able to ssh into it using the hostname (or the IP address of the device):
ssh mendel@your-hostname.local
If some issues arise, make sure your PC is connected to the same network as the Coral Dev Board Mini.
- Plug the
USB-C Powercable in and turn the portiloop on by pressing thePowerbutton for 3 seconds. - SSH into the device
- Clone this repository in the home folder:
cd ~ && git clone https://github.com/Portiloop/portiloop-software.git - Go into the cloned repository:
cd ~/portiloop-software, - Run
makeand follow the instructions when prompted - Don't forget to reboot the device afterward - Note that
makemay fail at several points during installation. Whenever it does, just callmakeagain.
That's it! Your Jupyter server should now be up and running, listening on IP address 192.168.4.1 and port 8080, and automatically starting whenever the system boots up. You can now access it by typing 192.168.4.1:8080 in your browser. This should lead you to a login page where you'll be prompted for your password. If any issue arises, try with a different web browser.
Similarly, the Simple UI can be accessed by typing 192.168.4.1:8081 in your browser.
If using an SD card to record your EEG signal in CSV format, plug the SD card into your Portiloop before powering the Portiloop on.
Your CSV will then be recorded in the SD card under the workspace folder.
Otherwise, your CSV will be recorded in internal memory under /home/mendel/workspace
Portiloop unusable: the internal memory is quite small and recording CSVs in internal memory should never be done, except for quick testing.
In case you inadvertently fill up your Portiloop internal memory, it will refuse to boot and you will have to reflash and reinstall the entire system.
To power the Portiloop, plug your USB-C battery into USB-C Power and press the Power button for 3 seconds.
Then, wait for the light next to USB-C Power to turn green (the green color indicates that boot was successful).
To power the Portiloop down, press the Power button for 3 seconds again and wait for a couple more seconds for the light close to USB-C Power to turn off.
You can then unplug the USB-C Power cable.
When everything goes smoothly, the light close to USB-C Power turns off.
However, it may happen that this light refuses to turn off due to some internal issue.
In that case, just wait for a couple more seconds before unplugging.
Portiloop, in which case you will have to reflash and reinstall the entire system.
The Portiloop system has 3 indicator LEDs:
- Coral board LED between the two USB-C connectors:
- orange: boot in progress
- green: boot complete
- red: the Coral Dev Board Mini is in fastboot mode, ready to flash
- turned off when the Portiloop is off
- Portiloop power LED
- green: power plugged
- turned off when the Portiloop is unplugged
- Portiloop indicator LED
- purple: capture in progress
- blue: capture in progress with detection and stimulation pipeline enabled
- turned off otherwise
Connect your computer (or smartphone) to the WiFi access point of the Portiloop that you want to use.
The Portiloop has two web-based Graphical User Interfaces that you can access via any web browser:
- A user-friendly
Simple UI- accessible via
192.168.4.1:8081
- accessible via
- An advanced UI in the form of a
jupyternotebook- accessible via
192.168.4.1:8080
- accessible via
To access the Simple UI, open your favorite browser and enter the following address: 192.168.4.1:8081.
This UI is pretty self-explanatory. It has several options, including:
- Detecting patterns of interest in real-time (e.g., Sleep Spindles)
- Performing closed-loop stimulation based on this detection
- Recording raw EEG along with the above detections in a CSV file
The Portiloop advanced UI is a web-based interface running as a jupyter server.
To access this UI, open your favorite browser and enter the following address: 192.168.4.1:8080.
You should now be connected to the jupyter server.
If the jupyter notebook is not yet created:
- Hit
Newand selectPython 3.
This creates a jupyter notebook, in which you can simply paste and execute the following:
from portiloop.capture import JupyterUI
cap = JupyterUI()The Channels panel enables you to configure each electrode:
simple: the electrode is used to measure signalbias: the electrode is used to output the measured bias ("ground") signaltest: the electrode is used to output a test signaltemp: the electrode is used to output a signal corresponding to the ADS temperature (conversion required)
Freqis the desired sampling rateTimeis the maximum duration of the experiment (you can also stop the experiment manually)Recordingis the name of the.csvoutput file if you wish to record the signal locally- Tick
Filterto enable the online filtering pipeline - Tick
Detectto enable the online detection pipeline - Tick
Stimulateto enable the online stimulation pipeline - Tick
Record CSVto record the signal in the file designated inRecording - Tick
Stream LSLto broadcast the signal on the local network via LSL - Tick
Displayto display the signal in the GUI Thresholdenables customizing the optional detection threshold from the GUI (e.g., for classifiers)- The
Clockwidget lets you select the sampling method: -Coralsets theADS1299sampling rate to twice your target sampling rate, and uses the Coral Real-Time clock to stick to your target sampling rate -ADSsets theADS1299sampling rate to the closest compatible to your target sampling rate and uses the ADS interrupts
The Filtering section lets you customize the filtering pipeline from the GUI.
- The
FIR filterswitch lets you select between the default low-pass FIR filter (used in the Portiloop paper), or customize this filter according to your needs (FIR orderandFIR cutoff) Polyak mean,Polyak stdandEpsilonlet you customize the online standardization pipeline, which also acts as a high-pass filter (only available in theSleep Spindlespipeline)
The core Portiloop software architecture is defined in portiloop.src.core.
It defines the three interfaces that developers of custom pipelines must implement:
processing.pydefines theProcessorinterface, in charge of all signal processing.detection.pydefines theDetectorinterface, in charge of all detection algorithms/models.stimulation.pydefines theStimulatorinterface, in charge of all response to the detector output.
The Portiloop software is a Python library.
You may implement the aforementioned interfaces, put these in a pipeline dictionary.
The portiloop.custom.custom_pipelines module defines the PIPELINES dictionary, which you can modify to define your custom Portiloop pipeline: just add an entry following the existing template, i.e.:
from portiloop.src.custom.custom_pipelines import PIPELINES
PIPELINES["Your_Pipeline_Name"] = { # This name will appear in the Portiloop GUIs.
"processor": Your_Processor_Class, # class of your Processor implementation (not instance).
"detector": Your_Detector_Class, # class of your Detector implementation (not instance).
"stimulator": Your_Stimulator_Class, # class of your Stimulator implementation (not instance).
"config_modifiers": {}
},You can then feed this dictionary as argument to the Portiloop GUIs.
Developers of new Portiloop pipelines that are to be merged with the repo must work entirely under the portiloop.custom package, where abstract interfaces are implemented for tasks such as Sleep Spindle or Sleep Slow Oscillations detection and stimulation.
Abide only to these interfaces and do not make additional assumptions, otherwise your custom pipeline will break the Portiloop GUIs, which rely exclusively on these interfaces.
portiloop.core package, nor the jupyter_gui and simple_gui packages.
If you feel you need to do any of these things, please ask for assistance, as you are probably doing something wrong.