<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.bci2000.org/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nluczak</id>
	<title>BCI2000 Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.bci2000.org/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nluczak"/>
	<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php/Special:Contributions/Nluczak"/>
	<updated>2026-06-29T19:21:48Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.6</generator>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=CortecExperience&amp;diff=12452</id>
		<title>CortecExperience</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=CortecExperience&amp;diff=12452"/>
		<updated>2026-05-15T16:51:56Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Introduction Video of CorTec Brain Interchange with BCI2000=&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot; dimensions=&amp;quot;900&amp;quot;&amp;gt;https://youtu.be/TMZPQPhRnn8&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Getting Started with Cortec BIC in BCI2000=&lt;br /&gt;
&lt;br /&gt;
#[[Programming Howto:Building and Customizing BCI2000|Install BCI2000]]&lt;br /&gt;
#*Here you will learn how to configure and compile BCI2000 on your own computer.&lt;br /&gt;
&lt;br /&gt;
#[[CortecADC]]&lt;br /&gt;
#*This article steps you through all the available configuration options and information stored with using BCI2000 with the Brain Interchange.&lt;br /&gt;
&lt;br /&gt;
#[[Contributions:XsensMTwLogger]]&lt;br /&gt;
#*This article shows how to combine any BCI2000 source module the XsensMTw device to capture motion simultaneously with electrophysiological signals.&lt;br /&gt;
&lt;br /&gt;
=Canine Surgical Procedure=&lt;br /&gt;
This article presents a brief introduction to surgical protocols for the implantation of the CorTec Brain Interchange. The main objective is to introduce the essential surgical considerations for implanting this device in different animal models. &lt;br /&gt;
&lt;br /&gt;
Download the [https://bci2000.org/downloads/doc/Canine_Cortec_Surgical_Protocol.pdf surgical protocol here].&lt;br /&gt;
&lt;br /&gt;
Download the updated [https://wustl.box.com/s/hq5rgw4mnb70nd6f07jkk50u2o70n46s surgical protocol here].&lt;br /&gt;
&lt;br /&gt;
=Preliminary experience with the CorTec BrainInterchange device in a canine modele=&lt;br /&gt;
This article describes initial work toward an ecosystem for adaptive neuromodulation in humans by documenting the experience of implanting CorTec&#039;s BrainInterchange (BIC) device in a beagle canine and using the BCI2000 environment to interact with the BIC device. It begins with laying out the substantial opportunity presented by a useful, easy-to-use, and widely available hardware/software ecosystem in the current landscape of the field of adaptive neuromodulation, and then describes experience with implantation, software integration, and post-surgical validation of recording of brain signals and implant parameters. Initial experience suggests that the hardware capabilities of the BIC device are fully supported by BCI2000, and that the BIC/BCI2000 device can record and process brain signals during free behavior. With further development and validation, the BIC/BCI2000 ecosystem could become an important tool for research into new adaptive neuromodulation protocols in humans. &lt;br /&gt;
&lt;br /&gt;
Schalk G, Worrell S, Mivalt F, Belsten A, Kim I, Morris JM, Hermes D, Klassen BT, Staff NP, Messina S, Kaufmann T, Rickert J, Brunner P, Worrell GA, Miller KJ. Toward a fully implantable ecosystem for adaptive neuromodulation in humans: Preliminary experience with the CorTec BrainInterchange device in a canine model. Front Neurosci. 2022 Dec 19;16:932782. doi: 10.3389/fnins.2022.932782. PMID: 36601593; PMCID: PMC9806357.&lt;br /&gt;
&lt;br /&gt;
Download the [https://bci2000.org/downloads/doc/Preliminary_experience_with_the_CorTec_BrainInterchange_device_in_a_canine_model.pdf article here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Data Sharing=&lt;br /&gt;
This data recorded is freely available on DANDI and OpenNeuro.&lt;br /&gt;
&lt;br /&gt;
Download the [https://dandiarchive.org/dandiset/000571?pos=1 canine data from DANDI].&lt;br /&gt;
&lt;br /&gt;
Download the [https://openneuro.org/datasets/ds004624/versions/1.0.1 canine data from OpenNeuro].&lt;br /&gt;
&lt;br /&gt;
=Closed-loop Stimulation=&lt;br /&gt;
With BCI2000, it is possible to stimulate with the Brain Interchange based on processed signals from Brain Interchange recordings! BCI2000&#039;s infrastructure was created for closed-loop control, as it processes the recorded activity and can directly use the results to affect the task or stimulation. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;See the [[Closed-Loop Stimulation]] page for more information!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot; dimensions=&amp;quot;900&amp;quot;&amp;gt;https://youtu.be/YIM_YmoHRR8&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To start out, we can review how to conduct a closed-loop brain-computer interface task. This has a very similar pipeline to closed-loop stimulation so it is a good place to start. Review the [[User Tutorial:Mu Rhythm BCI Tutorial|Mu Rhythm tutorial]] for in-depth instructions on how to set it up. &lt;br /&gt;
&lt;br /&gt;
Now that we have the closed-loop task control reviewed, we can move on to closed-loop stimulation. Since CortecADC is a source module, stimulation is conducted in the source module (review the [[User Reference:Filters|Filters]] page for BCI2000 overview). This means we have to carry-over the results from the past signal processing pipeline to the next block. This can be done with States, which stream through all the modules of BCI2000 in a closed-loop fashion. Since Cortec stimulation is controlled with Expressions, a State that was changed due to the processed signal will trigger stimulation. For example, you can use EarlyOffsetExpression available in the [[User Tutorial:StimulusPresentation|StimulusPresentation]] Application module to change stimuli due to a processed signal. You would set up the stimulation to be triggered once the new stimulus is reached, due to EarlyOffsetExpression becoming true.&lt;br /&gt;
&lt;br /&gt;
=Synchronize Inertial Measurement Units with the CorTec Brain Interchange=&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot; dimensions=&amp;quot;900&amp;quot;&amp;gt;https://youtu.be/-SOUX5J1vJE&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Video]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12451</id>
		<title>Contributions:CortecADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12451"/>
		<updated>2026-05-14T22:15:06Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CorTec_BrainInterchange.png|400px|thumb|right|CorTec Brain Interchange Implant]]&lt;br /&gt;
CortecADC is a source module that allows for intra-cranial recording and stimulating over 32 channels via a fully implantable device. It is intended for long-term measurement of neural activity and electrical stimulation of brain tissue. See the [https://www.cortec-neuro.com/solutions/complete-system/ CorTec site] for more information.&lt;br /&gt;
&#039;&#039;&#039;See the [[CortecExperience]] page for user tutorials and a broad overview!&#039;&#039;&#039; After viewing the [[CortecExperience]] page, refer to this page for detailed instructions.&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter.org)&lt;br /&gt;
* William Engelhardt (engelhardt@neurotechcenter.org)&lt;br /&gt;
* Alexander Belsten (belsten@neurotechcenter.org)&lt;br /&gt;
* Markus Adamek (adamek@neurotechcenter.org)&lt;br /&gt;
* Christian Stolle (christian.stolle@cortec-neuro.com)&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 6266&lt;br /&gt;
*Tested under: 9282&lt;br /&gt;
*Known to compile under: 9282&lt;br /&gt;
*Broken since: --&lt;br /&gt;
===BCI2000 Version History===&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Date !! Revision !! Note !! Contributor&lt;br /&gt;
|-&lt;br /&gt;
!11/29/2018&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R5829&lt;br /&gt;
|Initial untested version&lt;br /&gt;
|Adamek&lt;br /&gt;
|-&lt;br /&gt;
!04/19/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6271&lt;br /&gt;
|First working version&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!07/22/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6339&lt;br /&gt;
|Changed &#039;&#039;ImplantLostSample&#039;&#039; from a BCI2000 state to a stream, so it can record individual sample loss (instead of over the whole block)&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!01/01/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7133&lt;br /&gt;
|Updated API to version 1.0.200.&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!03/08/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7251&lt;br /&gt;
|Stimulation functionality added&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!05/19/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7367&lt;br /&gt;
|Impedance measurement enabled&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!10/26/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Stimulation latency vastly improved&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!02/20/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7847&lt;br /&gt;
|Version 1.0.230 added. Can change between versions in CMakeLists.txt file&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!08/09/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8313&lt;br /&gt;
|Version 1.0.238 added&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!01/17/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Interpolation filter added to interpolate lost samples&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!06/25/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8915&lt;br /&gt;
|All listener states were changed to events&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!04/13/2026&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R9351&lt;br /&gt;
|Refactored stimulation to be more in line with Cortec and BCI2000 standards.&lt;br /&gt;
|Nicholas Luczak&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
===Cortec API Version History===&lt;br /&gt;
Cortec is continually updating their devices with new API versions. In BCI2000, we currently support versions 1.0.200, 1.0.230, and 1.0.238. Each Brain Interchange Communication unit (BIC) is only compatible with one API version. To find your compatible version, connect the USB drive that comes with your BIC. Look under:&lt;br /&gt;
# &#039;&#039;&#039;Software folder&#039;&#039;&#039;: Each executable has the API version. E.g., &amp;lt;code&amp;gt;Bicapi_setup_1.0.200-bicapi-setup-1.0.200-rev35926.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Manuals foder&#039;&#039;&#039;: &#039;&#039;Appendix1_BIC_Application_Software_Short_Manual.pdf&#039;&#039;. On page 3, in Table 1, the third row contains the compatible version.&lt;br /&gt;
Here are some differences between the versions. As the device is always improving, the newest version will have the most features.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Features !! 1.0.200 !! 1.0.230 !! 1.0.238 !! 1.0.260&lt;br /&gt;
|-&lt;br /&gt;
!Matlab API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!C/C++ API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Stimulation modes&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!ASIC Noise Detection Mode&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Monopolar stimulation (Ch → GND)&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Measure GND impedances&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Self-tests&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Low noise recording&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
===Known Issues===&lt;br /&gt;
* Lost samples - The &amp;lt;code&amp;gt;ImplantLostSamples&amp;lt;/code&amp;gt; state records what samples are lost, and their locations. Lost samples are replaced with the previous valid sample for all channels. In offline analysis, be sure to remove these samples and replace them with interpolates.&lt;br /&gt;
* The Brain Interchange Communication Unit has been seen to work with certain USB inputs, and not with others. If you are experiencing connection issues, try using a different USB port.&lt;br /&gt;
==Installation==&lt;br /&gt;
# Install BCI2000&lt;br /&gt;
# Insert the Cortec USB drive that comes with the Brain Interchange (BIC) device. Under &#039;&#039;Software&#039;&#039;, run the &#039;&#039;Bicapi_setup...&#039;&#039; executable&lt;br /&gt;
# Run a batch file with CortecADC as your Signal Source!&lt;br /&gt;
# If you receive an error, and it states your API version is incorrect, you need to change it. Locate the &#039;&#039;CMakeLists.txt&#039;&#039; under &amp;lt;code&amp;gt;BCI2000/src/private/SignalSource/Cortec&amp;lt;/code&amp;gt;. You must change Line 12, where it states &amp;lt;code&amp;gt;set(BICAPI_VERSION 200)&amp;lt;/code&amp;gt;. Change 200 to 230 or 238, depending on your device (see [[#Cortec Version History | details above]]).&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:CortecSourceParameters.jpg|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the CortecADC]]&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. In the current implementation, this parameter cannot be edited, and will default to how many channels are available from the implant.&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block.&lt;br /&gt;
Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated. For example, at 1000 Hz sampling and a SampleBlockSize of 20, the system (e.g., source signal display, signal processing, and stimulus presentation) will be updated 50 times per second.&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. This parameter cannot be edited, and will default to the sampling rate available from the implant.&lt;br /&gt;
In case you are experiencing problems by higher sampling rates (e.g., data loss, jerky display, etc.), increase the SampleBlockSize so that you are updating the system less frequently (usually, updating the system 20-30 times per second is sufficient for most applications), and increase Visualize-&amp;gt;VisualizeSourceDecimation. This parameter will decrease the number of samples per second that are actually drawn in the Source display.&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel.&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel.&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel.&lt;br /&gt;
===LogCortecBinaryFiles===&lt;br /&gt;
Enable or disable binary logging of raw CorTec communication data.&lt;br /&gt;
When enabled, a binary log file is written to the BCI2000 session directory with the name:&lt;br /&gt;
&amp;lt;code&amp;gt;YYYYMMDD_HHMMSS_CortecAdcLog.bin&amp;lt;/code&amp;gt;&lt;br /&gt;
This file contains raw communication packets between the Brain Interchange Communication unit and the implant and is primarily useful for low-level debugging and support from CorTec.&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; (enabled)&lt;br /&gt;
Disable this parameter if binary logs are not needed or disk space usage is a concern.&lt;br /&gt;
===LogStimulationEvents===&lt;br /&gt;
Enable logging of stimulation configuration and execution events to the Operator Log.&lt;br /&gt;
When enabled, detailed information about stimulation functions, trigger evaluation, and stimulation execution will be printed using &amp;lt;code&amp;gt;bciout&amp;lt;/code&amp;gt; messages.&lt;br /&gt;
This is useful for debugging stimulation timing and verifying correct parameter interpretation.&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (disabled)&lt;br /&gt;
===ReferenceCh===&lt;br /&gt;
This list defines what channels will be used as reference. This list is uploaded to the device and set in hardware, effecting the raw bio-signal data that is recorded by BCI2000. If you do not want to effect the raw bio-signal data that is recorded, you can use the [https://www.bci2000.org/mediawiki/index.php/User_Reference:SpatialFilter spatial filter]. If this parameter is set to auto, no reference channels are used. It is strongly recommended to use at least one reference channel.&lt;br /&gt;
===AmplificationFactor===&lt;br /&gt;
Amplification factor that is applied to the recorded data on the implant. The choices are 39.5, 45.5, 51.5, 57.5 db.&lt;br /&gt;
===UseGround===&lt;br /&gt;
Enable to use the ground electrode while measuring. This setting can be overwritten during stimulation, depending if the ground electrode is being used or not. For example, if you have enabled this parameter but don&#039;t have &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;Destination ch&amp;lt;/code&amp;gt; list in the StimulationTriggers parameter, when you are stimulating you will not be using the ground electrode. Once stimulation is done, this parameter&#039;s settings are used again.&lt;br /&gt;
===SaveInfoFile===&lt;br /&gt;
Enable to save a text file, named the same as the data file run. It will contain the timestamp, amplification factor used in the run, and reference channels used. If the Impedance is measured, the impedance values will be saved to this file regardless of if this parameter is enabled.&lt;br /&gt;
===LogPacketErrors===&lt;br /&gt;
Enable to save the packet loss errors to the System Log. Helpful for debugging, however can get overwhelming if there are a lot of lost samples. The System Log can be programmatically saved by appending &amp;lt;code&amp;gt;--SystemLogFile=SOME_FILE.TXT&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;Startup system localhost&amp;lt;/code&amp;gt; line in your batch file.&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
The figure below summarizes the BCI2000 stimulation paradigm used by CortecADC. A BCI2000 expression (typically based on &amp;lt;code&amp;gt;StimulusCode&amp;lt;/code&amp;gt;) acts as a &#039;&#039;&#039;Stimulation Trigger&#039;&#039;&#039;. When a trigger evaluates true, one or more &#039;&#039;&#039;Stimulation Commands&#039;&#039;&#039; are executed. Each Stimulation Command is composed of one or more &#039;&#039;&#039;Stimulation Functions&#039;&#039;&#039; (with optional bursts, pauses, and repetitions), and every Stimulation Function is defined by a &#039;&#039;&#039;Stimulation Pulse&#039;&#039;&#039; with pulse amplitude, pulse duration, and dead-zone parameters. Use this figure as a mental model for interpreting the &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt; parameters described below.&lt;br /&gt;
[[File:StimDefinition_BCI2000.png|1000px|thumb|center|upright=2.5|Figure 2. Summary of the BCI2000 stimulation paradigm. A BCI2000 trigger expression (top, based on StimulusCode) launches a Stimulation Command (red, left), which is built from repeating Stimulation Functions, optional bursts, and pauses. Each Stimulation Function is defined by a Stimulation Pulse (blue, right), parameterized by Pulse Amplitude, Pulse Duration, Dead Zone 0, and Dead Zone 1.]]&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:CortecADC_stimulation_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationpulses_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationtriggers_parm1.PNG&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;!-- TODO (Nick): replace the three stimulation parameter screenshots above with refreshed images per docx item 3a. --&amp;gt;&lt;br /&gt;
===EnableStimulation===&lt;br /&gt;
This parameter enables/disables stimulation.&lt;br /&gt;
===StimulationMode===&lt;br /&gt;
The BIC has 3 stimulation modes. Each one has limitations. Here is a brief summary of how to use each one:&lt;br /&gt;
#Volatile Commands: The most flexible mode, allowing stimulation commands to be defined with virtually no size constraints. However, the stimulation configuration must be uploaded immediately before execution, which introduces additional latency. Furthermore, the configuration is cleared after each command, resulting in increased latency for repeated executions. This mode is best suited for iterating across multiple stimulation configurations and designing complex stimulation paradigms.&lt;br /&gt;
[[File:VolatileCommand.png|1000px|thumb|center|upright=2.5|Figure 3. Figure demonstrating volatile command functionality]]&lt;br /&gt;
#Persistent Command: This preloading mode enables uploading up to 16 stimulation functions to the device and executing them in a predefined order (the list of FunctionID(s) in StimulationTriggers must be the same). The stimulation command remains in memory after execution and can be repeated, making it best suited for delivering continuous or continuously repeated stimulation.&lt;br /&gt;
#Persistent Functions: This preloading mode enables uploading up to 16 stimulation functions to the device and executing them individually by calling the stimulation function ID. The device executes only one stimulation function (the indexed one) without repetition. This mode is best suited for rapidly iterating over subsets of stimulation pulses in single-pulse stimulation settings.&lt;br /&gt;
[[File:PersistantFunction.png|1000px|thumb|center|upright=2.5|Figure 4. Figure demonstrating Persistant Function functionality]]&lt;br /&gt;
&amp;lt;!-- TODO (Nick): per docx item 3e, edit PersistantFunction.png internally so the orange axis label currently reading &amp;quot;Source code&amp;quot; reads &amp;quot;StimulusCode&amp;quot;. --&amp;gt;&lt;br /&gt;
There cannot be any train settings (Train frequency and Train repetitions), so the StimulationTriggers must not have those rows. Also, StimulationTriggers must not have more than 16 columns, as that is the highest number of configurations that can be stored on the device.&lt;br /&gt;
Persistent Command and Functions modes have a lower latency because the stimulation is pre-uploaded. All modes are available to give you the highest amount of flexiblity with the BIC. [[#Stimulation Latency|See below for more details on latency.]]&lt;br /&gt;
===MeasureImpedance===&lt;br /&gt;
When enabled, the impedances of the used electrodes are printed when you set the configuration. All electrodes that are being recorded will conduct the impedance measurement. The impedances are shown to the user and also saved in the data directory.&lt;br /&gt;
===StimulationPulses===&lt;br /&gt;
This parameter defines stimulation &#039;&#039;functions&#039;&#039;. Each column defines a stimulation waveform and electrode configuration.&lt;br /&gt;
Each function consists of:&lt;br /&gt;
* Pulse waveform parameters&lt;br /&gt;
* Electrode mapping&lt;br /&gt;
* Repetition behavior&lt;br /&gt;
Rows are defined as follows:&lt;br /&gt;
====FunctionID====&lt;br /&gt;
Integer identifier for this stimulation function. This ID is referenced in the &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
====Pulse Amplitude====&lt;br /&gt;
Amplitude of the stimulation pulse in µA.&lt;br /&gt;
Valid range:&lt;br /&gt;
0 to 6120 µA&lt;br /&gt;
====Pulse Duration====&lt;br /&gt;
Duration of the main pulse in µs.&lt;br /&gt;
Valid range:&lt;br /&gt;
10 to 2550 µs&lt;br /&gt;
====Dead Zone 0====&lt;br /&gt;
Pause between main pulse and counter pulse.&lt;br /&gt;
====Dead Zone 1====&lt;br /&gt;
Pause after pulse delivery.&lt;br /&gt;
====Anode(s)====&lt;br /&gt;
Embedded list specifying source electrodes.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code&amp;gt;{ list 1 18 19 }&amp;lt;/code&amp;gt;&lt;br /&gt;
====Cathode(s)====&lt;br /&gt;
Embedded list specifying return electrodes.&lt;br /&gt;
Use &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; to reference ground.&lt;br /&gt;
====Pulse Repetition====&lt;br /&gt;
Number of times the pulse is repeated within a function.&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
====Burst Repetition====&lt;br /&gt;
Number of times the function is repeated.&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
Defines when stimulation functions are executed.&lt;br /&gt;
Each column contains:&lt;br /&gt;
====Trigger====&lt;br /&gt;
A valid BCI2000 expression.&lt;br /&gt;
When this expression evaluates to true, the associated stimulation function(s) are executed.&lt;br /&gt;
====FunctionID(s)====&lt;br /&gt;
List of FunctionIDs that should execute when the trigger evaluates true.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
StimulusCode==1   { list 1 3 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This means:&lt;br /&gt;
Execute FunctionID 1 followed by FunctionID 3 whenever the trigger becomes true.&lt;br /&gt;
Note:&lt;br /&gt;
Electrode configuration and repetition settings are defined in &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;, not here.&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, such as device type, device ID, and the firmware version.&lt;br /&gt;
===StateInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information regarding state units and their multiplier. The device provides information such as humidity, temperature, control value, etc., which are recorded in BCI2000 states (see state information on this page for a complete enumeration of states). The device provides these values with floats, but BCI2000 states can only be integers. The multipliers defined in this parameter are used to increase the amount of precision in the state values. To approximately recover the original float values with the units defined in this parameter, divide each state by its corresponding multiplier.&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information returned from the Cortec implant. The device provides this data in floating point numbers, however BCI2000 can only record integers to it&#039;s states. To maintain some precision, these floats are multiplied by constants, then recorded to the states as integers. To approximately recover the original data, divide the state by its corresponding constant. Constants are shown in the following table.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:right;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
! State&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot; | Constant&lt;br /&gt;
|-&lt;br /&gt;
| ImplantVoltage&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantHumidity&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantControlValue&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantPrimaryCoilCurrent&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantTemperature&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|}&lt;br /&gt;
===ImplantLostSample===&lt;br /&gt;
The communication protocol the device uses does not re-send lost data. This state annotates what samples were lost in the bio-signal data. Currently, lost samples are made up by duplicating the previous sample.&lt;br /&gt;
===ImplantVoltage===&lt;br /&gt;
16 bit state that changes when new supply voltage value is received from the implant. After dividing the integer state value by the the voltage multiplier defined in the StateInfo parameter, the units are in volts.&lt;br /&gt;
===ImplantHumidity===&lt;br /&gt;
16 bit state that changes when new humidity value is received from the implant. Units in %rh.&lt;br /&gt;
===ImplantControlValue===&lt;br /&gt;
16 bit state that changes when new current control value is received from the external unit. The power of the implant is controlled by the external unit. The control value provides a measure of how good the coupling between the two coils is and how much more power can be provided if necessary.&lt;br /&gt;
The value is between 0.0 and 100.0 percent, where 0.0 translates to no power and 100.0 translates to maximum power applied.&lt;br /&gt;
===ImplantPrimaryCoilCurrent===&lt;br /&gt;
16 bit state that change when new primary coil current value is received from the external unit. The primary coil refers to the coil inside the head piece of the external unit. Units are mA.&lt;br /&gt;
===ImplantTemperature===&lt;br /&gt;
16 bit state that changes when new temperature value is received from the implant. Units are degrees Celsius.&lt;br /&gt;
===ImplantStimulation===&lt;br /&gt;
Binary state that changes when the device reports that it is stimulating.&lt;br /&gt;
===ImplantStimulationBursts===&lt;br /&gt;
Updates when the device reports that stimulation functions have finished. Should increment during a stimulation train.&lt;br /&gt;
===ImplantRfQuality===&lt;br /&gt;
8 bit state that reports the antenna quality as reported from the rf-link in dBm. &#039;&#039;&#039;&#039;&#039;To obtain the original value, subtract by 128 (2^8)&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
===RequestedStimulation===&lt;br /&gt;
Binary state that records when a stimulation trigger expression evaluates true. State remains true for the duration triggered stimulation. This is useful for determining the latency between when stimulation is requested and when it is actually applied. This is done by computing the difference in time between the rising edges of &#039;&#039;ImplantStimulation&#039;&#039; and &#039;&#039;RequestedStimulation&#039;&#039; states.&lt;br /&gt;
===PauseStimulation===&lt;br /&gt;
Binary state that pauses stimulation execution without stopping data recording.&lt;br /&gt;
When this state is set to &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, trigger expressions are ignored and no stimulation will be delivered.&lt;br /&gt;
When set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, stimulation resumes normally.&lt;br /&gt;
This allows temporary suspension of stimulation during a recording session without restarting the system.&lt;br /&gt;
==Stimulation Logging==&lt;br /&gt;
When &amp;lt;code&amp;gt;LogStimulationEvents&amp;lt;/code&amp;gt; is enabled, stimulation activity will be written to the Operator Log.&lt;br /&gt;
Logged information includes:&lt;br /&gt;
* Stimulation mode&lt;br /&gt;
* Function definitions&lt;br /&gt;
* Trigger matches&lt;br /&gt;
* Stimulation execution events&lt;br /&gt;
This information is useful for:&lt;br /&gt;
* Debugging stimulation timing&lt;br /&gt;
* Verifying correct function configuration&lt;br /&gt;
* Investigating unexpected stimulation behavior&lt;br /&gt;
==[[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|SCIT]]==&lt;br /&gt;
To help out with creating the BCI2000 parameters, a GUI has been made which should make it easy to translate your stimulation specifications into BCI2000 parameter files. The GUI also visualizes the stimulation from three different perspectives, making it easy to tell if your parameters are really what you want. There is a [[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|Stimulation Configuration tool user reference]] which will further tell you how to use this tool.&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:CortecGUIimg.png|The Cortec GUI which creates BCI2000 parameters from stimulation specifications.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
==Stimulation Latency==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:StimulationModesLatencyCortec.png|Stimulation Latencies for the specified Stimulation Modes.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Tests were conducted for 100 pulses, with an ISI of 10 seconds.&lt;br /&gt;
Stimulation latency numbers:&lt;br /&gt;
*Persistent functions: &#039;&#039;&#039;13 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Persistent commands: &#039;&#039;&#039;11 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Volatile commands: &#039;&#039;&#039;60 ± 30 ms&#039;&#039;&#039;. Split into the 2 groups, the lower one is &#039;&#039;&#039;48 ± 3 ms&#039;&#039;&#039; and the higher one is &#039;&#039;&#039;174 ± 3 ms&#039;&#039;&#039;&lt;br /&gt;
As explained above, volatile commands are uploaded right before stimulation, which leads to the increased latency and jitter.&lt;br /&gt;
==Template Parameter Files==&lt;br /&gt;
The following &amp;lt;code&amp;gt;.prm&amp;lt;/code&amp;gt; files are &#039;&#039;&#039;stimulation parameter fragments&#039;&#039;&#039; — they contain only the Stimulation section (&amp;lt;code&amp;gt;EnableStimulation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StimulationMode&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MeasureImpedance&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LogStimulationEvents=1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt;). Load one on top of an existing CortecADC configuration in the BCI2000 config window to swap in a stimulation paradigm without overwriting your source/storage/visualization settings.&lt;br /&gt;
===Volatile Commands (StimulationMode = 0)===&lt;br /&gt;
* [https://bci2000.org/downloads/doc/complex_stim.prm complex_stim.prm] — &#039;&#039;&#039;Complex multi-function stimulation paradigm.&#039;&#039;&#039; 20-function StimulationPulses matrix mixing pause and stim functions, monopolar (cathode=0/ground) and multi-electrode anode/cathode lists, amplitudes 50–300µA, durations 50–500µs, and reps up to 255 × 100. Two triggers: &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt; runs functions [1, 2] with CommandRepetition=5; &amp;lt;code&amp;gt;StimulusCode==2&amp;lt;/code&amp;gt; runs functions [3…20] once. Useful for exercising the volatile-mode flexibility on a long, structured command.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/stim_100Hz_1min.prm stim_100Hz_1min.prm] — &#039;&#039;&#039;1-minute 100 Hz volatile stim train, three electrode targets.&#039;&#039;&#039; Three &amp;quot;100Hz&amp;quot; stimulation functions (FunctionID 1/2/3) all 250–150µA, 200µs, 100 pulses × 60 bursts (≈1 min at 100 Hz each). Triggers labeled &#039;&#039;&#039;ANT&#039;&#039;&#039;, &#039;&#039;&#039;HPC&#039;&#039;&#039;, and &#039;&#039;&#039;Cortical1&#039;&#039;&#039; map &amp;lt;code&amp;gt;StimulusCode==1/2/3&amp;lt;/code&amp;gt; to those functions, so the same 100 Hz / 1 min train can be steered to anterior thalamus, hippocampus, or cortical electrodes.&lt;br /&gt;
===Persistent Command (StimulationMode = 1)===&lt;br /&gt;
* [https://bci2000.org/downloads/doc/persistant_100Hz_1function.prm persistant_100Hz_1function.prm] — &#039;&#039;&#039;Single-function 100 Hz preloaded persistent command.&#039;&#039;&#039; One stimulation function &amp;quot;100Hz&amp;quot; (250µA, 200µs, anode 1 / cathode 2, 200 pulses × 30 bursts ≈ 1 min of 100 Hz). One trigger &amp;quot;Sequence1&amp;quot; on &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt;, CommandRepetition=1. Demonstrates the simplest persistent-command setup: preload once, fire on cue.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/stim_1Hz_1min.prm stim_1Hz_1min.prm] — &#039;&#039;&#039;1 Hz × 1 min persistent-command train.&#039;&#039;&#039; Two functions, &amp;quot;1Hz&amp;quot; and &amp;quot;pause&amp;quot;: a 250µA / 250µs single pulse (anode 1 / cathode 2) and a ~990 ms pause (IsPause=1, duration 990,000µs). One trigger &amp;quot;1Hz&amp;quot; on &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt; runs [1Hz, pause] with CommandRepetition=60 → 60 pulses spaced ~1 s apart = 1 Hz for 1 minute.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/stim_5Hz_1min.prm stim_5Hz_1min.prm] — &#039;&#039;&#039;5 Hz × 1 min persistent-command train.&#039;&#039;&#039; Same structure as the 1 Hz file but with a ~190 ms pause (190,000µs); trigger on &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt; with CommandRepetition=300 → 300 pulses at ~200 ms spacing = 5 Hz for 1 minute.&lt;br /&gt;
===Persistent Functions (StimulationMode = 2)===&lt;br /&gt;
* [https://bci2000.org/downloads/doc/persistant_function_single_pulse.prm persistant_function_single_pulse.prm] — &#039;&#039;&#039;Four indexed single-pulse persistent functions.&#039;&#039;&#039; Functions SinglePulse1–4 vary independently in amplitude (250 / 375 / 250 / 125 µA), pulse duration (250 / 250 / 200 / 500 µs), and electrode pair (10/11, 1/2, 3/5, 7/8). Triggers map &amp;lt;code&amp;gt;StimulusCode==1…4&amp;lt;/code&amp;gt; directly to FunctionID 1…4 so each StimulusCode value fires a different preloaded single pulse — ideal for rapid iteration over a small set of distinct pulses.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/singlePulse.prm singlePulse.prm] — &#039;&#039;&#039;16 indexed single-pulse persistent functions, one per bipolar pair.&#039;&#039;&#039; 16-function StimulationPulses matrix of 250µA / 250µs single pulses across electrode pairs 1/2 … 15/16, plus an 8-vs-8 final function. Triggers map &amp;lt;code&amp;gt;StimulusCode==1…16&amp;lt;/code&amp;gt; 1:1 onto FunctionID 1…16 (CommandRepetition=1) so each StimulusCode value fires a single pulse on its corresponding pair.&lt;br /&gt;
===Matrix Parameter Files (.bmt)===&lt;br /&gt;
&amp;lt;code&amp;gt;.bmt&amp;lt;/code&amp;gt; files are BCI2000 matrix parameter exports. Load one into a matrix parameter (e.g., &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;). These templates only populate the corresponding matrix; everything else in the configuration (StimulationMode, triggers, ReferenceCh, etc.) is unaffected, so they can be reused across any stimulation mode.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/SinglePulse_withPause.bmt SinglePulse_withPause.bmt] — StimulationPulses matrix with four functions in sequence: a 1 s leading pause, a 250µA / 250µs single pulse on anode 1 / cathode 2, a 250µA / 250µs single pulse on anode 3 / cathode 5, and a 2.5 s inter-stimulation pause. Demonstrates how to interleave pause functions with stimulation in a single command.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/100Hz.bmt 100Hz.bmt] — StimulationPulses matrix with three functions: a 250µA / 200µs 100 Hz train (anode 1 / cathode 2, 100 pulses × 60 bursts), a 1 s pause (amplitude 0, dead zone 1 = 1,000,000µs), and a second 150µA / 200µs 100 Hz train (anodes 3,4 / cathodes 5,6, 100 pulses × 60 bursts). Use for two-train protocols separated by a fixed pause.&lt;br /&gt;
==µZeus==&lt;br /&gt;
In order to use the new µZeus headpiece simply change the BICVERSION number on line 12 of the CMakeList.txt located in the project folder to use version 274 of the API. ie.,&lt;br /&gt;
&amp;lt;code&amp;gt;set(BICAPI_VERSION 274)&amp;lt;/code&amp;gt;&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12450</id>
		<title>Contributions:CortecADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12450"/>
		<updated>2026-05-14T22:06:45Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CorTec_BrainInterchange.png|400px|thumb|right|CorTec Brain Interchange Implant]]&lt;br /&gt;
CortecADC is a source module that allows for intra-cranial recording and stimulating over 32 channels via a fully implantable device. It is intended for long-term measurement of neural activity and electrical stimulation of brain tissue. See the [https://www.cortec-neuro.com/solutions/complete-system/ CorTec site] for more information.&lt;br /&gt;
&#039;&#039;&#039;See the [[CortecExperience]] page for user tutorials and a broad overview!&#039;&#039;&#039; After viewing the [[CortecExperience]] page, refer to this page for detailed instructions.&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter.org)&lt;br /&gt;
* William Engelhardt (engelhardt@neurotechcenter.org)&lt;br /&gt;
* Alexander Belsten (belsten@neurotechcenter.org)&lt;br /&gt;
* Markus Adamek (adamek@neurotechcenter.org)&lt;br /&gt;
* Christian Stolle (christian.stolle@cortec-neuro.com)&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 6266&lt;br /&gt;
*Tested under: 9282&lt;br /&gt;
*Known to compile under: 9282&lt;br /&gt;
*Broken since: --&lt;br /&gt;
===BCI2000 Version History===&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Date !! Revision !! Note !! Contributor&lt;br /&gt;
|-&lt;br /&gt;
!11/29/2018&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R5829&lt;br /&gt;
|Initial untested version&lt;br /&gt;
|Adamek&lt;br /&gt;
|-&lt;br /&gt;
!04/19/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6271&lt;br /&gt;
|First working version&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!07/22/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6339&lt;br /&gt;
|Changed &#039;&#039;ImplantLostSample&#039;&#039; from a BCI2000 state to a stream, so it can record individual sample loss (instead of over the whole block)&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!01/01/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7133&lt;br /&gt;
|Updated API to version 1.0.200.&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!03/08/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7251&lt;br /&gt;
|Stimulation functionality added&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!05/19/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7367&lt;br /&gt;
|Impedance measurement enabled&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!10/26/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Stimulation latency vastly improved&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!02/20/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7847&lt;br /&gt;
|Version 1.0.230 added. Can change between versions in CMakeLists.txt file&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!08/09/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8313&lt;br /&gt;
|Version 1.0.238 added&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!01/17/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Interpolation filter added to interpolate lost samples&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!06/25/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8915&lt;br /&gt;
|All listener states were changed to events&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!04/13/2026&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R9xxx&lt;br /&gt;
|Refactored stimulation to be more in line with Cortec and BCI2000 standards.&lt;br /&gt;
|Nicholas Luczak&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
===Cortec API Version History===&lt;br /&gt;
Cortec is continually updating their devices with new API versions. In BCI2000, we currently support versions 1.0.200, 1.0.230, and 1.0.238. Each Brain Interchange Communication unit (BIC) is only compatible with one API version. To find your compatible version, connect the USB drive that comes with your BIC. Look under:&lt;br /&gt;
# &#039;&#039;&#039;Software folder&#039;&#039;&#039;: Each executable has the API version. E.g., &amp;lt;code&amp;gt;Bicapi_setup_1.0.200-bicapi-setup-1.0.200-rev35926.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Manuals foder&#039;&#039;&#039;: &#039;&#039;Appendix1_BIC_Application_Software_Short_Manual.pdf&#039;&#039;. On page 3, in Table 1, the third row contains the compatible version.&lt;br /&gt;
Here are some differences between the versions. As the device is always improving, the newest version will have the most features.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Features !! 1.0.200 !! 1.0.230 !! 1.0.238 !! 1.0.260&lt;br /&gt;
|-&lt;br /&gt;
!Matlab API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!C/C++ API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Stimulation modes&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!ASIC Noise Detection Mode&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Monopolar stimulation (Ch → GND)&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Measure GND impedances&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Self-tests&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Low noise recording&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
===Known Issues===&lt;br /&gt;
* Lost samples - The &amp;lt;code&amp;gt;ImplantLostSamples&amp;lt;/code&amp;gt; state records what samples are lost, and their locations. Lost samples are replaced with the previous valid sample for all channels. In offline analysis, be sure to remove these samples and replace them with interpolates.&lt;br /&gt;
* The Brain Interchange Communication Unit has been seen to work with certain USB inputs, and not with others. If you are experiencing connection issues, try using a different USB port.&lt;br /&gt;
==Installation==&lt;br /&gt;
# Install BCI2000&lt;br /&gt;
# Insert the Cortec USB drive that comes with the Brain Interchange (BIC) device. Under &#039;&#039;Software&#039;&#039;, run the &#039;&#039;Bicapi_setup...&#039;&#039; executable&lt;br /&gt;
# Run a batch file with CortecADC as your Signal Source!&lt;br /&gt;
# If you receive an error, and it states your API version is incorrect, you need to change it. Locate the &#039;&#039;CMakeLists.txt&#039;&#039; under &amp;lt;code&amp;gt;BCI2000/src/private/SignalSource/Cortec&amp;lt;/code&amp;gt;. You must change Line 12, where it states &amp;lt;code&amp;gt;set(BICAPI_VERSION 200)&amp;lt;/code&amp;gt;. Change 200 to 230 or 238, depending on your device (see [[#Cortec Version History | details above]]).&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:CortecSourceParameters.jpg|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the CortecADC]]&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. In the current implementation, this parameter cannot be edited, and will default to how many channels are available from the implant.&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block.&lt;br /&gt;
Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated. For example, at 1000 Hz sampling and a SampleBlockSize of 20, the system (e.g., source signal display, signal processing, and stimulus presentation) will be updated 50 times per second.&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. This parameter cannot be edited, and will default to the sampling rate available from the implant.&lt;br /&gt;
In case you are experiencing problems by higher sampling rates (e.g., data loss, jerky display, etc.), increase the SampleBlockSize so that you are updating the system less frequently (usually, updating the system 20-30 times per second is sufficient for most applications), and increase Visualize-&amp;gt;VisualizeSourceDecimation. This parameter will decrease the number of samples per second that are actually drawn in the Source display.&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel.&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel.&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel.&lt;br /&gt;
===LogCortecBinaryFiles===&lt;br /&gt;
Enable or disable binary logging of raw CorTec communication data.&lt;br /&gt;
When enabled, a binary log file is written to the BCI2000 session directory with the name:&lt;br /&gt;
&amp;lt;code&amp;gt;YYYYMMDD_HHMMSS_CortecAdcLog.bin&amp;lt;/code&amp;gt;&lt;br /&gt;
This file contains raw communication packets between the Brain Interchange Communication unit and the implant and is primarily useful for low-level debugging and support from CorTec.&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; (enabled)&lt;br /&gt;
Disable this parameter if binary logs are not needed or disk space usage is a concern.&lt;br /&gt;
===LogStimulationEvents===&lt;br /&gt;
Enable logging of stimulation configuration and execution events to the Operator Log.&lt;br /&gt;
When enabled, detailed information about stimulation functions, trigger evaluation, and stimulation execution will be printed using &amp;lt;code&amp;gt;bciout&amp;lt;/code&amp;gt; messages.&lt;br /&gt;
This is useful for debugging stimulation timing and verifying correct parameter interpretation.&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (disabled)&lt;br /&gt;
===ReferenceCh===&lt;br /&gt;
This list defines what channels will be used as reference. This list is uploaded to the device and set in hardware, effecting the raw bio-signal data that is recorded by BCI2000. If you do not want to effect the raw bio-signal data that is recorded, you can use the [https://www.bci2000.org/mediawiki/index.php/User_Reference:SpatialFilter spatial filter]. If this parameter is set to auto, no reference channels are used. It is strongly recommended to use at least one reference channel.&lt;br /&gt;
===AmplificationFactor===&lt;br /&gt;
Amplification factor that is applied to the recorded data on the implant. The choices are 39.5, 45.5, 51.5, 57.5 db.&lt;br /&gt;
===UseGround===&lt;br /&gt;
Enable to use the ground electrode while measuring. This setting can be overwritten during stimulation, depending if the ground electrode is being used or not. For example, if you have enabled this parameter but don&#039;t have &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;Destination ch&amp;lt;/code&amp;gt; list in the StimulationTriggers parameter, when you are stimulating you will not be using the ground electrode. Once stimulation is done, this parameter&#039;s settings are used again.&lt;br /&gt;
===SaveInfoFile===&lt;br /&gt;
Enable to save a text file, named the same as the data file run. It will contain the timestamp, amplification factor used in the run, and reference channels used. If the Impedance is measured, the impedance values will be saved to this file regardless of if this parameter is enabled.&lt;br /&gt;
===LogPacketErrors===&lt;br /&gt;
Enable to save the packet loss errors to the System Log. Helpful for debugging, however can get overwhelming if there are a lot of lost samples. The System Log can be programmatically saved by appending &amp;lt;code&amp;gt;--SystemLogFile=SOME_FILE.TXT&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;Startup system localhost&amp;lt;/code&amp;gt; line in your batch file.&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
The figure below summarizes the BCI2000 stimulation paradigm used by CortecADC. A BCI2000 expression (typically based on &amp;lt;code&amp;gt;StimulusCode&amp;lt;/code&amp;gt;) acts as a &#039;&#039;&#039;Stimulation Trigger&#039;&#039;&#039;. When a trigger evaluates true, one or more &#039;&#039;&#039;Stimulation Commands&#039;&#039;&#039; are executed. Each Stimulation Command is composed of one or more &#039;&#039;&#039;Stimulation Functions&#039;&#039;&#039; (with optional bursts, pauses, and repetitions), and every Stimulation Function is defined by a &#039;&#039;&#039;Stimulation Pulse&#039;&#039;&#039; with pulse amplitude, pulse duration, and dead-zone parameters. Use this figure as a mental model for interpreting the &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt; parameters described below.&lt;br /&gt;
[[File:StimDefinition_BCI2000.png|1000px|thumb|center|upright=2.5|Figure 2. Summary of the BCI2000 stimulation paradigm. A BCI2000 trigger expression (top, based on StimulusCode) launches a Stimulation Command (red, left), which is built from repeating Stimulation Functions, optional bursts, and pauses. Each Stimulation Function is defined by a Stimulation Pulse (blue, right), parameterized by Pulse Amplitude, Pulse Duration, Dead Zone 0, and Dead Zone 1.]]&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:CortecADC_stimulation_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationpulses_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationtriggers_parm1.PNG&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&amp;lt;!-- TODO (Nick): replace the three stimulation parameter screenshots above with refreshed images per docx item 3a. --&amp;gt;&lt;br /&gt;
===EnableStimulation===&lt;br /&gt;
This parameter enables/disables stimulation.&lt;br /&gt;
===StimulationMode===&lt;br /&gt;
The BIC has 3 stimulation modes. Each one has limitations. Here is a brief summary of how to use each one:&lt;br /&gt;
#Volatile Commands: The most flexible mode, allowing stimulation commands to be defined with virtually no size constraints. However, the stimulation configuration must be uploaded immediately before execution, which introduces additional latency. Furthermore, the configuration is cleared after each command, resulting in increased latency for repeated executions. This mode is best suited for iterating across multiple stimulation configurations and designing complex stimulation paradigms.&lt;br /&gt;
[[File:VolatileCommand.png|1000px|thumb|center|upright=2.5|Figure 3. Figure demonstrating volatile command functionality]]&lt;br /&gt;
#Persistent Command: This preloading mode enables uploading up to 16 stimulation functions to the device and executing them in a predefined order (the list of FunctionID(s) in StimulationTriggers must be the same). The stimulation command remains in memory after execution and can be repeated, making it best suited for delivering continuous or continuously repeated stimulation.&lt;br /&gt;
#Persistent Functions: This preloading mode enables uploading up to 16 stimulation functions to the device and executing them individually by calling the stimulation function ID. The device executes only one stimulation function (the indexed one) without repetition. This mode is best suited for rapidly iterating over subsets of stimulation pulses in single-pulse stimulation settings.&lt;br /&gt;
[[File:PersistantFunction.png|1000px|thumb|center|upright=2.5|Figure 4. Figure demonstrating Persistant Function functionality]]&lt;br /&gt;
&amp;lt;!-- TODO (Nick): per docx item 3e, edit PersistantFunction.png internally so the orange axis label currently reading &amp;quot;Source code&amp;quot; reads &amp;quot;StimulusCode&amp;quot;. --&amp;gt;&lt;br /&gt;
There cannot be any train settings (Train frequency and Train repetitions), so the StimulationTriggers must not have those rows. Also, StimulationTriggers must not have more than 16 columns, as that is the highest number of configurations that can be stored on the device.&lt;br /&gt;
Persistent Command and Functions modes have a lower latency because the stimulation is pre-uploaded. All modes are available to give you the highest amount of flexiblity with the BIC. [[#Stimulation Latency|See below for more details on latency.]]&lt;br /&gt;
===MeasureImpedance===&lt;br /&gt;
When enabled, the impedances of the used electrodes are printed when you set the configuration. All electrodes that are being recorded will conduct the impedance measurement. The impedances are shown to the user and also saved in the data directory.&lt;br /&gt;
===StimulationPulses===&lt;br /&gt;
This parameter defines stimulation &#039;&#039;functions&#039;&#039;. Each column defines a stimulation waveform and electrode configuration.&lt;br /&gt;
Each function consists of:&lt;br /&gt;
* Pulse waveform parameters&lt;br /&gt;
* Electrode mapping&lt;br /&gt;
* Repetition behavior&lt;br /&gt;
Rows are defined as follows:&lt;br /&gt;
====FunctionID====&lt;br /&gt;
Integer identifier for this stimulation function. This ID is referenced in the &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
====Pulse Amplitude====&lt;br /&gt;
Amplitude of the stimulation pulse in µA.&lt;br /&gt;
Valid range:&lt;br /&gt;
0 to 6120 µA&lt;br /&gt;
====Pulse Duration====&lt;br /&gt;
Duration of the main pulse in µs.&lt;br /&gt;
Valid range:&lt;br /&gt;
10 to 2550 µs&lt;br /&gt;
====Dead Zone 0====&lt;br /&gt;
Pause between main pulse and counter pulse.&lt;br /&gt;
====Dead Zone 1====&lt;br /&gt;
Pause after pulse delivery.&lt;br /&gt;
====Anode(s)====&lt;br /&gt;
Embedded list specifying source electrodes.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code&amp;gt;{ list 1 18 19 }&amp;lt;/code&amp;gt;&lt;br /&gt;
====Cathode(s)====&lt;br /&gt;
Embedded list specifying return electrodes.&lt;br /&gt;
Use &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; to reference ground.&lt;br /&gt;
====Pulse Repetition====&lt;br /&gt;
Number of times the pulse is repeated within a function.&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
====Burst Repetition====&lt;br /&gt;
Number of times the function is repeated.&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
Defines when stimulation functions are executed.&lt;br /&gt;
Each column contains:&lt;br /&gt;
====Trigger====&lt;br /&gt;
A valid BCI2000 expression.&lt;br /&gt;
When this expression evaluates to true, the associated stimulation function(s) are executed.&lt;br /&gt;
====FunctionID(s)====&lt;br /&gt;
List of FunctionIDs that should execute when the trigger evaluates true.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
StimulusCode==1   { list 1 3 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This means:&lt;br /&gt;
Execute FunctionID 1 followed by FunctionID 3 whenever the trigger becomes true.&lt;br /&gt;
Note:&lt;br /&gt;
Electrode configuration and repetition settings are defined in &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;, not here.&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, such as device type, device ID, and the firmware version.&lt;br /&gt;
===StateInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information regarding state units and their multiplier. The device provides information such as humidity, temperature, control value, etc., which are recorded in BCI2000 states (see state information on this page for a complete enumeration of states). The device provides these values with floats, but BCI2000 states can only be integers. The multipliers defined in this parameter are used to increase the amount of precision in the state values. To approximately recover the original float values with the units defined in this parameter, divide each state by its corresponding multiplier.&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information returned from the Cortec implant. The device provides this data in floating point numbers, however BCI2000 can only record integers to it&#039;s states. To maintain some precision, these floats are multiplied by constants, then recorded to the states as integers. To approximately recover the original data, divide the state by its corresponding constant. Constants are shown in the following table.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:right;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
! State&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot; | Constant&lt;br /&gt;
|-&lt;br /&gt;
| ImplantVoltage&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantHumidity&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantControlValue&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantPrimaryCoilCurrent&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantTemperature&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|}&lt;br /&gt;
===ImplantLostSample===&lt;br /&gt;
The communication protocol the device uses does not re-send lost data. This state annotates what samples were lost in the bio-signal data. Currently, lost samples are made up by duplicating the previous sample.&lt;br /&gt;
===ImplantVoltage===&lt;br /&gt;
16 bit state that changes when new supply voltage value is received from the implant. After dividing the integer state value by the the voltage multiplier defined in the StateInfo parameter, the units are in volts.&lt;br /&gt;
===ImplantHumidity===&lt;br /&gt;
16 bit state that changes when new humidity value is received from the implant. Units in %rh.&lt;br /&gt;
===ImplantControlValue===&lt;br /&gt;
16 bit state that changes when new current control value is received from the external unit. The power of the implant is controlled by the external unit. The control value provides a measure of how good the coupling between the two coils is and how much more power can be provided if necessary.&lt;br /&gt;
The value is between 0.0 and 100.0 percent, where 0.0 translates to no power and 100.0 translates to maximum power applied.&lt;br /&gt;
===ImplantPrimaryCoilCurrent===&lt;br /&gt;
16 bit state that change when new primary coil current value is received from the external unit. The primary coil refers to the coil inside the head piece of the external unit. Units are mA.&lt;br /&gt;
===ImplantTemperature===&lt;br /&gt;
16 bit state that changes when new temperature value is received from the implant. Units are degrees Celsius.&lt;br /&gt;
===ImplantStimulation===&lt;br /&gt;
Binary state that changes when the device reports that it is stimulating.&lt;br /&gt;
===ImplantStimulationBursts===&lt;br /&gt;
Updates when the device reports that stimulation functions have finished. Should increment during a stimulation train.&lt;br /&gt;
===ImplantRfQuality===&lt;br /&gt;
8 bit state that reports the antenna quality as reported from the rf-link in dBm. &#039;&#039;&#039;&#039;&#039;To obtain the original value, subtract by 128 (2^8)&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
===RequestedStimulation===&lt;br /&gt;
Binary state that records when a stimulation trigger expression evaluates true. State remains true for the duration triggered stimulation. This is useful for determining the latency between when stimulation is requested and when it is actually applied. This is done by computing the difference in time between the rising edges of &#039;&#039;ImplantStimulation&#039;&#039; and &#039;&#039;RequestedStimulation&#039;&#039; states.&lt;br /&gt;
===PauseStimulation===&lt;br /&gt;
Binary state that pauses stimulation execution without stopping data recording.&lt;br /&gt;
When this state is set to &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, trigger expressions are ignored and no stimulation will be delivered.&lt;br /&gt;
When set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, stimulation resumes normally.&lt;br /&gt;
This allows temporary suspension of stimulation during a recording session without restarting the system.&lt;br /&gt;
==Stimulation Logging==&lt;br /&gt;
When &amp;lt;code&amp;gt;LogStimulationEvents&amp;lt;/code&amp;gt; is enabled, stimulation activity will be written to the Operator Log.&lt;br /&gt;
Logged information includes:&lt;br /&gt;
* Stimulation mode&lt;br /&gt;
* Function definitions&lt;br /&gt;
* Trigger matches&lt;br /&gt;
* Stimulation execution events&lt;br /&gt;
This information is useful for:&lt;br /&gt;
* Debugging stimulation timing&lt;br /&gt;
* Verifying correct function configuration&lt;br /&gt;
* Investigating unexpected stimulation behavior&lt;br /&gt;
==[[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|SCIT]]==&lt;br /&gt;
To help out with creating the BCI2000 parameters, a GUI has been made which should make it easy to translate your stimulation specifications into BCI2000 parameter files. The GUI also visualizes the stimulation from three different perspectives, making it easy to tell if your parameters are really what you want. There is a [[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|Stimulation Configuration tool user reference]] which will further tell you how to use this tool.&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:CortecGUIimg.png|The Cortec GUI which creates BCI2000 parameters from stimulation specifications.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
==Stimulation Latency==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:StimulationModesLatencyCortec.png|Stimulation Latencies for the specified Stimulation Modes.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Tests were conducted for 100 pulses, with an ISI of 10 seconds.&lt;br /&gt;
Stimulation latency numbers:&lt;br /&gt;
*Persistent functions: &#039;&#039;&#039;13 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Persistent commands: &#039;&#039;&#039;11 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Volatile commands: &#039;&#039;&#039;60 ± 30 ms&#039;&#039;&#039;. Split into the 2 groups, the lower one is &#039;&#039;&#039;48 ± 3 ms&#039;&#039;&#039; and the higher one is &#039;&#039;&#039;174 ± 3 ms&#039;&#039;&#039;&lt;br /&gt;
As explained above, volatile commands are uploaded right before stimulation, which leads to the increased latency and jitter.&lt;br /&gt;
==Template Parameter Files==&lt;br /&gt;
The following &amp;lt;code&amp;gt;.prm&amp;lt;/code&amp;gt; files are &#039;&#039;&#039;stimulation parameter fragments&#039;&#039;&#039; — they contain only the Stimulation section (&amp;lt;code&amp;gt;EnableStimulation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StimulationMode&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MeasureImpedance&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;LogStimulationEvents=1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt;). Load one on top of an existing CortecADC configuration in the BCI2000 config window to swap in a stimulation paradigm without overwriting your source/storage/visualization settings.&lt;br /&gt;
===Volatile Commands (StimulationMode = 0)===&lt;br /&gt;
* [https://bci2000.org/downloads/doc/complex_stim.prm complex_stim.prm] — &#039;&#039;&#039;Complex multi-function stimulation paradigm.&#039;&#039;&#039; 20-function StimulationPulses matrix mixing pause and stim functions, monopolar (cathode=0/ground) and multi-electrode anode/cathode lists, amplitudes 50–300µA, durations 50–500µs, and reps up to 255 × 100. Two triggers: &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt; runs functions [1, 2] with CommandRepetition=5; &amp;lt;code&amp;gt;StimulusCode==2&amp;lt;/code&amp;gt; runs functions [3…20] once. Useful for exercising the volatile-mode flexibility on a long, structured command.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/stim_100Hz_1min.prm stim_100Hz_1min.prm] — &#039;&#039;&#039;1-minute 100 Hz volatile stim train, three electrode targets.&#039;&#039;&#039; Three &amp;quot;100Hz&amp;quot; stimulation functions (FunctionID 1/2/3) all 250–150µA, 200µs, 100 pulses × 60 bursts (≈1 min at 100 Hz each). Triggers labeled &#039;&#039;&#039;ANT&#039;&#039;&#039;, &#039;&#039;&#039;HPC&#039;&#039;&#039;, and &#039;&#039;&#039;Cortical1&#039;&#039;&#039; map &amp;lt;code&amp;gt;StimulusCode==1/2/3&amp;lt;/code&amp;gt; to those functions, so the same 100 Hz / 1 min train can be steered to anterior thalamus, hippocampus, or cortical electrodes.&lt;br /&gt;
===Persistent Command (StimulationMode = 1)===&lt;br /&gt;
* [https://bci2000.org/downloads/doc/persistant_100Hz_1function.prm persistant_100Hz_1function.prm] — &#039;&#039;&#039;Single-function 100 Hz preloaded persistent command.&#039;&#039;&#039; One stimulation function &amp;quot;100Hz&amp;quot; (250µA, 200µs, anode 1 / cathode 2, 200 pulses × 30 bursts ≈ 1 min of 100 Hz). One trigger &amp;quot;Sequence1&amp;quot; on &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt;, CommandRepetition=1. Demonstrates the simplest persistent-command setup: preload once, fire on cue.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/stim_1Hz_1min.prm stim_1Hz_1min.prm] — &#039;&#039;&#039;1 Hz × 1 min persistent-command train.&#039;&#039;&#039; Two functions, &amp;quot;1Hz&amp;quot; and &amp;quot;pause&amp;quot;: a 250µA / 250µs single pulse (anode 1 / cathode 2) and a ~990 ms pause (IsPause=1, duration 990,000µs). One trigger &amp;quot;1Hz&amp;quot; on &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt; runs [1Hz, pause] with CommandRepetition=60 → 60 pulses spaced ~1 s apart = 1 Hz for 1 minute.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/stim_5Hz_1min.prm stim_5Hz_1min.prm] — &#039;&#039;&#039;5 Hz × 1 min persistent-command train.&#039;&#039;&#039; Same structure as the 1 Hz file but with a ~190 ms pause (190,000µs); trigger on &amp;lt;code&amp;gt;StimulusCode==1&amp;lt;/code&amp;gt; with CommandRepetition=300 → 300 pulses at ~200 ms spacing = 5 Hz for 1 minute.&lt;br /&gt;
===Persistent Functions (StimulationMode = 2)===&lt;br /&gt;
* [https://bci2000.org/downloads/doc/persistant_function_single_pulse.prm persistant_function_single_pulse.prm] — &#039;&#039;&#039;Four indexed single-pulse persistent functions.&#039;&#039;&#039; Functions SinglePulse1–4 vary independently in amplitude (250 / 375 / 250 / 125 µA), pulse duration (250 / 250 / 200 / 500 µs), and electrode pair (10/11, 1/2, 3/5, 7/8). Triggers map &amp;lt;code&amp;gt;StimulusCode==1…4&amp;lt;/code&amp;gt; directly to FunctionID 1…4 so each StimulusCode value fires a different preloaded single pulse — ideal for rapid iteration over a small set of distinct pulses.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/singlePulse.prm singlePulse.prm] — &#039;&#039;&#039;16 indexed single-pulse persistent functions, one per bipolar pair.&#039;&#039;&#039; 16-function StimulationPulses matrix of 250µA / 250µs single pulses across electrode pairs 1/2 … 15/16, plus an 8-vs-8 final function. Triggers map &amp;lt;code&amp;gt;StimulusCode==1…16&amp;lt;/code&amp;gt; 1:1 onto FunctionID 1…16 (CommandRepetition=1) so each StimulusCode value fires a single pulse on its corresponding pair.&lt;br /&gt;
===Matrix Parameter Files (.bmt)===&lt;br /&gt;
&amp;lt;code&amp;gt;.bmt&amp;lt;/code&amp;gt; files are BCI2000 matrix parameter exports. Load one into a matrix parameter (e.g., &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;). These templates only populate the corresponding matrix; everything else in the configuration (StimulationMode, triggers, ReferenceCh, etc.) is unaffected, so they can be reused across any stimulation mode.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/SinglePulse_withPause.bmt SinglePulse_withPause.bmt] — StimulationPulses matrix with four functions in sequence: a 1 s leading pause, a 250µA / 250µs single pulse on anode 1 / cathode 2, a 250µA / 250µs single pulse on anode 3 / cathode 5, and a 2.5 s inter-stimulation pause. Demonstrates how to interleave pause functions with stimulation in a single command.&lt;br /&gt;
* [https://bci2000.org/downloads/doc/100Hz.bmt 100Hz.bmt] — StimulationPulses matrix with three functions: a 250µA / 200µs 100 Hz train (anode 1 / cathode 2, 100 pulses × 60 bursts), a 1 s pause (amplitude 0, dead zone 1 = 1,000,000µs), and a second 150µA / 200µs 100 Hz train (anodes 3,4 / cathodes 5,6, 100 pulses × 60 bursts). Use for two-train protocols separated by a fixed pause.&lt;br /&gt;
==µZeus==&lt;br /&gt;
In order to use the new µZeus headpiece simply change the BICVERSION number on line 12 of the CMakeList.txt located in the project folder to use version 274 of the API. ie.,&lt;br /&gt;
&amp;lt;code&amp;gt;set(BICAPI_VERSION 274)&amp;lt;/code&amp;gt;&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=CortecExperience&amp;diff=12449</id>
		<title>CortecExperience</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=CortecExperience&amp;diff=12449"/>
		<updated>2026-05-14T21:12:15Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Canine Surgical Procedure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
=Introduction Video of CorTec Brain Interchange with BCI2000=&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot; dimensions=&amp;quot;900&amp;quot;&amp;gt;https://youtu.be/TMZPQPhRnn8&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Getting Started with Cortec BIC in BCI2000=&lt;br /&gt;
&lt;br /&gt;
#[[Programming Howto:Building and Customizing BCI2000|Install BCI2000]]&lt;br /&gt;
#*Here you will learn how to configure and compile BCI2000 on your own computer.&lt;br /&gt;
&lt;br /&gt;
#[[CortecADC]]&lt;br /&gt;
#*This article steps you through all the available configuration options and information stored with using BCI2000 with the Brain Interchange.&lt;br /&gt;
&lt;br /&gt;
#[[Contributions:XsensMTwLogger]]&lt;br /&gt;
#*This article shows how to combine any BCI2000 source module the XsensMTw device to capture motion simultaneously with electrophysiological signals.&lt;br /&gt;
&lt;br /&gt;
=Canine Surgical Procedure=&lt;br /&gt;
This article presents a brief introduction to surgical protocols for the implantation of the CorTec Brain Interchange. The main objective is to introduce the essential surgical considerations for implanting this device in different animal models. &lt;br /&gt;
&lt;br /&gt;
Download the [https://bci2000.org/downloads/doc/Canine_Cortec_Surgical_Protocol.pdf surgical protocol here].&lt;br /&gt;
&lt;br /&gt;
Download the updated [https://bci2000.org/downloads/doc/Animal_Surgical_Protocol_CorTec_May2026.pdf surgical protocol here].&lt;br /&gt;
&lt;br /&gt;
=Preliminary experience with the CorTec BrainInterchange device in a canine modele=&lt;br /&gt;
This article describes initial work toward an ecosystem for adaptive neuromodulation in humans by documenting the experience of implanting CorTec&#039;s BrainInterchange (BIC) device in a beagle canine and using the BCI2000 environment to interact with the BIC device. It begins with laying out the substantial opportunity presented by a useful, easy-to-use, and widely available hardware/software ecosystem in the current landscape of the field of adaptive neuromodulation, and then describes experience with implantation, software integration, and post-surgical validation of recording of brain signals and implant parameters. Initial experience suggests that the hardware capabilities of the BIC device are fully supported by BCI2000, and that the BIC/BCI2000 device can record and process brain signals during free behavior. With further development and validation, the BIC/BCI2000 ecosystem could become an important tool for research into new adaptive neuromodulation protocols in humans. &lt;br /&gt;
&lt;br /&gt;
Schalk G, Worrell S, Mivalt F, Belsten A, Kim I, Morris JM, Hermes D, Klassen BT, Staff NP, Messina S, Kaufmann T, Rickert J, Brunner P, Worrell GA, Miller KJ. Toward a fully implantable ecosystem for adaptive neuromodulation in humans: Preliminary experience with the CorTec BrainInterchange device in a canine model. Front Neurosci. 2022 Dec 19;16:932782. doi: 10.3389/fnins.2022.932782. PMID: 36601593; PMCID: PMC9806357.&lt;br /&gt;
&lt;br /&gt;
Download the [https://bci2000.org/downloads/doc/Preliminary_experience_with_the_CorTec_BrainInterchange_device_in_a_canine_model.pdf article here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Data Sharing=&lt;br /&gt;
This data recorded is freely available on DANDI and OpenNeuro.&lt;br /&gt;
&lt;br /&gt;
Download the [https://dandiarchive.org/dandiset/000571?pos=1 canine data from DANDI].&lt;br /&gt;
&lt;br /&gt;
Download the [https://openneuro.org/datasets/ds004624/versions/1.0.1 canine data from OpenNeuro].&lt;br /&gt;
&lt;br /&gt;
=Closed-loop Stimulation=&lt;br /&gt;
With BCI2000, it is possible to stimulate with the Brain Interchange based on processed signals from Brain Interchange recordings! BCI2000&#039;s infrastructure was created for closed-loop control, as it processes the recorded activity and can directly use the results to affect the task or stimulation. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;See the [[Closed-Loop Stimulation]] page for more information!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot; dimensions=&amp;quot;900&amp;quot;&amp;gt;https://youtu.be/YIM_YmoHRR8&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To start out, we can review how to conduct a closed-loop brain-computer interface task. This has a very similar pipeline to closed-loop stimulation so it is a good place to start. Review the [[User Tutorial:Mu Rhythm BCI Tutorial|Mu Rhythm tutorial]] for in-depth instructions on how to set it up. &lt;br /&gt;
&lt;br /&gt;
Now that we have the closed-loop task control reviewed, we can move on to closed-loop stimulation. Since CortecADC is a source module, stimulation is conducted in the source module (review the [[User Reference:Filters|Filters]] page for BCI2000 overview). This means we have to carry-over the results from the past signal processing pipeline to the next block. This can be done with States, which stream through all the modules of BCI2000 in a closed-loop fashion. Since Cortec stimulation is controlled with Expressions, a State that was changed due to the processed signal will trigger stimulation. For example, you can use EarlyOffsetExpression available in the [[User Tutorial:StimulusPresentation|StimulusPresentation]] Application module to change stimuli due to a processed signal. You would set up the stimulation to be triggered once the new stimulus is reached, due to EarlyOffsetExpression becoming true.&lt;br /&gt;
&lt;br /&gt;
=Synchronize Inertial Measurement Units with the CorTec Brain Interchange=&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot; dimensions=&amp;quot;900&amp;quot;&amp;gt;https://youtu.be/-SOUX5J1vJE&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Video]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:StimDefinition_BCI2000.png&amp;diff=12448</id>
		<title>File:StimDefinition BCI2000.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:StimDefinition_BCI2000.png&amp;diff=12448"/>
		<updated>2026-05-14T21:05:37Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12447</id>
		<title>Contributions:CortecADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12447"/>
		<updated>2026-05-14T21:05:01Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CorTec_BrainInterchange.png|400px|thumb|right|CorTec Brain Interchange Implant]]&lt;br /&gt;
CortecADC is a source module that allows for intra-cranial recording and stimulating over 32 channels via a fully implantable device. It is intended for long-term measurement of neural activity and electrical stimulation of brain tissue. See the [https://www.cortec-neuro.com/solutions/complete-system/ CorTec site] for more information.&lt;br /&gt;
&#039;&#039;&#039;See the [[CortecExperience]] page for user tutorials and a broad overview!&#039;&#039;&#039; After viewing the [[CortecExperience]] page, refer to this page for detailed instructions.&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter.org)&lt;br /&gt;
* William Engelhardt (engelhardt@neurotechcenter.org)&lt;br /&gt;
* Alexander Belsten (belsten@neurotechcenter.org)&lt;br /&gt;
* Markus Adamek (adamek@neurotechcenter.org)&lt;br /&gt;
* Christian Stolle (christian.stolle@cortec-neuro.com)&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 6266&lt;br /&gt;
*Tested under: 9282&lt;br /&gt;
*Known to compile under: 9282&lt;br /&gt;
*Broken since: --&lt;br /&gt;
===BCI2000 Version History===&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Date !! Revision !! Note !! Contributor&lt;br /&gt;
|-&lt;br /&gt;
!11/29/2018&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R5829&lt;br /&gt;
|Initial untested version&lt;br /&gt;
|Adamek&lt;br /&gt;
|-&lt;br /&gt;
!04/19/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6271&lt;br /&gt;
|First working version&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!07/22/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6339&lt;br /&gt;
|Changed &#039;&#039;ImplantLostSample&#039;&#039; from a BCI2000 state to a stream, so it can record individual sample loss (instead of over the whole block)&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!01/01/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7133&lt;br /&gt;
|Updated API to version 1.0.200.&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!03/08/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7251&lt;br /&gt;
|Stimulation functionality added&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!05/19/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7367&lt;br /&gt;
|Impedance measurement enabled&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!10/26/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Stimulation latency vastly improved&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!02/20/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7847&lt;br /&gt;
|Version 1.0.230 added. Can change between versions in CMakeLists.txt file&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!08/09/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8313&lt;br /&gt;
|Version 1.0.238 added&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!01/17/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Interpolation filter added to interpolate lost samples&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!06/25/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8915&lt;br /&gt;
|All listener states were changed to events&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!04/13/2026&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R9xxx&lt;br /&gt;
|Refactored stimulation to be more in line with Cortec and BCI2000 standards.&lt;br /&gt;
|Nicholas Luczak&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
===Cortec API Version History===&lt;br /&gt;
Cortec is continually updating their devices with new API versions. In BCI2000, we currently support versions 1.0.200, 1.0.230, and 1.0.238. Each Brain Interchange Communication unit (BIC) is only compatible with one API version. To find your compatible version, connect the USB drive that comes with your BIC. Look under:&lt;br /&gt;
# &#039;&#039;&#039;Software folder&#039;&#039;&#039;: Each executable has the API version. E.g., &amp;lt;code&amp;gt;Bicapi_setup_1.0.200-bicapi-setup-1.0.200-rev35926.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Manuals foder&#039;&#039;&#039;: &#039;&#039;Appendix1_BIC_Application_Software_Short_Manual.pdf&#039;&#039;. On page 3, in Table 1, the third row contains the compatible version.&lt;br /&gt;
Here are some differences between the versions. As the device is always improving, the newest version will have the most features.&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Features !! 1.0.200 !! 1.0.230 !! 1.0.238 !! 1.0.260&lt;br /&gt;
|-&lt;br /&gt;
!Matlab API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!C/C++ API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Stimulation modes&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!ASIC Noise Detection Mode&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Monopolar stimulation (Ch → GND)&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Measure GND impedances&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Self-tests&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Low noise recording&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
===Known Issues===&lt;br /&gt;
* Lost samples - The &amp;lt;code&amp;gt;ImplantLostSamples&amp;lt;/code&amp;gt; state records what samples are lost, and their locations. Lost samples are replaced with the previous valid sample for all channels. In offline analysis, be sure to remove these samples and replace them with interpolates.&lt;br /&gt;
* The Brain Interchange Communication Unit has been seen to work with certain USB inputs, and not with others. If you are experiencing connection issues, try using a different USB port.&lt;br /&gt;
==Installation==&lt;br /&gt;
# Install BCI2000&lt;br /&gt;
# Insert the Cortec USB drive that comes with the Brain Interchange (BIC) device. Under &#039;&#039;Software&#039;&#039;, run the &#039;&#039;Bicapi_setup...&#039;&#039; executable&lt;br /&gt;
# Run a batch file with CortecADC as your Signal Source!&lt;br /&gt;
# If you receive an error, and it states your API version is incorrect, you need to change it. Locate the &#039;&#039;CMakeLists.txt&#039;&#039; under &amp;lt;code&amp;gt;BCI2000/src/private/SignalSource/Cortec&amp;lt;/code&amp;gt;. You must change Line 12, where it states &amp;lt;code&amp;gt;set(BICAPI_VERSION 200)&amp;lt;/code&amp;gt;. Change 200 to 230 or 238, depending on your device (see [[#Cortec Version History | details above]]).&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:CortecSourceParameters.jpg|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the CortecADC]]&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. In the current implementation, this parameter cannot be edited, and will default to how many channels are available from the implant.&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block.&lt;br /&gt;
Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated. For example, at 1000 Hz sampling and a SampleBlockSize of 20, the system (e.g., source signal display, signal processing, and stimulus presentation) will be updated 50 times per second.&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. This parameter cannot be edited, and will default to the sampling rate available from the implant.&lt;br /&gt;
In case you are experiencing problems by higher sampling rates (e.g., data loss, jerky display, etc.), increase the SampleBlockSize so that you are updating the system less frequently (usually, updating the system 20-30 times per second is sufficient for most applications), and increase Visualize-&amp;gt;VisualizeSourceDecimation. This parameter will decrease the number of samples per second that are actually drawn in the Source display.&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel.&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel.&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel.&lt;br /&gt;
===LogCortecBinaryFiles===&lt;br /&gt;
Enable or disable binary logging of raw CorTec communication data.&lt;br /&gt;
When enabled, a binary log file is written to the BCI2000 session directory with the name:&lt;br /&gt;
&amp;lt;code&amp;gt;YYYYMMDD_HHMMSS_CortecAdcLog.bin&amp;lt;/code&amp;gt;&lt;br /&gt;
This file contains raw communication packets between the Brain Interchange Communication unit and the implant and is primarily useful for low-level debugging and support from CorTec.&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; (enabled)&lt;br /&gt;
Disable this parameter if binary logs are not needed or disk space usage is a concern.&lt;br /&gt;
===LogStimulationEvents===&lt;br /&gt;
Enable logging of stimulation configuration and execution events to the Operator Log.&lt;br /&gt;
When enabled, detailed information about stimulation functions, trigger evaluation, and stimulation execution will be printed using &amp;lt;code&amp;gt;bciout&amp;lt;/code&amp;gt; messages.&lt;br /&gt;
This is useful for debugging stimulation timing and verifying correct parameter interpretation.&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (disabled)&lt;br /&gt;
===ReferenceCh===&lt;br /&gt;
This list defines what channels will be used as reference. This list is uploaded to the device and set in hardware, effecting the raw bio-signal data that is recorded by BCI2000. If you do not want to effect the raw bio-signal data that is recorded, you can use the [https://www.bci2000.org/mediawiki/index.php/User_Reference:SpatialFilter spatial filter]. If this parameter is set to auto, no reference channels are used. It is strongly recommended to use at least one reference channel.&lt;br /&gt;
===AmplificationFactor===&lt;br /&gt;
Amplification factor that is applied to the recorded data on the implant. The choices are 39.5, 45.5, 51.5, 57.5 db.&lt;br /&gt;
===UseGround===&lt;br /&gt;
Enable to use the ground electrode while measuring. This setting can be overwritten during stimulation, depending if the ground electrode is being used or not. For example, if you have enabled this parameter but don&#039;t have &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;Destination ch&amp;lt;/code&amp;gt; list in the StimulationTriggers parameter, when you are stimulating you will not be using the ground electrode. Once stimulation is done, this parameter&#039;s settings are used again.&lt;br /&gt;
===SaveInfoFile===&lt;br /&gt;
Enable to save a text file, named the same as the data file run. It will contain the timestamp, amplification factor used in the run, and reference channels used. If the Impedance is measured, the impedance values will be saved to this file regardless of if this parameter is enabled.&lt;br /&gt;
===LogPacketErrors===&lt;br /&gt;
Enable to save the packet loss errors to the System Log. Helpful for debugging, however can get overwhelming if there are a lot of lost samples. The System Log can be programmatically saved by appending &amp;lt;code&amp;gt;--SystemLogFile=SOME_FILE.TXT&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;Startup system localhost&amp;lt;/code&amp;gt; line in your batch file.&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
The figure below summarizes the BCI2000 stimulation paradigm used by CortecADC. A BCI2000 expression (typically based on &amp;lt;code&amp;gt;StimulusCode&amp;lt;/code&amp;gt;) acts as a &#039;&#039;&#039;Stimulation Trigger&#039;&#039;&#039;. When a trigger evaluates true, one or more &#039;&#039;&#039;Stimulation Commands&#039;&#039;&#039; are executed. Each Stimulation Command is composed of one or more &#039;&#039;&#039;Stimulation Functions&#039;&#039;&#039; (with optional bursts, pauses, and repetitions), and every Stimulation Function is defined by a &#039;&#039;&#039;Stimulation Pulse&#039;&#039;&#039; with pulse amplitude, pulse duration, and dead-zone parameters. Use this figure as a mental model for interpreting the &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt; parameters described below.&lt;br /&gt;
[[File:StimDefinition_BCI2000.png|1000px|thumb|center|upright=2.5|Figure 2. Summary of the BCI2000 stimulation paradigm. A BCI2000 trigger expression (top, based on StimulusCode) launches a Stimulation Command (red, left), which is built from repeating Stimulation Functions, optional bursts, and pauses. Each Stimulation Function is defined by a Stimulation Pulse (blue, right), parameterized by Pulse Amplitude, Pulse Duration, Dead Zone 0, and Dead Zone 1.]]&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:CortecADC_stimulation_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationpulses_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationtriggers_parm1.PNG&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===EnableStimulation===&lt;br /&gt;
This parameter enables/disables stimulation.&lt;br /&gt;
===StimulationMode===&lt;br /&gt;
The BIC has 3 stimulation modes. Each one has limitations. Here is a brief summary of how to use each one:&lt;br /&gt;
#Volatile Commands: The most flexible mode, allowing stimulation commands to be defined with virtually no size constraints. However, the stimulation configuration must be uploaded immediately before execution, which introduces additional latency. Furthermore, the configuration is cleared after each command, resulting in increased latency for repeated executions. This mode is best suited for iterating across multiple stimulation configurations and designing complex stimulation paradigms.&lt;br /&gt;
[[File:VolatileCommand.png|1000px|thumb|center|upright=2.5|Figure 3. Figure demonstrating volatile command functionality]]&lt;br /&gt;
#Persistent Command: This preloading mode enables uploading up to 16 stimulation functions to the device and executing them in a predefined order (the list of FunctionID(s) in StimulationTriggers must be the same). The stimulation command remains in memory after execution and can be repeated, making it best suited for delivering continuous or continuously repeated stimulation.&lt;br /&gt;
#Persistent Functions: This preloading mode enables uploading up to 16 stimulation functions to the device and executing them individually by calling the stimulation function ID. The device executes only one stimulation function (the indexed one) without repetition. This mode is best suited for rapidly iterating over subsets of stimulation pulses in single-pulse stimulation settings.&lt;br /&gt;
[[File:PersistantFunction.png|1000px|thumb|center|upright=2.5|Figure 4. Figure demonstrating Persistant Function functionality]]&lt;br /&gt;
&lt;br /&gt;
There cannot be any train settings (Train frequency and Train repetitions), so the StimulationTriggers must not have those rows. Also, StimulationTriggers must not have more than 16 columns, as that is the highest number of configurations that can be stored on the device.&lt;br /&gt;
Persistent Command and Functions modes have a lower latency because the stimulation is pre-uploaded. All modes are available to give you the highest amount of flexiblity with the BIC. [[#Stimulation Latency|See below for more details on latency.]]&lt;br /&gt;
===MeasureImpedance===&lt;br /&gt;
When enabled, the impedances of the used electrodes are printed when you set the configuration. All electrodes that are being recorded will conduct the impedance measurement. The impedances are shown to the user and also saved in the data directory.&lt;br /&gt;
===StimulationPulses===&lt;br /&gt;
This parameter defines stimulation &#039;&#039;functions&#039;&#039;. Each column defines a stimulation waveform and electrode configuration.&lt;br /&gt;
Each function consists of:&lt;br /&gt;
* Pulse waveform parameters&lt;br /&gt;
* Electrode mapping&lt;br /&gt;
* Repetition behavior&lt;br /&gt;
Rows are defined as follows:&lt;br /&gt;
====FunctionID====&lt;br /&gt;
Integer identifier for this stimulation function. This ID is referenced in the &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
====Pulse Amplitude====&lt;br /&gt;
Amplitude of the stimulation pulse in µA.&lt;br /&gt;
Valid range:&lt;br /&gt;
0 to 6120 µA&lt;br /&gt;
====Pulse Duration====&lt;br /&gt;
Duration of the main pulse in µs.&lt;br /&gt;
Valid range:&lt;br /&gt;
10 to 2550 µs&lt;br /&gt;
====Dead Zone 0====&lt;br /&gt;
Pause between main pulse and counter pulse.&lt;br /&gt;
====Dead Zone 1====&lt;br /&gt;
Pause after pulse delivery.&lt;br /&gt;
====Anode(s)====&lt;br /&gt;
Embedded list specifying source electrodes.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code&amp;gt;{ list 1 18 19 }&amp;lt;/code&amp;gt;&lt;br /&gt;
====Cathode(s)====&lt;br /&gt;
Embedded list specifying return electrodes.&lt;br /&gt;
Use &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; to reference ground.&lt;br /&gt;
====Pulse Repetition====&lt;br /&gt;
Number of times the pulse is repeated within a function.&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
====Burst Repetition====&lt;br /&gt;
Number of times the function is repeated.&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
Defines when stimulation functions are executed.&lt;br /&gt;
Each column contains:&lt;br /&gt;
====Trigger====&lt;br /&gt;
A valid BCI2000 expression.&lt;br /&gt;
When this expression evaluates to true, the associated stimulation function(s) are executed.&lt;br /&gt;
====FunctionID(s)====&lt;br /&gt;
List of FunctionIDs that should execute when the trigger evaluates true.&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
StimulusCode==1   { list 1 3 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This means:&lt;br /&gt;
Execute FunctionID 1 followed by FunctionID 3 whenever the trigger becomes true.&lt;br /&gt;
Note:&lt;br /&gt;
Electrode configuration and repetition settings are defined in &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;, not here.&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, such as device type, device ID, and the firmware version.&lt;br /&gt;
===StateInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information regarding state units and their multiplier. The device provides information such as humidity, temperature, control value, etc., which are recorded in BCI2000 states (see state information on this page for a complete enumeration of states). The device provides these values with floats, but BCI2000 states can only be integers. The multipliers defined in this parameter are used to increase the amount of precision in the state values. To approximately recover the original float values with the units defined in this parameter, divide each state by its corresponding multiplier.&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information returned from the Cortec implant. The device provides this data in floating point numbers, however BCI2000 can only record integers to it&#039;s states. To maintain some precision, these floats are multiplied by constants, then recorded to the states as integers. To approximately recover the original data, divide the state by its corresponding constant. Constants are shown in the following table.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:right;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
! State&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot; | Constant&lt;br /&gt;
|-&lt;br /&gt;
| ImplantVoltage&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantHumidity&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantControlValue&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantPrimaryCoilCurrent&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantTemperature&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|}&lt;br /&gt;
===ImplantLostSample===&lt;br /&gt;
The communication protocol the device uses does not re-send lost data. This state annotates what samples were lost in the bio-signal data. Currently, lost samples are made up by duplicating the previous sample.&lt;br /&gt;
===ImplantVoltage===&lt;br /&gt;
16 bit state that changes when new supply voltage value is received from the implant. After dividing the integer state value by the the voltage multiplier defined in the StateInfo parameter, the units are in volts.&lt;br /&gt;
===ImplantHumidity===&lt;br /&gt;
16 bit state that changes when new humidity value is received from the implant. Units in %rh.&lt;br /&gt;
===ImplantControlValue===&lt;br /&gt;
16 bit state that changes when new current control value is received from the external unit. The power of the implant is controlled by the external unit. The control value provides a measure of how good the coupling between the two coils is and how much more power can be provided if necessary.&lt;br /&gt;
The value is between 0.0 and 100.0 percent, where 0.0 translates to no power and 100.0 translates to maximum power applied.&lt;br /&gt;
===ImplantPrimaryCoilCurrent===&lt;br /&gt;
16 bit state that change when new primary coil current value is received from the external unit. The primary coil refers to the coil inside the head piece of the external unit. Units are mA.&lt;br /&gt;
===ImplantTemperature===&lt;br /&gt;
16 bit state that changes when new temperature value is received from the implant. Units are degrees Celsius.&lt;br /&gt;
===ImplantStimulation===&lt;br /&gt;
Binary state that changes when the device reports that it is stimulating.&lt;br /&gt;
===ImplantStimulationBursts===&lt;br /&gt;
Updates when the device reports that stimulation functions have finished. Should increment during a stimulation train.&lt;br /&gt;
===ImplantRfQuality===&lt;br /&gt;
8 bit state that reports the antenna quality as reported from the rf-link in dBm. &#039;&#039;&#039;&#039;&#039;To obtain the original value, subtract by 128 (2^8)&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
===RequestedStimulation===&lt;br /&gt;
Binary state that records when a stimulation trigger expression evaluates true. State remains true for the duration triggered stimulation. This is useful for determining the latency between when stimulation is requested and when it is actually applied. This is done by computing the difference in time between the rising edges of &#039;&#039;ImplantStimulation&#039;&#039; and &#039;&#039;RequestedStimulation&#039;&#039; states.&lt;br /&gt;
===PauseStimulation===&lt;br /&gt;
Binary state that pauses stimulation execution without stopping data recording.&lt;br /&gt;
When this state is set to &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, trigger expressions are ignored and no stimulation will be delivered.&lt;br /&gt;
When set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, stimulation resumes normally.&lt;br /&gt;
This allows temporary suspension of stimulation during a recording session without restarting the system.&lt;br /&gt;
==Stimulation Logging==&lt;br /&gt;
When &amp;lt;code&amp;gt;LogStimulationEvents&amp;lt;/code&amp;gt; is enabled, stimulation activity will be written to the Operator Log.&lt;br /&gt;
Logged information includes:&lt;br /&gt;
* Stimulation mode&lt;br /&gt;
* Function definitions&lt;br /&gt;
* Trigger matches&lt;br /&gt;
* Stimulation execution events&lt;br /&gt;
This information is useful for:&lt;br /&gt;
* Debugging stimulation timing&lt;br /&gt;
* Verifying correct function configuration&lt;br /&gt;
* Investigating unexpected stimulation behavior&lt;br /&gt;
==[[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|SCIT]]==&lt;br /&gt;
To help out with creating the BCI2000 parameters, a GUI has been made which should make it easy to translate your stimulation specifications into BCI2000 parameter files. The GUI also visualizes the stimulation from three different perspectives, making it easy to tell if your parameters are really what you want. There is a [[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|Stimulation Configuration tool user reference]] which will further tell you how to use this tool.&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:CortecGUIimg.png|The Cortec GUI which creates BCI2000 parameters from stimulation specifications.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
==Stimulation Latency==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:StimulationModesLatencyCortec.png|Stimulation Latencies for the specified Stimulation Modes.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Tests were conducted for 100 pulses, with an ISI of 10 seconds.&lt;br /&gt;
Stimulation latency numbers:&lt;br /&gt;
*Persistent functions: &#039;&#039;&#039;13 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Persistent commands: &#039;&#039;&#039;11 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Volatile commands: &#039;&#039;&#039;60 ± 30 ms&#039;&#039;&#039;. Split into the 2 groups, the lower one is &#039;&#039;&#039;48 ± 3 ms&#039;&#039;&#039; and the higher one is &#039;&#039;&#039;174 ± 3 ms&#039;&#039;&#039;&lt;br /&gt;
As explained above, volatile commands are uploaded right before stimulation, which leads to the increased latency and jitter.&lt;br /&gt;
==Template Parameter Files==&lt;br /&gt;
&amp;lt;!-- TODO (Nick): per docx item 3g, attach reviewed template .prm files for each stimulation mode (Volatile, Persistent Command, Persistent Functions) and link them here once paths/save locations are adjusted. --&amp;gt;&lt;br /&gt;
Template parameter files are provided for each stimulation mode to make it easier to get started:&lt;br /&gt;
* &#039;&#039;&#039;Volatile Commands&#039;&#039;&#039; — &#039;&#039;(link pending)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Persistent Command&#039;&#039;&#039; — &#039;&#039;(link pending)&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Persistent Functions&#039;&#039;&#039; — &#039;&#039;(link pending)&#039;&#039;&lt;br /&gt;
==µZeus==&lt;br /&gt;
In order to use the new µZeus headpiece simply change the BICVERSION number on line 12 of the CMakeList.txt located in the project folder to use version 274 of the API. ie.,&lt;br /&gt;
&amp;lt;code&amp;gt;set(BICAPI_VERSION 274)&amp;lt;/code&amp;gt;&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationtriggers_parm1.PNG&amp;diff=12446</id>
		<title>File:CortecADC stimulationtriggers parm1.PNG</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationtriggers_parm1.PNG&amp;diff=12446"/>
		<updated>2026-05-14T20:58:22Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Nluczak uploaded a new version of File:CortecADC stimulationtriggers parm1.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationpulses_parm.PNG&amp;diff=12445</id>
		<title>File:CortecADC stimulationpulses parm.PNG</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationpulses_parm.PNG&amp;diff=12445"/>
		<updated>2026-05-14T20:57:56Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Nluczak uploaded a new version of File:CortecADC stimulationpulses parm.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulation_parm.PNG&amp;diff=12444</id>
		<title>File:CortecADC stimulation parm.PNG</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulation_parm.PNG&amp;diff=12444"/>
		<updated>2026-05-14T20:57:30Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Nluczak uploaded a new version of File:CortecADC stimulation parm.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:VolatileCommand.png&amp;diff=12443</id>
		<title>File:VolatileCommand.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:VolatileCommand.png&amp;diff=12443"/>
		<updated>2026-05-14T20:51:14Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Nluczak uploaded a new version of File:VolatileCommand.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:BlackrockGemini&amp;diff=12409</id>
		<title>Contributions:BlackrockGemini</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:BlackrockGemini&amp;diff=12409"/>
		<updated>2026-04-20T20:34:50Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Synopsis==&lt;br /&gt;
The BlackrockGemini signal source module acquires data from Blackrock Microsystems Gemini acquisition hardware over Ethernet, using the Cerebus SDK ([https://github.com/dashesy/CereLink cbsdk]).  All channel configuration — enabled channels, per-channel sampling rate, gain, and label — is set in Blackrock&#039;s Central application and imported into BCI2000 automatically at &amp;lt;code&amp;gt;SetConfig&amp;lt;/code&amp;gt; time.&lt;br /&gt;
&lt;br /&gt;
==Location==&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/contrib/SignalSource/BlackrockGemini&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Authors===&lt;br /&gt;
Griffin Milsap (griffin.milsap@gmail.com), Jürgen Mellinger (mellinger@neurotechcenter.org), Nicholas Luczak (luczak@neurotechcenter.org)&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 8061&lt;br /&gt;
*Tested under: 9216&lt;br /&gt;
*Known to compile under: 9216&lt;br /&gt;
*Broken since: N/A&lt;br /&gt;
&lt;br /&gt;
==System Setup==&lt;br /&gt;
&lt;br /&gt;
===Network Configuration===&lt;br /&gt;
The module talks to the Gemini Hub over UDP and is sensitive to packet loss.  Connect the BCI2000 machine and the Gemini Hub to a &#039;&#039;&#039;single&#039;&#039;&#039; commercial-grade switch, or use a crossover cable directly between the two.  Do not place a second switch, or a consumer-grade router, in between.&lt;br /&gt;
&lt;br /&gt;
Configure the BCI2000 machine&#039;s network interface as follows:&lt;br /&gt;
* &#039;&#039;&#039;IP address:&#039;&#039;&#039; &amp;lt;code&amp;gt;192.168.137.&amp;lt;u&amp;gt;XXX&amp;lt;/u&amp;gt;&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;XXX&amp;lt;/code&amp;gt; is below 128, not 10, and ideally below 16.  Make sure no other computer on the switch uses the same address.&lt;br /&gt;
* &#039;&#039;&#039;Subnet mask:&#039;&#039;&#039; &amp;lt;code&amp;gt;255.255.255.0&amp;lt;/code&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Default gateway:&#039;&#039;&#039; blank&lt;br /&gt;
&lt;br /&gt;
To verify connectivity, open a command prompt and run:&lt;br /&gt;
 ping 192.168.137.128&lt;br /&gt;
That is the Gemini Hub&#039;s default address.  If the hub responds, the module should be able to reach it.&lt;br /&gt;
&lt;br /&gt;
===Configuring Channels in Central===&lt;br /&gt;
All amplifier-side configuration is done in Blackrock&#039;s Central software.  The Gemini Hub always digitises at 30 kHz; each channel can be independently enabled for continuous streaming at 500 Hz, 1 kHz, 2 kHz, 10 kHz, or 30 kHz.  The hub decimates non-30 kHz streams (with antialiasing) before transmission.&lt;br /&gt;
&lt;br /&gt;
A sample group may mix neural-amplifier channels and analog-input channels (sync pulses, eye-tracker outputs, photodiode signals, and so on).  Any channel enabled for continuous streaming at the SamplingRate selected in BCI2000 will appear in the signal, regardless of the bank it lives on.  Within the signal, channels are grouped by Blackrock instrument id (neural-amp channels first, analog inputs next), and within each instrument they appear in the order reported by Central.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
All parameters live under &#039;&#039;&#039;Source -- Signal Properties&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
Selects the sample group to record from.  Valid values are 500 Hz, 1000 Hz, 2000 Hz, 10000 Hz, and 30000 Hz.  When &amp;lt;code&amp;gt;SetConfig&amp;lt;/code&amp;gt; is pressed, the module collects every channel currently enabled at this rate in Central and configures BCI2000 to acquire them.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per block per channel.  Set to &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt; to pick a default that clocks BCI2000 at approximately 50 Hz:&lt;br /&gt;
&lt;br /&gt;
    int gGroupRates[] = { 0, 500, 1000, 2000, 10000, 30000 }; // samples per second&lt;br /&gt;
    int gBlockSizes[] = { 0, 10,  20,   40,   200,   600   }; // samples per block (~50 Hz)&lt;br /&gt;
&lt;br /&gt;
Any positive integer is accepted.  Clocking BCI2000 faster than 50 Hz is [http://www.youtube.com/watch?v=2FM3Em7FIOc generally a bad idea].&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
Total number of channels.  Set to &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt;; the module fills this in from the Central configuration at &amp;lt;code&amp;gt;SetConfig&amp;lt;/code&amp;gt; time.&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Channel labels.  Populated automatically from the Channel Label column in Central.  Use &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset / SourceChGain===&lt;br /&gt;
Per-channel offset and gain.  Populated automatically from each channel&#039;s &amp;lt;code&amp;gt;cbSCALING&amp;lt;/code&amp;gt; limits reported by cbsdk.  Use &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
&lt;br /&gt;
===NSPSyncState===&lt;br /&gt;
A two-bit state used internally by the module&#039;s start-of-run state machine.  Not intended for downstream analysis.&lt;br /&gt;
&lt;br /&gt;
===BlackrockSourceTimeHigh / BlackrockSourceTimeLow===&lt;br /&gt;
The upper and lower 32 bits of the 64-bit per-sample timestamp produced by the Gemini Hub.  Concatenate as&lt;br /&gt;
 timestamp_ns = (BlackrockSourceTimeHigh &amp;lt;&amp;lt; 32) | BlackrockSourceTimeLow&lt;br /&gt;
to obtain nanoseconds since the Unix epoch (1970-01-01 UTC, 1 ns resolution).&lt;br /&gt;
&lt;br /&gt;
Under the hood, these states are populated by reserving the final two rows of the source signal and labelling them &amp;lt;code&amp;gt;@BlackrockSourceTimeHigh&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;@BlackrockSourceTimeLow&amp;lt;/code&amp;gt;; the &amp;lt;code&amp;gt;@&amp;lt;/code&amp;gt; prefix instructs BCI2000 to route those samples into the corresponding state rather than leave them in the signal.&lt;br /&gt;
&lt;br /&gt;
==Implementation Notes==&lt;br /&gt;
This section is intended for programmers extending, porting, or debugging the module.&lt;br /&gt;
&lt;br /&gt;
===Class Overview===&lt;br /&gt;
&amp;lt;code&amp;gt;BlackrockADC&amp;lt;/code&amp;gt; derives from &amp;lt;code&amp;gt;BufferedADC&amp;lt;/code&amp;gt;.  Acquisition is callback-driven:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;OnStartAcquisition()&amp;lt;/code&amp;gt; opens the cbsdk connection and registers &amp;lt;code&amp;gt;DataCallback&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;cbSdkRegisterCallback(CBSDKCALLBACK_CONTINUOUS)&amp;lt;/code&amp;gt;.  Every incoming &amp;lt;code&amp;gt;cbPKT_GROUP&amp;lt;/code&amp;gt; is dispatched to &amp;lt;code&amp;gt;OnData()&amp;lt;/code&amp;gt; on a cbsdk thread.&lt;br /&gt;
* &amp;lt;code&amp;gt;OnData()&amp;lt;/code&amp;gt; assembles one composite sample per timestep and pushes it into &amp;lt;code&amp;gt;mDataPacketBuffers&amp;lt;/code&amp;gt;.  When enough samples are queued for a full block, it signals &amp;lt;code&amp;gt;mDataAvailable&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &amp;lt;code&amp;gt;DoAcquire()&amp;lt;/code&amp;gt;, running on BCI2000&#039;s source thread, blocks on &amp;lt;code&amp;gt;mDataAvailable&amp;lt;/code&amp;gt; and drains a block&#039;s worth of composite samples into the output signal.&lt;br /&gt;
* &amp;lt;code&amp;gt;mDataMutex&amp;lt;/code&amp;gt; (a &amp;lt;code&amp;gt;std::recursive_mutex&amp;lt;/code&amp;gt;) protects the per-instrument queues, the composite buffers, and the layout vectors.&lt;br /&gt;
&lt;br /&gt;
===Per-timestep Packet Pairing===&lt;br /&gt;
On Gemini, each timestep is broadcast as &#039;&#039;&#039;one &amp;lt;code&amp;gt;cbPKT_GROUP&amp;lt;/code&amp;gt; per instrument&#039;&#039;&#039; — for example, one for the front-end amplifier and a second for the AINP board.  The &amp;lt;code&amp;gt;cbpkt_header.time&amp;lt;/code&amp;gt; field in these packets is a per-packet send time, not a shared sample time, so channels cannot be paired across instruments by matching timestamps.&lt;br /&gt;
&lt;br /&gt;
The module pairs them &#039;&#039;&#039;by arrival order&#039;&#039;&#039; instead:&lt;br /&gt;
# Each instrument has its own FIFO in &amp;lt;code&amp;gt;mInstrumentQueues&amp;lt;/code&amp;gt;.&lt;br /&gt;
# &amp;lt;code&amp;gt;OnData()&amp;lt;/code&amp;gt; pushes every packet into the FIFO for its &amp;lt;code&amp;gt;cbpkt_header.instrument&amp;lt;/code&amp;gt;.&lt;br /&gt;
# While every FIFO is non-empty, the fronts are popped and concatenated into one composite frame in &amp;lt;code&amp;gt;mDataPacketBuffers&amp;lt;/code&amp;gt;, with each instrument&#039;s samples written at its reserved &amp;lt;code&amp;gt;baseOffset&amp;lt;/code&amp;gt; inside the frame.&lt;br /&gt;
# A &#039;&#039;&#039;resync guard&#039;&#039;&#039; flushes every FIFO if any one of them exceeds &amp;lt;code&amp;gt;kMaxInstrumentQueueDepth&amp;lt;/code&amp;gt; (8192 packets).  This re-aligns pairing from a clean state if an instrument falls far behind.&lt;br /&gt;
&lt;br /&gt;
===Channel Discovery===&lt;br /&gt;
&amp;lt;code&amp;gt;GetChannelConfig()&amp;lt;/code&amp;gt; deliberately does &#039;&#039;&#039;not&#039;&#039;&#039; use &amp;lt;code&amp;gt;cbSdkGetSampleGroupList()&amp;lt;/code&amp;gt;.  On Gemini, that API reports only front-end channels in the requested sample group; AINP channels configured for the same rate stream as &amp;lt;code&amp;gt;cbPKT_GROUP&amp;lt;/code&amp;gt; packets under a different &amp;lt;code&amp;gt;cbpkt_header.instrument&amp;lt;/code&amp;gt; and are omitted from the list.&lt;br /&gt;
&lt;br /&gt;
Instead, the module probes every channel id from 1 through &amp;lt;code&amp;gt;cbNUM_ANALOG_CHANS&amp;lt;/code&amp;gt; with &amp;lt;code&amp;gt;cbSdkGetChannelConfig()&amp;lt;/code&amp;gt;, filters by &amp;lt;code&amp;gt;chanInfo.smpgroup == iGroup&amp;lt;/code&amp;gt;, groups the survivors by &amp;lt;code&amp;gt;chanInfo.cbpkt_header.instrument&amp;lt;/code&amp;gt;, and emits them in ascending instrument-id order.  As a side effect, this yields the instrument id used to route each channel&#039;s packets in &amp;lt;code&amp;gt;OnData()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Build===&lt;br /&gt;
The CMake target is Windows-only.  It links against the prebuilt Cerebus SDK in &amp;lt;code&amp;gt;lib/x64/cbsdkx64.lib&amp;lt;/code&amp;gt; (x64) or &amp;lt;code&amp;gt;lib/x86/cbsdk.lib&amp;lt;/code&amp;gt; (x86).  The headers &amp;lt;code&amp;gt;cbsdk.h&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;cbhwlib.h&amp;lt;/code&amp;gt; ship in &amp;lt;code&amp;gt;include/&amp;lt;/code&amp;gt;.  Batch files are copied to &amp;lt;code&amp;gt;prog/batch&amp;lt;/code&amp;gt;, and the &amp;lt;code&amp;gt;BlackrockGemini.prm&amp;lt;/code&amp;gt; fragment to &amp;lt;code&amp;gt;parms/fragments/amplifiers&amp;lt;/code&amp;gt;, by &amp;lt;code&amp;gt;BCI2000_ADD_SIGNAL_SOURCE_MODULE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The module has been built and run against both the official Blackrock cbsdk release and the open-source [https://github.com/dashesy/CereLink CereLink] fork; either is compatible.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:BlackrockGemini&amp;diff=12408</id>
		<title>Contributions:BlackrockGemini</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:BlackrockGemini&amp;diff=12408"/>
		<updated>2026-04-20T16:31:23Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Updated to reflect on changes to gemini&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Synopsis==&lt;br /&gt;
The Blackrock Gemini acquisition module enables signal acquisition from Blackrock Microsystems Gemini acquisition hardware through the &amp;quot;cbsdk&amp;quot; C++ API.&lt;br /&gt;
&lt;br /&gt;
==Location==&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/contrib/SignalSource/BlackrockGemini&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Author===&lt;br /&gt;
Griffin Milsap (griffin.milsap@gmail.com), Jürgen Mellinger (mellinger@neurotechcenter.org)&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 4365/8061&lt;br /&gt;
*Tested under: 8522&lt;br /&gt;
*Known to compile under: 8522&lt;br /&gt;
*Broken since: N/A&lt;br /&gt;
&lt;br /&gt;
==Functional Description==&lt;br /&gt;
The BlackrockGemini source module is used for acquiring recordings from Blackrock Gemini systems using CBSDK as provided through official Blackrock channels, or through CereLink (https://github.com/dashesy/CereLink). This documentation explains the parameterization and specifics on how to set up the system.&lt;br /&gt;
&lt;br /&gt;
===System Setup===&lt;br /&gt;
Building the BlackrockGemini module should copy .bat files for standard experiments into the batch directory.&lt;br /&gt;
&lt;br /&gt;
Ensure your machine is connected to a switch or router that the Gemini Hub is also connected to.  This module communicates to the Gemini Hub using UDP, and is susceptible to packet loss.  Ensure you have a commercial grade switch to avoid dropping packets.  You can also use a crossover cable to connect directly to the Gemini Hub, but this prevents other computers from receiving data from the Gemini Hub.&lt;br /&gt;
&lt;br /&gt;
You will also need to change your interface&#039;s network configuration:&lt;br /&gt;
* IP address: 192.168.137.XXX where XXX is less than 128.  &amp;lt;u&amp;gt;This number needs to be below 16 and not 10.&amp;lt;/u&amp;gt;  Ensure no other computers have this same address on this switch.&lt;br /&gt;
* Subnet Mask: 255.255.255.0&lt;br /&gt;
* Default Gateway: &amp;lt;Blank&amp;gt;&lt;br /&gt;
To test your network configuration, open a terminal or command prompt and type &#039;&#039;&#039;ping 192.168.137.128&#039;&#039;&#039;. This is the Gemini Hub&#039;s default network address.  If you can ping the Gemini Hub, you should be able to run the module.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
Blackrock systems are very configurable, and it appears to make little sense to reproduce each individual setting as a BCI2000 parameter.&lt;br /&gt;
Rather, you will configure the recording setup using the Blackrock &amp;quot;Central&amp;quot; software, and BCI2000 will auto-configure to match the SampleGroup dictated by the SamplingRate parameter.  Gemini Hubs always acquire data at 30Khz, but channels can be added to a SampleGroup which is downsampled (with antialiasing) in real-time by the Gemini Hub before being streamed over ethernet to receivers.  You can add channels to these channel groups in the Central software by enabling continuous streaming on individual channels, and selecting the sampling rate.&lt;br /&gt;
&lt;br /&gt;
The following parameters are available for configuring the BlackrockGemini source module. You will find these parameters in the Source -- Signal Properties section. &lt;br /&gt;
===SamplingRate===&lt;br /&gt;
In standard use, this is one of two parameters you need to play with.  This is where you select the sample group you want BCI2000 to record from.  Valid sampling rates are 500 Hz, 1000 Hz, 2000 Hz, 10000 Hz, and 30000 Hz.  When the SetConfig button is pressed, BCI2000 will collect all channels that are members of that SampleGroup and configure to acquire from those channels.&lt;br /&gt;
&lt;br /&gt;
The sample group can mix neural channels and analog input channels (such as sync, eye-tracking, or photodiode signals).  Any channel you have enabled for continuous streaming in Central at the selected rate will be picked up, regardless of which bank it lives on.  In the BCI2000 signal, neural channels are listed first, followed by the analog input channels, in the order shown by Central.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
There are a bunch of default SampleBlockSizes for the different SamplingRates, which you will get if you use &#039;auto&#039; as the value of this parameter.  They are roughly set to clock BCI2000 at about 50 Hz. Depending on the processing you&#039;re doing, you may want to lengthen the block size. Any number of samples is valid here: even 1.  You may want to not do that, however.  Clocking the system above 50 Hz [http://www.youtube.com/watch?v=2FM3Em7FIOc is a bad choice].  The default block size for different sample groups is as follows:&lt;br /&gt;
&lt;br /&gt;
    int gGroupRates[] = { 0, 500, 1000, 2000, 10000, 30000 }; // samples per second&lt;br /&gt;
    int gBlockSizes[] = { 0, 10,  20,   40,   200,   600   }; // samples per block (50 Hz)&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
These will be pulled from the Channel Label property set in the Central Software.  Use &#039;auto&#039; to configure this parameter.&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset/SourceChGain===&lt;br /&gt;
Again, these are populated automatically.  Use &#039;auto&#039; to configure this parameter.&lt;br /&gt;
&lt;br /&gt;
===NSPInstances===&lt;br /&gt;
This parameter determines how many NSPs you intend to record from.  This is the other parameter that you might want to play with, but only if you have more than one NSP.  Using more than 2 NSPs is untested.&lt;br /&gt;
&lt;br /&gt;
===DigitalOutput===&lt;br /&gt;
This parameter specifies a matrix of expressions that will be evaluated once per SampleBlock to set the digital output channels.  Each row of this matrix defines an expression for one digital output.  If that expression evaluates true for that block, the associated digital output will be set high, and vice versa for false.  See [[User Reference:Expression Syntax]] for help with BCI2000 Expressions.  An example matrix is provided below.&lt;br /&gt;
&lt;br /&gt;
    Instance Output Expression&lt;br /&gt;
    1        1      StimulusCode!=0 // Will set output 1 on NSP1 high whenever a stimulus is on screen&lt;br /&gt;
    2        3      KeyDown!=0 // Will set output 3 on NSP2 high whenever a key is pressed.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
===BlackrockTimeStampHigh===&lt;br /&gt;
The higher 32 bits of the 64-bit per-sample timestamp sent by the Gemini Hub.&lt;br /&gt;
===BlackrockTimeStampLow===&lt;br /&gt;
The lower 32 bits of the 64-bit per-sample timestamp sent by the Gemini Hub.&lt;br /&gt;
The time stamp itself represents the amount of time since the UNIX epoch (1.1.1970), with a resolution of 1ns (one nanosecond, 1e-9 seconds).&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]], [[Contributions:Blackrock]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationtriggers_parm1.PNG&amp;diff=12404</id>
		<title>File:CortecADC stimulationtriggers parm1.PNG</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationtriggers_parm1.PNG&amp;diff=12404"/>
		<updated>2026-04-13T19:16:54Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Nluczak uploaded a new version of File:CortecADC stimulationtriggers parm1.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationpulses_parm.PNG&amp;diff=12403</id>
		<title>File:CortecADC stimulationpulses parm.PNG</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulationpulses_parm.PNG&amp;diff=12403"/>
		<updated>2026-04-13T19:16:17Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Nluczak uploaded a new version of File:CortecADC stimulationpulses parm.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulation_parm.PNG&amp;diff=12402</id>
		<title>File:CortecADC stimulation parm.PNG</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:CortecADC_stimulation_parm.PNG&amp;diff=12402"/>
		<updated>2026-04-13T19:14:36Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Nluczak uploaded a new version of File:CortecADC stimulation parm.PNG&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12401</id>
		<title>Contributions:CortecADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12401"/>
		<updated>2026-04-13T19:08:57Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CorTec_BrainInterchange.png|400px|thumb|right|CorTec Brain Interchange Implant]]&lt;br /&gt;
&lt;br /&gt;
CortecADC is a source module that allows for intra-cranial recording and stimulating over 32 channels via a fully implantable device. It is intended for long-term measurement of neural activity and electrical stimulation of brain tissue. See the [https://www.cortec-neuro.com/solutions/complete-system/ CorTec site] for more information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;See the [[CortecExperience]] page for user tutorials and a broad overview!&#039;&#039;&#039; After viewing the [[CortecExperience]] page, refer to this page for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter.org)&lt;br /&gt;
* William Engelhardt (engelhardt@neurotechcenter.org)&lt;br /&gt;
* Alexander Belsten (belsten@neurotechcenter.org)&lt;br /&gt;
* Markus Adamek (adamek@neurotechcenter.org)&lt;br /&gt;
* Christian Stolle (christian.stolle@cortec-neuro.com)&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 6266&lt;br /&gt;
*Tested under: 9282&lt;br /&gt;
*Known to compile under: 9282&lt;br /&gt;
*Broken since: --&lt;br /&gt;
&lt;br /&gt;
===BCI2000 Version History===&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Date !! Revision !! Note !! Contributor&lt;br /&gt;
|-&lt;br /&gt;
!11/29/2018&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R5829&lt;br /&gt;
|Initial untested version&lt;br /&gt;
|Adamek&lt;br /&gt;
|-&lt;br /&gt;
!04/19/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6271&lt;br /&gt;
|First working version&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!07/22/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6339&lt;br /&gt;
|Changed &#039;&#039;ImplantLostSample&#039;&#039; from a BCI2000 state to a stream, so it can record individual sample loss (instead of over the whole block)&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!01/01/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7133&lt;br /&gt;
|Updated API to version 1.0.200. &lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!03/08/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7251&lt;br /&gt;
|Stimulation functionality added&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!05/19/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7367&lt;br /&gt;
|Impedance measurement enabled&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!10/26/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Stimulation latency vastly improved&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!02/20/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7847&lt;br /&gt;
|Version 1.0.230 added. Can change between versions in CMakeLists.txt file&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!08/09/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8313&lt;br /&gt;
|Version 1.0.238 added&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!01/17/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Interpolation filter added to interpolate lost samples&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!06/25/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8915&lt;br /&gt;
|All listener states were changed to events&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!04/13/2026&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R9xxx&lt;br /&gt;
|Refactored stimulation to be more in line with Cortec and BCI2000 standards.&lt;br /&gt;
|Nicholas Luczak&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Cortec API Version History===&lt;br /&gt;
Cortec is continually updating their devices with new API versions. In BCI2000, we currently support versions 1.0.200, 1.0.230, and 1.0.238. Each Brain Interchange Communication unit (BIC) is only compatible with one API version. To find your compatible version, connect the USB drive that comes with your BIC. Look under:&lt;br /&gt;
# &#039;&#039;&#039;Software folder&#039;&#039;&#039;: Each executable has the API version. E.g., &amp;lt;code&amp;gt;Bicapi_setup_1.0.200-bicapi-setup-1.0.200-rev35926.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Manuals foder&#039;&#039;&#039;: &#039;&#039;Appendix1_BIC_Application_Software_Short_Manual.pdf&#039;&#039;. On page 3, in Table 1, the third row contains the compatible version.&lt;br /&gt;
&lt;br /&gt;
Here are some differences between the versions. As the device is always improving, the newest version will have the most features.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Features !! 1.0.200 !! 1.0.230 !! 1.0.238 !! 1.0.260&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!Matlab API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!C/C++ API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Stimulation modes&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!ASIC Noise Detection Mode&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Monopolar stimulation (Ch → GND)&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Measure GND impedances&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Self-tests&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Low noise recording&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Known Issues===&lt;br /&gt;
* Lost samples - The &amp;lt;code&amp;gt;ImplantLostSamples&amp;lt;/code&amp;gt; state records what samples are lost, and their locations. Lost samples are replaced with the previous valid sample for all channels. In offline analysis, be sure to remove these samples and replace them with interpolates.&lt;br /&gt;
* The Brain Interchange Communication Unit has been seen to work with certain USB inputs, and not with others. If you are experiencing connection issues, try using a different USB port.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
# Install BCI2000&lt;br /&gt;
# Insert the Cortec USB drive that comes with the Brain Interchange (BIC) device. Under &#039;&#039;Software&#039;&#039;, run the &#039;&#039;Bicapi_setup...&#039;&#039; executable&lt;br /&gt;
# Run a batch file with CortecADC as your Signal Source!&lt;br /&gt;
# If you receive an error, and it states your API version is incorrect, you need to change it. Locate the &#039;&#039;CMakeLists.txt&#039;&#039; under &amp;lt;code&amp;gt;BCI2000/src/private/SignalSource/Cortec&amp;lt;/code&amp;gt;. You must change Line 12, where it states &amp;lt;code&amp;gt;set(BICAPI_VERSION 200)&amp;lt;/code&amp;gt;. Change 200 to 230 or 238, depending on your device (see [[#Cortec Version History | details above]]).&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:CortecSourceParameters.jpg|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the CortecADC]]&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. In the current implementation, this parameter cannot be edited, and will default to how many channels are available from the implant. &lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. &lt;br /&gt;
Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated. For example, at 1000 Hz sampling and a SampleBlockSize of 20, the system (e.g., source signal display, signal processing, and stimulus presentation) will be updated 50 times per second.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. This parameter cannot be edited, and will default to the sampling rate available from the implant. &lt;br /&gt;
In case you are experiencing problems by higher sampling rates (e.g., data loss, jerky display, etc.), increase the SampleBlockSize so that you are updating the system less frequently (usually, updating the system 20-30 times per second is sufficient for most applications), and increase Visualize-&amp;gt;VisualizeSourceDecimation. This parameter will decrease the number of samples per second that are actually drawn in the Source display.&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel. &lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel.&lt;br /&gt;
&lt;br /&gt;
===LogCortecBinaryFiles===&lt;br /&gt;
Enable or disable binary logging of raw CorTec communication data.&lt;br /&gt;
&lt;br /&gt;
When enabled, a binary log file is written to the BCI2000 session directory with the name:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;YYYYMMDD_HHMMSS_CortecAdcLog.bin&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This file contains raw communication packets between the Brain Interchange Communication unit and the implant and is primarily useful for low-level debugging and support from CorTec.&lt;br /&gt;
&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; (enabled)&lt;br /&gt;
&lt;br /&gt;
Disable this parameter if binary logs are not needed or disk space usage is a concern.&lt;br /&gt;
&lt;br /&gt;
===LogStimulationEvents===&lt;br /&gt;
Enable logging of stimulation configuration and execution events to the Operator Log.&lt;br /&gt;
&lt;br /&gt;
When enabled, detailed information about stimulation functions, trigger evaluation, and stimulation execution will be printed using &amp;lt;code&amp;gt;bciout&amp;lt;/code&amp;gt; messages.&lt;br /&gt;
&lt;br /&gt;
This is useful for debugging stimulation timing and verifying correct parameter interpretation.&lt;br /&gt;
&lt;br /&gt;
Default value: &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (disabled)&lt;br /&gt;
&lt;br /&gt;
===ReferenceCh===&lt;br /&gt;
This list defines what channels will be used as reference. This list is uploaded to the device and set in hardware, effecting the raw bio-signal data that is recorded by BCI2000. If you do not want to effect the raw bio-signal data that is recorded, you can use the [https://www.bci2000.org/mediawiki/index.php/User_Reference:SpatialFilter spatial filter]. If this parameter is set to auto, no reference channels are used. It is strongly recommended to use at least one reference channel.&lt;br /&gt;
&lt;br /&gt;
===AmplificationFactor===&lt;br /&gt;
Amplification factor that is applied to the recorded data on the implant. The choices are 39.5, 45.5, 51.5, 57.5 db.&lt;br /&gt;
&lt;br /&gt;
===UseGround===&lt;br /&gt;
Enable to use the ground electrode while measuring. This setting can be overwritten during stimulation, depending if the ground electrode is being used or not. For example, if you have enabled this parameter but don&#039;t have &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;Destination ch&amp;lt;/code&amp;gt; list in the StimulationTriggers parameter, when you are stimulating you will not be using the ground electrode. Once stimulation is done, this parameter&#039;s settings are used again.&lt;br /&gt;
&lt;br /&gt;
===SaveInfoFile===&lt;br /&gt;
Enable to save a text file, named the same as the data file run. It will contain the timestamp, amplification factor used in the run, and reference channels used. If the Impedance is measured, the impedance values will be saved to this file regardless of if this parameter is enabled.&lt;br /&gt;
&lt;br /&gt;
===LogPacketErrors===&lt;br /&gt;
Enable to save the packet loss errors to the System Log. Helpful for debugging, however can get overwhelming if there are a lot of lost samples. The System Log can be programmatically saved by appending &amp;lt;code&amp;gt;--SystemLogFile=SOME_FILE.TXT&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;Startup system localhost&amp;lt;/code&amp;gt; line in your batch file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab of the BCI2000 config window. &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:CortecADC_stimulation_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationpulses_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationtriggers_parm1.PNG&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===EnableStimulation===&lt;br /&gt;
This parameter enables/disables stimulation. &lt;br /&gt;
&lt;br /&gt;
===StimulationMode===&lt;br /&gt;
The BIC has 3 stimulation modes. Each one has limitations. Here is a brief summary of how to use each one:&lt;br /&gt;
#Volatile Commands: The most flexible mode. The limitation is that the stimulation configuration is uploaded right before starting the stimulation, which increases the latency of the stimulation. This mode is best used in single pulse stimulation or stimulation burst applications. Can cause issues in longer stimulation trains due to the latency introduced by uploading commands repeatedly. &lt;br /&gt;
[[File:VolatileCommand.png|1000px|thumb|center|upright=2.5|Figure 1. Figure demonstrating volatile command functionality]]&lt;br /&gt;
#Persistent Command: There can only be one stimulation configuration (one column in StimulationPulses), which includes burst settings. You cannot change the source and destination channels without uploading a new command. This mode is useful for implementing stimulation trains, otherwise similar but less flexible when compared to volatile commands.&lt;br /&gt;
[[File:PersistantCommand.png|1000px|thumb|center|upright=2.5|Figure 2. Figure demonstrating Persistant Command functionality]]&lt;br /&gt;
&lt;br /&gt;
#Persistent Functions: This function allows you to preload multiple stimulation configurations allowing for the user to define different source and destination channels. The device executes only one of the stim configrations, and without repetition. This is best used for rapidly iterating over subsets of stimulation pulses in single-pulse stimulation settings. &lt;br /&gt;
[[File:PersistantFunction.png|1000px|thumb|center|upright=2.5|Figure 3. Figure demonstrating Persistant Function functionality]]&lt;br /&gt;
There cannot be any train settings (Train frequency and Train repetitions), so the StimulationTriggers must not have those rows. Also, StimulationTriggers must not have more than 16 columns, as that is the highest number of configurations that can be stored on the device.&lt;br /&gt;
&lt;br /&gt;
Persistent Command and Functions modes have a lower latency because the stimulation is pre-uploaded. All modes are available to give you the highest amount of flexiblity with the BIC. [[#Stimulation Latency|See below for more details on latency.]]&lt;br /&gt;
&lt;br /&gt;
===MeasureImpedance===&lt;br /&gt;
When enabled, the impedances of the used electrodes are printed when you set the configuration. All electrodes that are being recorded will conduct the impedance measurement. The impedances are shown to the user and also saved in the data directory.&lt;br /&gt;
&lt;br /&gt;
===StimulationPulses===&lt;br /&gt;
This parameter defines stimulation &#039;&#039;functions&#039;&#039;. Each column defines a stimulation waveform and electrode configuration.&lt;br /&gt;
&lt;br /&gt;
Each function consists of:&lt;br /&gt;
&lt;br /&gt;
* Pulse waveform parameters&lt;br /&gt;
* Electrode mapping&lt;br /&gt;
* Repetition behavior&lt;br /&gt;
&lt;br /&gt;
Rows are defined as follows:&lt;br /&gt;
&lt;br /&gt;
====FunctionID====&lt;br /&gt;
Integer identifier for this stimulation function. This ID is referenced in the &amp;lt;code&amp;gt;StimulationTriggers&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
====Pulse Amplitude====&lt;br /&gt;
Amplitude of the stimulation pulse in µA.&lt;br /&gt;
&lt;br /&gt;
Valid range:&lt;br /&gt;
0 to 6120 µA&lt;br /&gt;
&lt;br /&gt;
====Pulse Duration====&lt;br /&gt;
Duration of the main pulse in µs.&lt;br /&gt;
&lt;br /&gt;
Valid range:&lt;br /&gt;
10 to 2550 µs&lt;br /&gt;
&lt;br /&gt;
====Dead Zone 0====&lt;br /&gt;
Pause between main pulse and counter pulse.&lt;br /&gt;
&lt;br /&gt;
====Dead Zone 1====&lt;br /&gt;
Pause after pulse delivery.&lt;br /&gt;
&lt;br /&gt;
====Anode(s)====&lt;br /&gt;
Embedded list specifying source electrodes.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;{ list 1 18 19 }&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Cathode(s)====&lt;br /&gt;
Embedded list specifying return electrodes.&lt;br /&gt;
&lt;br /&gt;
Use &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; to reference ground.&lt;br /&gt;
&lt;br /&gt;
====Pulse Repetition====&lt;br /&gt;
Number of times the pulse is repeated within a function.&lt;br /&gt;
&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
&lt;br /&gt;
====Burst Repetition====&lt;br /&gt;
Number of times the function is repeated.&lt;br /&gt;
&lt;br /&gt;
Range:&lt;br /&gt;
1 to 255&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
Defines when stimulation functions are executed.&lt;br /&gt;
&lt;br /&gt;
Each column contains:&lt;br /&gt;
&lt;br /&gt;
====Trigger====&lt;br /&gt;
A valid BCI2000 expression.&lt;br /&gt;
&lt;br /&gt;
When this expression evaluates to true, the associated stimulation function(s) are executed.&lt;br /&gt;
&lt;br /&gt;
====FunctionID(s)====&lt;br /&gt;
List of FunctionIDs that should execute when the trigger evaluates true.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
StimulusCode==1   { list 1 3 }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means:&lt;br /&gt;
&lt;br /&gt;
Execute FunctionID 1 followed by FunctionID 3 whenever the trigger becomes true.&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
Electrode configuration and repetition settings are defined in &amp;lt;code&amp;gt;StimulationPulses&amp;lt;/code&amp;gt;, not here.&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, such as device type, device ID, and the firmware version. &lt;br /&gt;
&lt;br /&gt;
===StateInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information regarding state units and their multiplier. The device provides information such as humidity, temperature, control value, etc., which are recorded in BCI2000 states (see state information on this page for a complete enumeration of states). The device provides these values with floats, but BCI2000 states can only be integers. The multipliers defined in this parameter are used to increase the amount of precision in the state values. To approximately recover the original float values with the units defined in this parameter, divide each state by its corresponding multiplier.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information returned from the Cortec implant. The device provides this data in floating point numbers, however BCI2000 can only record integers to it&#039;s states. To maintain some precision, these floats are multiplied by constants, then recorded to the states as integers. To approximately recover the original data, divide the state by its corresponding constant. Constants are shown in the following table. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:right;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
! State&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot; | Constant&lt;br /&gt;
|-&lt;br /&gt;
| ImplantVoltage&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantHumidity&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantControlValue&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantPrimaryCoilCurrent&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantTemperature&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|}&lt;br /&gt;
===ImplantLostSample===&lt;br /&gt;
The communication protocol the device uses does not re-send lost data. This state annotates what samples were lost in the bio-signal data. Currently, lost samples are made up by duplicating the previous sample. &lt;br /&gt;
&lt;br /&gt;
===ImplantVoltage===&lt;br /&gt;
16 bit state that changes when new supply voltage value is received from the implant. After dividing the integer state value by the the voltage multiplier defined in the StateInfo parameter, the units are in volts.&lt;br /&gt;
&lt;br /&gt;
===ImplantHumidity===&lt;br /&gt;
16 bit state that changes when new humidity value is received from the implant. Units in %rh. &lt;br /&gt;
&lt;br /&gt;
===ImplantControlValue===&lt;br /&gt;
16 bit state that changes when new current control value is received from the external unit. The power of the implant is controlled by the external unit. The control value provides a measure of how good the coupling between the two coils is and how much more power can be provided if necessary.&lt;br /&gt;
The value is between 0.0 and 100.0 percent, where 0.0 translates to no power and 100.0 translates to maximum power applied.&lt;br /&gt;
&lt;br /&gt;
===ImplantPrimaryCoilCurrent===&lt;br /&gt;
16 bit state that change when new primary coil current value is received from the external unit. The primary coil refers to the coil inside the head piece of the external unit. Units are mA. &lt;br /&gt;
&lt;br /&gt;
===ImplantTemperature===&lt;br /&gt;
16 bit state that changes when new temperature value is received from the implant. Units are degrees Celsius. &lt;br /&gt;
&lt;br /&gt;
===ImplantStimulation===&lt;br /&gt;
Binary state that changes when the device reports that it is stimulating. &lt;br /&gt;
&lt;br /&gt;
===ImplantStimulationBursts===&lt;br /&gt;
Updates when the device reports that stimulation functions have finished. Should increment during a stimulation train.&lt;br /&gt;
&lt;br /&gt;
===ImplantRfQuality===&lt;br /&gt;
8 bit state that reports the antenna quality as reported from the rf-link in dBm. &#039;&#039;&#039;&#039;&#039;To obtain the original value, subtract by 128 (2^8)&#039;&#039;&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
===RequestedStimulation===&lt;br /&gt;
Binary state that records when a stimulation trigger expression evaluates true. State remains true for the duration triggered stimulation. This is useful for determining the latency between when stimulation is requested and when it is actually applied. This is done by computing the difference in time between the rising edges of &#039;&#039;ImplantStimulation&#039;&#039; and &#039;&#039;RequestedStimulation&#039;&#039; states.&lt;br /&gt;
&lt;br /&gt;
===PauseStimulation===&lt;br /&gt;
Binary state that pauses stimulation execution without stopping data recording.&lt;br /&gt;
&lt;br /&gt;
When this state is set to &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt;, trigger expressions are ignored and no stimulation will be delivered.&lt;br /&gt;
&lt;br /&gt;
When set to &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;, stimulation resumes normally.&lt;br /&gt;
&lt;br /&gt;
This allows temporary suspension of stimulation during a recording session without restarting the system.&lt;br /&gt;
&lt;br /&gt;
==Stimulation Logging==&lt;br /&gt;
When &amp;lt;code&amp;gt;LogStimulationEvents&amp;lt;/code&amp;gt; is enabled, stimulation activity will be written to the Operator Log.&lt;br /&gt;
&lt;br /&gt;
Logged information includes:&lt;br /&gt;
&lt;br /&gt;
* Stimulation mode&lt;br /&gt;
* Function definitions&lt;br /&gt;
* Trigger matches&lt;br /&gt;
* Stimulation execution events&lt;br /&gt;
&lt;br /&gt;
This information is useful for:&lt;br /&gt;
&lt;br /&gt;
* Debugging stimulation timing&lt;br /&gt;
* Verifying correct function configuration&lt;br /&gt;
* Investigating unexpected stimulation behavior&lt;br /&gt;
&lt;br /&gt;
==[[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|SCIT]]==&lt;br /&gt;
To help out with creating the BCI2000 parameters, a GUI has been made which should make it easy to translate your stimulation specifications into BCI2000 parameter files. The GUI also visualizes the stimulation from three different perspectives, making it easy to tell if your parameters are really what you want. There is a [[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|Stimulation Configuration tool user reference]] which will further tell you how to use this tool.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:CortecGUIimg.png|The Cortec GUI which creates BCI2000 parameters from stimulation specifications. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Stimulation Latency==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:StimulationModesLatencyCortec.png|Stimulation Latencies for the specified Stimulation Modes. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Tests were conducted for 100 pulses, with an ISI of 10 seconds.&lt;br /&gt;
&lt;br /&gt;
Stimulation latency numbers:&lt;br /&gt;
*Persistent functions: &#039;&#039;&#039;13 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Persistent commands: &#039;&#039;&#039;11 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Volatile commands: &#039;&#039;&#039;60 ± 30 ms&#039;&#039;&#039;. Split into the 2 groups, the lower one is &#039;&#039;&#039;48 ± 3 ms&#039;&#039;&#039; and the higher one is &#039;&#039;&#039;174 ± 3 ms&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As explained above, volatile commands are uploaded right before stimulation, which leads to the increased latency and jitter.&lt;br /&gt;
==µZeus==&lt;br /&gt;
In order to use the new µZeus headpiece simply change the BICVERSION number on line 12 of the CMakeList.txt located in the project folder to use version 274 of the API. ie.,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set(BICAPI_VERSION 274)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:AmpServerProADC&amp;diff=12372</id>
		<title>Contributions:AmpServerProADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:AmpServerProADC&amp;diff=12372"/>
		<updated>2026-03-18T13:43:39Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Source Code Revisions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Synopsis==&lt;br /&gt;
The &#039;&#039;AmpServerProADC&#039;&#039; component implements the client side of EGI&#039;s TCP/IP-based Amp Server Pro (ASP) protocol. Thus, it may be used to interface BCI2000 with an EGI amplifier. Amplifiers that record data and administer transcranial direct current stimulation (GTEN devices) are supported.&lt;br /&gt;
&lt;br /&gt;
==Location==&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/contrib/SignalSource/AmpServerPro&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Author===&lt;br /&gt;
Joshua Fialkoff, (c) 2008 Wadsworth Center, New York State Department of Health. (V1)&lt;br /&gt;
&lt;br /&gt;
Alex Belsten (belsten@neurotechcenter.org), NCAN. (V2)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* V1.00 - 06/11/2008 - First working version&lt;br /&gt;
* V2.00 - 05/10/2020 - Added support for GTEN devices and packet format 2 &lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 1998&lt;br /&gt;
*Tested under: 9297&lt;br /&gt;
*Known to compile under: 9297&lt;br /&gt;
*Stimulation broken since: 7273 - Race condition in AmpServerProADC allows stimulation to start before train upload completes, causing “train not uploaded” errors and SignalSource crashes.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot;&amp;gt;https://www.youtube.com/watch?v=wW-xEy9e5ps&amp;amp;list=PL6LrR5Nj3cAxOxKHNsnqyKfLDGikpi8Qi&amp;amp;index=7&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the AmpServerPro Source Module==&lt;br /&gt;
For using the AmpServerPro source module, you will need to obtain a license for the AmpServerPro SDK. Without such a license, you may be able to connect to the machine running the EGI software, but it will not send any real-time data when asked to. In order to obtain an AmpServerPro SDK license, you will need to contact EGI at http://www.egi.com.&lt;br /&gt;
&lt;br /&gt;
==Setting Up the Hardware==&lt;br /&gt;
The EGI system comes with many hardware and cables, so connecting everything in a step-by-step manner is helpful for getting everything connected correctly. There are a few steps to this process. First, make sure you have all of the necessary cables and hardware. These items can be seen in the two images below (Fig. 1 and Fig. 2). &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:EGI-cables.jpeg|Figure 1: The necessary cables.&lt;br /&gt;
File:EGI-boxes.jpg|Figure 2: EGI hardware.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
In addition to the hardware shown in Fig. 1 and 2, you will need the EGI iMac that comes with the amplifier and a research PC. This PC must be running Windows and needs an ethernet port or an adapter that connects to an ethernet cable.&lt;br /&gt;
Once sure that all of the necessary hardware/cables are present, it is time to connect all the hardware. For your reference, the general architecture is shown in the figure below. &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:EGI-power_and_network.png|Figure 3: General hardware architecture.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
===Setting up the Power Supplies===&lt;br /&gt;
The transformer is the first piece of hardware to set up. It provides isolated power to the EGI amplifier, switch box, and EGI iMac. Each of these devices connects to the plugs on the back of the transformer, as shown in Fig. 4. &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:EGI-transformer_connections.jpeg|Figure 4: Three different types of plugs on the back of the transformer.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify that the transformer is off and use plug type 3 in Fig. 4 to plug into a standard wall socket. Now, connect the EGI iMac to plug type 2. Next, you will need two cables of type 1 (IEC plug cable). Connect one to the amplifier power supply and the other to the switch box. Keep the transformer off for now. Lastly, you will need to use the amplifier power cable to connect the amplifier power supply to the amplifier.&lt;br /&gt;
&lt;br /&gt;
===Setting up the Network Cables===&lt;br /&gt;
Next, the network cables need to be connected. Fig. 5 and 6 serve as a reference through this process. &lt;br /&gt;
&amp;lt;gallery class=&amp;quot;center&amp;quot; mode=&amp;quot;nolines&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:EGI-back-of-amp.jpeg|Figure 5: Connections to back of amplifier.&lt;br /&gt;
File:EGI-switch-box.jpeg|Figure 6: Network connections to switch box.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Start by connecting the orange fiber optic cable to the back of the amplifier and then connect the other end to the front of the switch box. Then, connect one of the network cables to the EGI iMac and connect the other end to any one of the eight ports on the switch box. Lastly, connect the other network cable to your research PC and then to the switch box. Now that everything is connected, the transformer and amplifier power supply can be turned on. Next, boot up the EGI iMac. Navigate to the browser and enter the amplifier&#039;s IPv4 address into the address bar. You can find the IPv4 address of your amplifier by launching Net Station Acquisition on the EGI iMac and expanding the &#039;&#039;sharing&#039;&#039; tab. All of the EGI amplifiers have an IPv4 address of the form &amp;lt;code&amp;gt;10.10.10.X&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; is some integer between 0 and 256. You should now see the amplifier&#039;s web page, similar to the one shown in Fig. 7. If you cannot see this web page, verify that all network connections are secure and the amplifier is powered on.  &lt;br /&gt;
&amp;lt;gallery class=&amp;quot;center&amp;quot; mode=&amp;quot;nolines&amp;quot; widths=600px heights=600px&amp;gt;&lt;br /&gt;
File:EGI-amp_webserver.jpg|Figure 7: Amplifier webpage that is accessible from amplifier&#039;s IPv4 address.  &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuring and Setting Up BCI2000 on the Research PC==&lt;br /&gt;
Now it is time to set up the research PC. First, install BCI2000 (a guide to do this can be found at [[Programming_Howto:Building_and_Customizing_BCI2000]]) and make sure the &amp;lt;code&amp;gt;BUILD_CONTRIB&amp;lt;/code&amp;gt; option is enabled in CMake before compiling. &lt;br /&gt;
&lt;br /&gt;
The research PC&#039;s IP address must be configured to allow the amplifier and Net Station to recognize it. On the research PC, configure the IP (IPv4) for a manual IP address (&amp;lt;code&amp;gt;10.10.10.Y&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt; is any digits other than the last two digits used by the amp); with the manual IPv4 address configured, set the subnet mask to 255.255.255.0. Once this has been completed, open a browser on the research PC and enter the amplifier&#039;s IPv4 address into the address bar. If the research PC&#039;s IP address is set correctly, the page will populate with information about the amplifier shown in Fig. 7. If the web page fails to load, then the PC&#039;s IPv4 address may not have been set correctly, or the research PC has a firewall that is blocking the amplifier. Verify that the research IPv4 address is correct and firewalls have been disabled. &lt;br /&gt;
&lt;br /&gt;
===Starting Amp Server Pro===&lt;br /&gt;
Amp Server Pro is capable of working with many amplifiers concurrently.  To begin using Amp Server Pro with BCI2000, ensure that at least one amplifier is connected to the server.  If no amplifier is connected, the Amp Server software emulates an amplifier.  If you choose to use the emulated amplifier, you should expect to see a smooth sine wave signal for all channels.  To start the amp server simply navigate to the Amp Server Pro directory and double click the file named &amp;quot;&amp;lt;tt&amp;gt;Amp Server&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Creating a BCI2000 Batch File===&lt;br /&gt;
Although it is not necessary, it is convenient to create a batch file to run BCI2000 with the Amp Server Pro module.  To create the batch file, start out with a copy of a suitable batch file in &amp;lt;tt&amp;gt;BCI2000/batch/&amp;lt;/tt&amp;gt;, and open it in a text editor.&lt;br /&gt;
&lt;br /&gt;
Towards the end of the file, you will see a sequence of lines beginning with&lt;br /&gt;
 start executable &lt;br /&gt;
&lt;br /&gt;
These lines are responsible for starting up source, signal processing, and application module, in that sequence. To use the AmpServerPro module, you will need to replace the executable name in the first entry, e.g.&lt;br /&gt;
 start executable SignalGenerator --local&lt;br /&gt;
becomes&lt;br /&gt;
 start executable AmpServerPro --local&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Contributions:How_to_use_a_Contributed_Source_Module#Creating_batch_files|this page]].&lt;br /&gt;
&lt;br /&gt;
===Using Amp Server Pro with BCI2000===&lt;br /&gt;
Once you have started the Amp Server and compiled the Amp Server Pro module, you can begin collecting data with BCI2000 by following the steps below.&lt;br /&gt;
# Double click &amp;lt;tt&amp;gt;BCI2000/batch/CursorTask_AmpServerPro.bat&amp;lt;/tt&amp;gt; - the batch file that was created in the previous section - to start BCI2000.&lt;br /&gt;
# Click the &amp;quot;Configure&amp;quot; button.&lt;br /&gt;
# Set the appropriate parameters.  The Amp Server Pro module is initialized with a number of parameters that can be configured from the &amp;quot;Source&amp;quot; tab.  A summary and description of these parameters can be found below.&lt;br /&gt;
# Click &amp;quot;Set Config&amp;quot;.&lt;br /&gt;
# Click &amp;quot;Start&amp;quot; to begin your experiment.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
===SourceCh===&lt;br /&gt;
Enter the number of channels that have electrodes connected (32, 64, 128, or 256).&lt;br /&gt;
Make sure that &#039;&#039;&#039;SourceChOffset&#039;&#039;&#039; and &#039;&#039;&#039;SourceChGain&#039;&#039;&#039; are set to &amp;quot;auto&amp;quot; or you may get an error message about a mismatching number of entries.&lt;br /&gt;
&lt;br /&gt;
===BlockSize===&lt;br /&gt;
This parameter should always be set to &#039;&#039;auto&#039;&#039;. If the amp uses packet format 1, then the block size is fixed at 40 samples per block. If the amp uses packet format 2 then the block size specified by &#039;&#039;SampleBlockSize&#039;&#039; will be used. The packet format will be displayed in the operator window of BCI2000 after clicking &#039;Set Config&#039; and successful connection to amp.&lt;br /&gt;
&lt;br /&gt;
===ServerIP===&lt;br /&gt;
The IP address of the amplifier (e.g. &amp;lt;code&amp;gt;10.10.10.51&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
===CommandPort===&lt;br /&gt;
The port number of the port used for command layer communication.  Unless you have explicitly set the port number via Amp Server&#039;s configuration, the default of 9877 should be correct.&lt;br /&gt;
&lt;br /&gt;
===NotificationPort===&lt;br /&gt;
The port number of the port used for notification layer communication.  Unless you have explicitly set the port number via Amp Server&#039;s configuration, the default of 9878 should be correct.&lt;br /&gt;
&lt;br /&gt;
===StreamPort===&lt;br /&gt;
The port number of the port used for data streaming.  Unless you have explicitly set the port number via Amp Server&#039;s configuration, the default of 9879 should be correct.&lt;br /&gt;
&lt;br /&gt;
===AmplifierID===&lt;br /&gt;
Amp Server Pro is capable of managing many amplifiers concurrently.  BCI2000, however, operates with a single amplifier.  If only a single amplifier is connected, you may enter the value &amp;quot;auto&amp;quot; here and allow BCI2000 to automatically determine the Amplifier ID.  If multiple amplifiers are connected, however, you must enter a valid ID from 0 to N-1, where N is the number of amplifiers connected.&lt;br /&gt;
&lt;br /&gt;
==Packet Format 2 Parameter==&lt;br /&gt;
===SampleBlockSize=== &lt;br /&gt;
If the connected amp uses packet format 2, then the user can configure the number of samples per block using this parameter. &lt;br /&gt;
&lt;br /&gt;
==GTEN Parameters==&lt;br /&gt;
The GTEN parameters are only used when using a GTEN device. If the connected amp cannot perform stimulation, disable &#039;&#039;RunTranscranialStim&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===RunTranscranialStim===&lt;br /&gt;
Enables stimulation. If stimulation is enabled, the following parameters are used. &lt;br /&gt;
&lt;br /&gt;
===ModulationPlanFile===&lt;br /&gt;
The modulation plan file contains all of the information about the stimulation train. This file is created on the Net Station iMac with the EGI program Reciprocity. Reciprocity allows the user to configure all of the parameters of the stimulation train such as electrode location, waveform amplitude, duration, etc. See EGI&#039;s GTEN manual for information related to Reciprocity use. &lt;br /&gt;
&lt;br /&gt;
Once the train is designed in Reciprocity, save the .mcb plan file and note its location. Copy the .mcb file and transfer it to the research PC. Launch BCI2000 and click the browse button for the &#039;&#039;ModulationPlanFile&#039;&#039; parameter. On windows, the .mcb file will now be a folder. Navigate to this folder and inside, there will be multiple files and two other folders. Select the file called &#039;plan.mcf&#039; as the &#039;&#039;ModulationPlanFile&#039;&#039;. Select ONLY the &#039;plan.mcf&#039; file as the BCI2000 parameter value, but also DO NOT change any of the other contents of the .mcb folder.&lt;br /&gt;
&lt;br /&gt;
===StimulationExpression===&lt;br /&gt;
Expression that triggers stimulation. For more info on expressions, see [[User Reference:Expression Syntax]].&lt;br /&gt;
===AbortExpression===&lt;br /&gt;
Expression that aborts stimulation. If this is never triggered, the stimulation will continue until the &amp;lt;code&amp;gt;duration_ms&amp;lt;/code&amp;gt;, specified in the uploaded Modulation Plan, runs to its full duration. &lt;br /&gt;
==States==&lt;br /&gt;
===GTENStimulationTriggered===&lt;br /&gt;
This binary state is set to 1 when stimulation is triggered. &lt;br /&gt;
===GTENTrainRunning===&lt;br /&gt;
This state is one byte in size and contains information sent back from the amplifier about stimulation. If bit 2 is low (XXXX X0XX) then current is being injected by the amp. If bit 4 is low (XXX0 XXXX) then a new block in the neuromodulation train has just begun.&lt;br /&gt;
===EGIDigitalInputStream===&lt;br /&gt;
This state is 16 bits and records the digital inputs on the back of the amplifier as seen in Fig. 5.&lt;br /&gt;
===DigitalInput1-4===&lt;br /&gt;
These 4 binary states are 1 when there is a digital input, or 0 in the absence of one. This information is parsed from the EGIDigitalInputStream, but separated for user convenience. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Certification Results==&lt;br /&gt;
The AmpServerPro certification was performed to give a better understanding of the restraints that must be placed on the system when using this device. Certification success criteria was determined internally and without rigor, and reflects our experience with psychophysical experiments and the performance we expect to need for the system. More information about certification testing can be found on the [[User Reference:BCI2000Certification|certification wiki page]]. &lt;br /&gt;
&lt;br /&gt;
===PC Specifications===&lt;br /&gt;
*Lenovo Thinkpad E580 (https://www.lenovo.com/us/en/laptops/thinkpad/thinkpad-e-series/ThinkPad-E580/p/22TP2TEE580)&lt;br /&gt;
*Processor: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.7GHz&lt;br /&gt;
*Installed Ram: 8.00 GB&lt;br /&gt;
*Graphics Card: Intel(R) HD Graphics 620&lt;br /&gt;
*System Type: 64-bit operating system, x64-based processor&lt;br /&gt;
*BCI2000 compiled with MSVC2019 and Qt 5.15.2&lt;br /&gt;
&lt;br /&gt;
===Certification Tests Performed===&lt;br /&gt;
Certification testing varied block size (50, 100 ms), and task (P3Spell (7x7 grid), P3Spell (1x1 grid), CursorTask, CursorTaskLow, and StimulusPresentation), and tested audio and video latency, for a total of 12 performed tasks. The audio latency and video latency are partitioned into separate windows, as we tested them in different runs. &lt;br /&gt;
&lt;br /&gt;
===Success Criteria and Overall Results===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot;&lt;br /&gt;
|Name&lt;br /&gt;
|Actual Latency&lt;br /&gt;
|Success Criteria&lt;br /&gt;
|Result&lt;br /&gt;
|-&lt;br /&gt;
|Timestamp Latency Mean&lt;br /&gt;
|509µs&lt;br /&gt;
|1 ms&lt;br /&gt;
|passed&lt;br /&gt;
|-&lt;br /&gt;
|Timestamp Latency STD&lt;br /&gt;
|2.02ms&lt;br /&gt;
|1 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Processing Latency Mean&lt;br /&gt;
|44.7ms&lt;br /&gt;
|20 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Processing Latency STD&lt;br /&gt;
|20.3ms&lt;br /&gt;
|10 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Video Latency Mean&lt;br /&gt;
|73.1ms&lt;br /&gt;
|65 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Video Latency STD&lt;br /&gt;
|17.7ms&lt;br /&gt;
|20 ms&lt;br /&gt;
|passed&lt;br /&gt;
|-&lt;br /&gt;
|Audio Latency Mean&lt;br /&gt;
|62.9ms&lt;br /&gt;
|65 ms&lt;br /&gt;
|passed&lt;br /&gt;
|-&lt;br /&gt;
|Audio Latency STD&lt;br /&gt;
|3.33ms&lt;br /&gt;
|20 ms&lt;br /&gt;
|passed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Stimulation Latency===&lt;br /&gt;
The Stimulation Latency for the EGI system seems to be dependent on the stimulation width and ISI width. When the &#039;&#039;&#039;stimulation width plus the ISI width is less than 8 seconds&#039;&#039;&#039;, it has a large latency and can also miss stimulation (see Figure 8).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=450px heights=450px&amp;gt;&lt;br /&gt;
File:EGILatency 2sStim.png|Figure 8: The jitter of the stimulation latency, showing a large mean and variation of latency for ISI&#039;s less than 6 seconds.&lt;br /&gt;
File:EGILatencyHist.png | Figure 9: The latency of the EGI system. Run for 100 trials, with a 2s stimulation width and an 8s ISI width. The block size was 40 ms with a sampling rate of 1 kHz. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The stimulation latency seems to be inconsistent, however for large enough ISI widths, it is usually around 1.1 seconds. For the trial shown in Figure 9, the average latency was 1,159 ± 5 ms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Individual Task Breakdown===&lt;br /&gt;
====Video Latency====&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:black 1px solid;width:1000px;height:600px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
Overall result: 0/10 tasks passed, 10/10 tasks failed, 10 tasks are missing data&lt;br /&gt;
&lt;br /&gt;
global 2021-03-22T09:56:03&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=0, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=2119, &amp;lt;x&amp;gt;=509µs±2.02ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=379, &amp;lt;x&amp;gt;=44.7ms±20.3ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=379, &amp;lt;x&amp;gt;=12.9ms±12.7ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=373, &amp;lt;x&amp;gt;=73.1ms±17.7ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTask_1000_128ch_100ms001/CursorTask_1000_128ch_100msS001R01.dat 2021-03-01T10:33:38&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=216, &amp;lt;x&amp;gt;=1.66ms±1.66ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=63.7ms±18.1ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=9.34ms±13.6ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=69.8ms±5.56ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTask_1000_128ch_50ms001/CursorTask_1000_128ch_50msS001R01.dat 2021-03-01T10:31:22&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=396, &amp;lt;x&amp;gt;=263µs±1.52ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=46.2ms±7.73ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=11.9ms±4.86ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=71.2ms±6.8ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTaskLow_1000_128ch_100ms001/CursorTaskLow_1000_128ch_100msS001R01.dat 2021-03-01T10:34:06&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=216, &amp;lt;x&amp;gt;=2.37ms±1.66ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=70.2ms±21.1ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=9.94ms±5.61ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=66.4ms±5.66ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTaskLow_1000_128ch_50ms001/CursorTaskLow_1000_128ch_50msS001R01.dat 2021-03-01T10:31:47&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=397, &amp;lt;x&amp;gt;=788µs±1.56ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=47ms±8.92ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=13.4ms±5.03ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=71.3ms±5.01ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3Spell_1000_128ch_100ms001/P3Spell_1000_128ch_100msS001R01.dat 2021-03-01T10:32:44&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=289, &amp;lt;x&amp;gt;=-1.38ms±2.31ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=29.6ms±10.7ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=13.6ms±27.9ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=19, &amp;lt;x&amp;gt;=125ms±21.8ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3Spell_1000_128ch_50ms001/P3Spell_1000_128ch_50msS001R01.dat 2021-03-01T10:30:28&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=590, &amp;lt;x&amp;gt;=-1.17ms±2.07ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=16.3ms±6.37ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=43.5ms±19.3ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=110ms±15.8ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3SpellSingle_1000_128ch_100ms001/P3SpellSingle_1000_128ch_100msS001R01.dat 2021-03-01T10:33:19&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=129, &amp;lt;x&amp;gt;=1.1ms±1.55ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=37.5ms±10.5ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=12.5ms±5.32ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=69.3ms±5.57ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3SpellSingle_1000_128ch_50ms001/P3SpellSingle_1000_128ch_50msS001R01.dat 2021-03-01T10:31:03&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=269, &amp;lt;x&amp;gt;=-325µs±1.75ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=16.4ms±3.81ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=10.2ms±6ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=68.2ms±5.57ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/StimulusPresentationAV_128ch_100ms001/StimulusPresentationAV_128ch_100msS001R01.dat 2021-03-01T10:34:34&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=207, &amp;lt;x&amp;gt;=647µs±1.57ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=38.2ms±10.9ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=9.8ms±5.81ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=37.6ms±2.7ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=66.6ms±5.92ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/StimulusPresentationAV_128ch_50ms001/StimulusPresentationAV_128ch_50msS001R01.dat 2021-03-01T10:32:12&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=527, &amp;lt;x&amp;gt;=1.62ms±2.02ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=34.8ms±8.53ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=11.9ms±6.12ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=38.3ms±4.28ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=62ms±9.89ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
====Audio Latency====&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:black 1px solid;width:1000px;height:600px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
Overall result: 0/2 tasks passed, 2/2 tasks failed, 2 tasks are missing data&lt;br /&gt;
&lt;br /&gt;
global 2021-03-22T09:59:01&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=0, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=734, &amp;lt;x&amp;gt;=1.11ms±1.79ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=18.6ms±7.01ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=9.7ms±6.35ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=38.1ms±3.37ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=0, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=62.9ms±3.33ms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_audio/StimulusPresentationAV_128ch_100ms001/StimulusPresentationAV_128ch_100msS001R01.dat 2021-02-27T09:13:48&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=208, &amp;lt;x&amp;gt;=-251µs±1.72ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=20ms±8.2ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=8.88ms±6.68ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=37.1ms±2.84ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=63.9ms±3.43ms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_audio/StimulusPresentationAV_128ch_50ms001/StimulusPresentationAV_128ch_50msS001R01.dat 2021-02-27T09:13:16&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=526, &amp;lt;x&amp;gt;=1.65ms±1.52ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=17.3ms±5.25ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=10.5ms±5.9ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=39.1ms±3.56ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=62ms±2.95ms&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:AmpServerProADC&amp;diff=12371</id>
		<title>Contributions:AmpServerProADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:AmpServerProADC&amp;diff=12371"/>
		<updated>2026-03-18T13:43:28Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Versioning */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Synopsis==&lt;br /&gt;
The &#039;&#039;AmpServerProADC&#039;&#039; component implements the client side of EGI&#039;s TCP/IP-based Amp Server Pro (ASP) protocol. Thus, it may be used to interface BCI2000 with an EGI amplifier. Amplifiers that record data and administer transcranial direct current stimulation (GTEN devices) are supported.&lt;br /&gt;
&lt;br /&gt;
==Location==&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/contrib/SignalSource/AmpServerPro&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Author===&lt;br /&gt;
Joshua Fialkoff, (c) 2008 Wadsworth Center, New York State Department of Health. (V1)&lt;br /&gt;
&lt;br /&gt;
Alex Belsten (belsten@neurotechcenter.org), NCAN. (V2)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* V1.00 - 06/11/2008 - First working version&lt;br /&gt;
* V2.00 - 05/10/2020 - Added support for GTEN devices and packet format 2 &lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 1998&lt;br /&gt;
*Tested under: 9297&lt;br /&gt;
*Known to compile under: 9297&lt;br /&gt;
*Stimulation broken since: 7273&lt;br /&gt;
Race condition in AmpServerProADC allows stimulation to start before train upload completes, causing “train not uploaded” errors and SignalSource crashes.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&amp;lt;youtube alignment=&amp;quot;center&amp;quot;&amp;gt;https://www.youtube.com/watch?v=wW-xEy9e5ps&amp;amp;list=PL6LrR5Nj3cAxOxKHNsnqyKfLDGikpi8Qi&amp;amp;index=7&amp;lt;/youtube&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using the AmpServerPro Source Module==&lt;br /&gt;
For using the AmpServerPro source module, you will need to obtain a license for the AmpServerPro SDK. Without such a license, you may be able to connect to the machine running the EGI software, but it will not send any real-time data when asked to. In order to obtain an AmpServerPro SDK license, you will need to contact EGI at http://www.egi.com.&lt;br /&gt;
&lt;br /&gt;
==Setting Up the Hardware==&lt;br /&gt;
The EGI system comes with many hardware and cables, so connecting everything in a step-by-step manner is helpful for getting everything connected correctly. There are a few steps to this process. First, make sure you have all of the necessary cables and hardware. These items can be seen in the two images below (Fig. 1 and Fig. 2). &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:EGI-cables.jpeg|Figure 1: The necessary cables.&lt;br /&gt;
File:EGI-boxes.jpg|Figure 2: EGI hardware.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
In addition to the hardware shown in Fig. 1 and 2, you will need the EGI iMac that comes with the amplifier and a research PC. This PC must be running Windows and needs an ethernet port or an adapter that connects to an ethernet cable.&lt;br /&gt;
Once sure that all of the necessary hardware/cables are present, it is time to connect all the hardware. For your reference, the general architecture is shown in the figure below. &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:EGI-power_and_network.png|Figure 3: General hardware architecture.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
===Setting up the Power Supplies===&lt;br /&gt;
The transformer is the first piece of hardware to set up. It provides isolated power to the EGI amplifier, switch box, and EGI iMac. Each of these devices connects to the plugs on the back of the transformer, as shown in Fig. 4. &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:EGI-transformer_connections.jpeg|Figure 4: Three different types of plugs on the back of the transformer.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verify that the transformer is off and use plug type 3 in Fig. 4 to plug into a standard wall socket. Now, connect the EGI iMac to plug type 2. Next, you will need two cables of type 1 (IEC plug cable). Connect one to the amplifier power supply and the other to the switch box. Keep the transformer off for now. Lastly, you will need to use the amplifier power cable to connect the amplifier power supply to the amplifier.&lt;br /&gt;
&lt;br /&gt;
===Setting up the Network Cables===&lt;br /&gt;
Next, the network cables need to be connected. Fig. 5 and 6 serve as a reference through this process. &lt;br /&gt;
&amp;lt;gallery class=&amp;quot;center&amp;quot; mode=&amp;quot;nolines&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:EGI-back-of-amp.jpeg|Figure 5: Connections to back of amplifier.&lt;br /&gt;
File:EGI-switch-box.jpeg|Figure 6: Network connections to switch box.&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Start by connecting the orange fiber optic cable to the back of the amplifier and then connect the other end to the front of the switch box. Then, connect one of the network cables to the EGI iMac and connect the other end to any one of the eight ports on the switch box. Lastly, connect the other network cable to your research PC and then to the switch box. Now that everything is connected, the transformer and amplifier power supply can be turned on. Next, boot up the EGI iMac. Navigate to the browser and enter the amplifier&#039;s IPv4 address into the address bar. You can find the IPv4 address of your amplifier by launching Net Station Acquisition on the EGI iMac and expanding the &#039;&#039;sharing&#039;&#039; tab. All of the EGI amplifiers have an IPv4 address of the form &amp;lt;code&amp;gt;10.10.10.X&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;X&amp;lt;/code&amp;gt; is some integer between 0 and 256. You should now see the amplifier&#039;s web page, similar to the one shown in Fig. 7. If you cannot see this web page, verify that all network connections are secure and the amplifier is powered on.  &lt;br /&gt;
&amp;lt;gallery class=&amp;quot;center&amp;quot; mode=&amp;quot;nolines&amp;quot; widths=600px heights=600px&amp;gt;&lt;br /&gt;
File:EGI-amp_webserver.jpg|Figure 7: Amplifier webpage that is accessible from amplifier&#039;s IPv4 address.  &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Configuring and Setting Up BCI2000 on the Research PC==&lt;br /&gt;
Now it is time to set up the research PC. First, install BCI2000 (a guide to do this can be found at [[Programming_Howto:Building_and_Customizing_BCI2000]]) and make sure the &amp;lt;code&amp;gt;BUILD_CONTRIB&amp;lt;/code&amp;gt; option is enabled in CMake before compiling. &lt;br /&gt;
&lt;br /&gt;
The research PC&#039;s IP address must be configured to allow the amplifier and Net Station to recognize it. On the research PC, configure the IP (IPv4) for a manual IP address (&amp;lt;code&amp;gt;10.10.10.Y&amp;lt;/code&amp;gt; where &amp;lt;code&amp;gt;Y&amp;lt;/code&amp;gt; is any digits other than the last two digits used by the amp); with the manual IPv4 address configured, set the subnet mask to 255.255.255.0. Once this has been completed, open a browser on the research PC and enter the amplifier&#039;s IPv4 address into the address bar. If the research PC&#039;s IP address is set correctly, the page will populate with information about the amplifier shown in Fig. 7. If the web page fails to load, then the PC&#039;s IPv4 address may not have been set correctly, or the research PC has a firewall that is blocking the amplifier. Verify that the research IPv4 address is correct and firewalls have been disabled. &lt;br /&gt;
&lt;br /&gt;
===Starting Amp Server Pro===&lt;br /&gt;
Amp Server Pro is capable of working with many amplifiers concurrently.  To begin using Amp Server Pro with BCI2000, ensure that at least one amplifier is connected to the server.  If no amplifier is connected, the Amp Server software emulates an amplifier.  If you choose to use the emulated amplifier, you should expect to see a smooth sine wave signal for all channels.  To start the amp server simply navigate to the Amp Server Pro directory and double click the file named &amp;quot;&amp;lt;tt&amp;gt;Amp Server&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Creating a BCI2000 Batch File===&lt;br /&gt;
Although it is not necessary, it is convenient to create a batch file to run BCI2000 with the Amp Server Pro module.  To create the batch file, start out with a copy of a suitable batch file in &amp;lt;tt&amp;gt;BCI2000/batch/&amp;lt;/tt&amp;gt;, and open it in a text editor.&lt;br /&gt;
&lt;br /&gt;
Towards the end of the file, you will see a sequence of lines beginning with&lt;br /&gt;
 start executable &lt;br /&gt;
&lt;br /&gt;
These lines are responsible for starting up source, signal processing, and application module, in that sequence. To use the AmpServerPro module, you will need to replace the executable name in the first entry, e.g.&lt;br /&gt;
 start executable SignalGenerator --local&lt;br /&gt;
becomes&lt;br /&gt;
 start executable AmpServerPro --local&lt;br /&gt;
&lt;br /&gt;
For more information, see [[Contributions:How_to_use_a_Contributed_Source_Module#Creating_batch_files|this page]].&lt;br /&gt;
&lt;br /&gt;
===Using Amp Server Pro with BCI2000===&lt;br /&gt;
Once you have started the Amp Server and compiled the Amp Server Pro module, you can begin collecting data with BCI2000 by following the steps below.&lt;br /&gt;
# Double click &amp;lt;tt&amp;gt;BCI2000/batch/CursorTask_AmpServerPro.bat&amp;lt;/tt&amp;gt; - the batch file that was created in the previous section - to start BCI2000.&lt;br /&gt;
# Click the &amp;quot;Configure&amp;quot; button.&lt;br /&gt;
# Set the appropriate parameters.  The Amp Server Pro module is initialized with a number of parameters that can be configured from the &amp;quot;Source&amp;quot; tab.  A summary and description of these parameters can be found below.&lt;br /&gt;
# Click &amp;quot;Set Config&amp;quot;.&lt;br /&gt;
# Click &amp;quot;Start&amp;quot; to begin your experiment.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
===SourceCh===&lt;br /&gt;
Enter the number of channels that have electrodes connected (32, 64, 128, or 256).&lt;br /&gt;
Make sure that &#039;&#039;&#039;SourceChOffset&#039;&#039;&#039; and &#039;&#039;&#039;SourceChGain&#039;&#039;&#039; are set to &amp;quot;auto&amp;quot; or you may get an error message about a mismatching number of entries.&lt;br /&gt;
&lt;br /&gt;
===BlockSize===&lt;br /&gt;
This parameter should always be set to &#039;&#039;auto&#039;&#039;. If the amp uses packet format 1, then the block size is fixed at 40 samples per block. If the amp uses packet format 2 then the block size specified by &#039;&#039;SampleBlockSize&#039;&#039; will be used. The packet format will be displayed in the operator window of BCI2000 after clicking &#039;Set Config&#039; and successful connection to amp.&lt;br /&gt;
&lt;br /&gt;
===ServerIP===&lt;br /&gt;
The IP address of the amplifier (e.g. &amp;lt;code&amp;gt;10.10.10.51&amp;lt;/code&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
===CommandPort===&lt;br /&gt;
The port number of the port used for command layer communication.  Unless you have explicitly set the port number via Amp Server&#039;s configuration, the default of 9877 should be correct.&lt;br /&gt;
&lt;br /&gt;
===NotificationPort===&lt;br /&gt;
The port number of the port used for notification layer communication.  Unless you have explicitly set the port number via Amp Server&#039;s configuration, the default of 9878 should be correct.&lt;br /&gt;
&lt;br /&gt;
===StreamPort===&lt;br /&gt;
The port number of the port used for data streaming.  Unless you have explicitly set the port number via Amp Server&#039;s configuration, the default of 9879 should be correct.&lt;br /&gt;
&lt;br /&gt;
===AmplifierID===&lt;br /&gt;
Amp Server Pro is capable of managing many amplifiers concurrently.  BCI2000, however, operates with a single amplifier.  If only a single amplifier is connected, you may enter the value &amp;quot;auto&amp;quot; here and allow BCI2000 to automatically determine the Amplifier ID.  If multiple amplifiers are connected, however, you must enter a valid ID from 0 to N-1, where N is the number of amplifiers connected.&lt;br /&gt;
&lt;br /&gt;
==Packet Format 2 Parameter==&lt;br /&gt;
===SampleBlockSize=== &lt;br /&gt;
If the connected amp uses packet format 2, then the user can configure the number of samples per block using this parameter. &lt;br /&gt;
&lt;br /&gt;
==GTEN Parameters==&lt;br /&gt;
The GTEN parameters are only used when using a GTEN device. If the connected amp cannot perform stimulation, disable &#039;&#039;RunTranscranialStim&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===RunTranscranialStim===&lt;br /&gt;
Enables stimulation. If stimulation is enabled, the following parameters are used. &lt;br /&gt;
&lt;br /&gt;
===ModulationPlanFile===&lt;br /&gt;
The modulation plan file contains all of the information about the stimulation train. This file is created on the Net Station iMac with the EGI program Reciprocity. Reciprocity allows the user to configure all of the parameters of the stimulation train such as electrode location, waveform amplitude, duration, etc. See EGI&#039;s GTEN manual for information related to Reciprocity use. &lt;br /&gt;
&lt;br /&gt;
Once the train is designed in Reciprocity, save the .mcb plan file and note its location. Copy the .mcb file and transfer it to the research PC. Launch BCI2000 and click the browse button for the &#039;&#039;ModulationPlanFile&#039;&#039; parameter. On windows, the .mcb file will now be a folder. Navigate to this folder and inside, there will be multiple files and two other folders. Select the file called &#039;plan.mcf&#039; as the &#039;&#039;ModulationPlanFile&#039;&#039;. Select ONLY the &#039;plan.mcf&#039; file as the BCI2000 parameter value, but also DO NOT change any of the other contents of the .mcb folder.&lt;br /&gt;
&lt;br /&gt;
===StimulationExpression===&lt;br /&gt;
Expression that triggers stimulation. For more info on expressions, see [[User Reference:Expression Syntax]].&lt;br /&gt;
===AbortExpression===&lt;br /&gt;
Expression that aborts stimulation. If this is never triggered, the stimulation will continue until the &amp;lt;code&amp;gt;duration_ms&amp;lt;/code&amp;gt;, specified in the uploaded Modulation Plan, runs to its full duration. &lt;br /&gt;
==States==&lt;br /&gt;
===GTENStimulationTriggered===&lt;br /&gt;
This binary state is set to 1 when stimulation is triggered. &lt;br /&gt;
===GTENTrainRunning===&lt;br /&gt;
This state is one byte in size and contains information sent back from the amplifier about stimulation. If bit 2 is low (XXXX X0XX) then current is being injected by the amp. If bit 4 is low (XXX0 XXXX) then a new block in the neuromodulation train has just begun.&lt;br /&gt;
===EGIDigitalInputStream===&lt;br /&gt;
This state is 16 bits and records the digital inputs on the back of the amplifier as seen in Fig. 5.&lt;br /&gt;
===DigitalInput1-4===&lt;br /&gt;
These 4 binary states are 1 when there is a digital input, or 0 in the absence of one. This information is parsed from the EGIDigitalInputStream, but separated for user convenience. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Certification Results==&lt;br /&gt;
The AmpServerPro certification was performed to give a better understanding of the restraints that must be placed on the system when using this device. Certification success criteria was determined internally and without rigor, and reflects our experience with psychophysical experiments and the performance we expect to need for the system. More information about certification testing can be found on the [[User Reference:BCI2000Certification|certification wiki page]]. &lt;br /&gt;
&lt;br /&gt;
===PC Specifications===&lt;br /&gt;
*Lenovo Thinkpad E580 (https://www.lenovo.com/us/en/laptops/thinkpad/thinkpad-e-series/ThinkPad-E580/p/22TP2TEE580)&lt;br /&gt;
*Processor: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2.7GHz&lt;br /&gt;
*Installed Ram: 8.00 GB&lt;br /&gt;
*Graphics Card: Intel(R) HD Graphics 620&lt;br /&gt;
*System Type: 64-bit operating system, x64-based processor&lt;br /&gt;
*BCI2000 compiled with MSVC2019 and Qt 5.15.2&lt;br /&gt;
&lt;br /&gt;
===Certification Tests Performed===&lt;br /&gt;
Certification testing varied block size (50, 100 ms), and task (P3Spell (7x7 grid), P3Spell (1x1 grid), CursorTask, CursorTaskLow, and StimulusPresentation), and tested audio and video latency, for a total of 12 performed tasks. The audio latency and video latency are partitioned into separate windows, as we tested them in different runs. &lt;br /&gt;
&lt;br /&gt;
===Success Criteria and Overall Results===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot;&lt;br /&gt;
|Name&lt;br /&gt;
|Actual Latency&lt;br /&gt;
|Success Criteria&lt;br /&gt;
|Result&lt;br /&gt;
|-&lt;br /&gt;
|Timestamp Latency Mean&lt;br /&gt;
|509µs&lt;br /&gt;
|1 ms&lt;br /&gt;
|passed&lt;br /&gt;
|-&lt;br /&gt;
|Timestamp Latency STD&lt;br /&gt;
|2.02ms&lt;br /&gt;
|1 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Processing Latency Mean&lt;br /&gt;
|44.7ms&lt;br /&gt;
|20 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Processing Latency STD&lt;br /&gt;
|20.3ms&lt;br /&gt;
|10 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Video Latency Mean&lt;br /&gt;
|73.1ms&lt;br /&gt;
|65 ms&lt;br /&gt;
|failed&lt;br /&gt;
|-&lt;br /&gt;
|Video Latency STD&lt;br /&gt;
|17.7ms&lt;br /&gt;
|20 ms&lt;br /&gt;
|passed&lt;br /&gt;
|-&lt;br /&gt;
|Audio Latency Mean&lt;br /&gt;
|62.9ms&lt;br /&gt;
|65 ms&lt;br /&gt;
|passed&lt;br /&gt;
|-&lt;br /&gt;
|Audio Latency STD&lt;br /&gt;
|3.33ms&lt;br /&gt;
|20 ms&lt;br /&gt;
|passed&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Stimulation Latency===&lt;br /&gt;
The Stimulation Latency for the EGI system seems to be dependent on the stimulation width and ISI width. When the &#039;&#039;&#039;stimulation width plus the ISI width is less than 8 seconds&#039;&#039;&#039;, it has a large latency and can also miss stimulation (see Figure 8).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=450px heights=450px&amp;gt;&lt;br /&gt;
File:EGILatency 2sStim.png|Figure 8: The jitter of the stimulation latency, showing a large mean and variation of latency for ISI&#039;s less than 6 seconds.&lt;br /&gt;
File:EGILatencyHist.png | Figure 9: The latency of the EGI system. Run for 100 trials, with a 2s stimulation width and an 8s ISI width. The block size was 40 ms with a sampling rate of 1 kHz. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The stimulation latency seems to be inconsistent, however for large enough ISI widths, it is usually around 1.1 seconds. For the trial shown in Figure 9, the average latency was 1,159 ± 5 ms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
===Individual Task Breakdown===&lt;br /&gt;
====Video Latency====&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:black 1px solid;width:1000px;height:600px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
Overall result: 0/10 tasks passed, 10/10 tasks failed, 10 tasks are missing data&lt;br /&gt;
&lt;br /&gt;
global 2021-03-22T09:56:03&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=0, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=2119, &amp;lt;x&amp;gt;=509µs±2.02ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=379, &amp;lt;x&amp;gt;=44.7ms±20.3ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=379, &amp;lt;x&amp;gt;=12.9ms±12.7ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=373, &amp;lt;x&amp;gt;=73.1ms±17.7ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTask_1000_128ch_100ms001/CursorTask_1000_128ch_100msS001R01.dat 2021-03-01T10:33:38&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=216, &amp;lt;x&amp;gt;=1.66ms±1.66ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=63.7ms±18.1ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=9.34ms±13.6ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=69.8ms±5.56ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTask_1000_128ch_50ms001/CursorTask_1000_128ch_50msS001R01.dat 2021-03-01T10:31:22&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=396, &amp;lt;x&amp;gt;=263µs±1.52ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=46.2ms±7.73ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=11.9ms±4.86ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=71.2ms±6.8ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTaskLow_1000_128ch_100ms001/CursorTaskLow_1000_128ch_100msS001R01.dat 2021-03-01T10:34:06&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=216, &amp;lt;x&amp;gt;=2.37ms±1.66ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=70.2ms±21.1ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=9.94ms±5.61ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=66.4ms±5.66ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/CursorTaskLow_1000_128ch_50ms001/CursorTaskLow_1000_128ch_50msS001R01.dat 2021-03-01T10:31:47&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=397, &amp;lt;x&amp;gt;=788µs±1.56ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=47ms±8.92ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=13.4ms±5.03ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=71.3ms±5.01ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3Spell_1000_128ch_100ms001/P3Spell_1000_128ch_100msS001R01.dat 2021-03-01T10:32:44&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=289, &amp;lt;x&amp;gt;=-1.38ms±2.31ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=29.6ms±10.7ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=13.6ms±27.9ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=19, &amp;lt;x&amp;gt;=125ms±21.8ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3Spell_1000_128ch_50ms001/P3Spell_1000_128ch_50msS001R01.dat 2021-03-01T10:30:28&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=590, &amp;lt;x&amp;gt;=-1.17ms±2.07ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=16.3ms±6.37ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=43.5ms±19.3ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=110ms±15.8ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3SpellSingle_1000_128ch_100ms001/P3SpellSingle_1000_128ch_100msS001R01.dat 2021-03-01T10:33:19&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=129, &amp;lt;x&amp;gt;=1.1ms±1.55ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=37.5ms±10.5ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=12.5ms±5.32ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=69.3ms±5.57ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/P3SpellSingle_1000_128ch_50ms001/P3SpellSingle_1000_128ch_50msS001R01.dat 2021-03-01T10:31:03&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=269, &amp;lt;x&amp;gt;=-325µs±1.75ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=16.4ms±3.81ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=10.2ms±6ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=20, &amp;lt;x&amp;gt;=68.2ms±5.57ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/StimulusPresentationAV_128ch_100ms001/StimulusPresentationAV_128ch_100msS001R01.dat 2021-03-01T10:34:34&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  failed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=207, &amp;lt;x&amp;gt;=647µs±1.57ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=38.2ms±10.9ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=9.8ms±5.81ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=37.6ms±2.7ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=66.6ms±5.92ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_video/StimulusPresentationAV_128ch_50ms001/StimulusPresentationAV_128ch_50msS001R01.dat 2021-03-01T10:32:12&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=527, &amp;lt;x&amp;gt;=1.62ms±2.02ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=34.8ms±8.53ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=11.9ms±6.12ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=38.3ms±4.28ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=62ms±9.89ms&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
====Audio Latency====&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:black 1px solid;width:1000px;height:600px;overflow:auto;&amp;quot;&amp;gt;&lt;br /&gt;
Overall result: 0/2 tasks passed, 2/2 tasks failed, 2 tasks are missing data&lt;br /&gt;
&lt;br /&gt;
global 2021-03-22T09:59:01&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=0, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=734, &amp;lt;x&amp;gt;=1.11ms±1.79ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=18.6ms±7.01ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=9.7ms±6.35ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=38.1ms±3.37ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=0, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=99, &amp;lt;x&amp;gt;=62.9ms±3.33ms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_audio/StimulusPresentationAV_128ch_100ms001/StimulusPresentationAV_128ch_100msS001R01.dat 2021-02-27T09:13:48&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  passed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=208, &amp;lt;x&amp;gt;=-251µs±1.72ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=20ms±8.2ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=8.88ms±6.68ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=37.1ms±2.84ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=49, &amp;lt;x&amp;gt;=63.9ms±3.43ms&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:/BCI2000/data/EGICertification_audio/StimulusPresentationAV_128ch_50ms001/StimulusPresentationAV_128ch_50msS001R01.dat 2021-02-27T09:13:16&lt;br /&gt;
could not evaluate all 10 requirements:&lt;br /&gt;
  AmpLatency.mean() &amp;lt; time(&amp;quot;7ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AmpLatency.sdev() &amp;lt; time(&amp;quot;2ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  TimestampLatency.mean() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  TimestampLatency.sdev() &amp;lt; time(&amp;quot;1ms&amp;quot;)  failed&lt;br /&gt;
  ProcessingLatency.mean() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  ProcessingLatency.sdev() &amp;lt; time(&amp;quot;10ms&amp;quot;)  passed&lt;br /&gt;
  VideoLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  VideoLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  missing or invalid data&lt;br /&gt;
  AudioLatency.mean() &amp;lt; time(&amp;quot;65ms&amp;quot;)  passed&lt;br /&gt;
  AudioLatency.sdev() &amp;lt; time(&amp;quot;20ms&amp;quot;)  passed&lt;br /&gt;
  AmpLatency -- interval between block begin, and amp digital out signal change:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  TimestampLatency -- clock skew between sample clock, and SourceTime time stamp:&lt;br /&gt;
  n=526, &amp;lt;x&amp;gt;=1.65ms±1.52ms&lt;br /&gt;
  ProcessingLatency -- time interval between block received, and stimulus triggered:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=17.3ms±5.25ms&lt;br /&gt;
  PresentationLatency -- time interval between stimulus trigger, and video memory change:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=10.5ms±5.9ms&lt;br /&gt;
  AudioPresentationLatency -- time interval between audio buffering, and estimated audio output:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=39.1ms±3.56ms&lt;br /&gt;
  VideoLatency -- time interval between stimulus trigger, and video signal change detected:&lt;br /&gt;
  n=nan, &amp;lt;x&amp;gt;=nan±nan&lt;br /&gt;
  AudioLatency -- time interval between stimulus trigger, and audio signal detected:&lt;br /&gt;
  n=50, &amp;lt;x&amp;gt;=62ms±2.95ms&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=User_Reference:gNautilus&amp;diff=12339</id>
		<title>User Reference:gNautilus</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=User_Reference:gNautilus&amp;diff=12339"/>
		<updated>2026-02-25T14:00:13Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Synopsis==&lt;br /&gt;
The g.Nautilus is a biopotential amplifier with wireless transmission technology with either wet or dry electrodes. It reads in up to 32 signal channels and 8 trigger channels.&lt;br /&gt;
&lt;br /&gt;
==Location==&lt;br /&gt;
http://{{SERVERNAME}}/svn/trunk/src/core/SignalSource/g.NautilusSource&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
===Author===&lt;br /&gt;
Kristopher Kaleb Goering (kaleb.goering@gmail.com) University of Kansas&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 4928&lt;br /&gt;
*Tested under: 9282&lt;br /&gt;
*Known to compile under: 9282&lt;br /&gt;
*Broken since: N/A&lt;br /&gt;
&lt;br /&gt;
==Functional Description==&lt;br /&gt;
The g.Nautilus is a wireless headset by g.tec, and is the first in their product line to use g.NEEDaccess exclusively for realtime access.  This documentation explains the parameterization and specifics on how to set up the system.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Install g.NEEDaccess_Sever. Ensure the device is charged and connected to the base station (refer to the included documentation for help with this).  Start BCI2000 with the gNautilusSource module.&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
===SourceCh===&lt;br /&gt;
represents the total number of channels to be logged from the source module.&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
should be set equal to the size of the sample block pulled from the device.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; &amp;lt;span style=&amp;quot;text-decoration: underline;&amp;quot;&amp;gt; 25 and up found to work best during testing for 250Hz&amp;lt;/span&amp;gt;&lt;br /&gt;
===SampleRate===&lt;br /&gt;
determines the rate at which the device samples data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; &amp;lt;span style=&amp;quot;text-decoration: underline;&amp;quot;&amp;gt;Only the following sample rates are currently supported by the API: 250Hz and 500Hz.&amp;lt;/span&amp;gt;&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
is a convenience parameter.  Name channels here and they can be referenced by these names later.&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
should be set to a list of &amp;quot;0&amp;quot;s -- one 0 for each channel as indicated by SourceCh, separated by spaces.&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
should be set to a list of &amp;quot;1&amp;quot;s -- one 0 for each channel as indicated by SourceCh, separated by spaces.&lt;br /&gt;
===DeviceIDMaster===&lt;br /&gt;
is the serial number identifier of the master g.Nautilus device.  This serial can be found on the physical device and is typically in a &amp;quot;&#039;&#039;&#039;NB-20XX.XX.XX&#039;&#039;&#039;&amp;quot; format.  This parameter can also be set to &amp;quot;&#039;&#039;&#039;auto&#039;&#039;&#039;&amp;quot; if there is only one g.Nautilus device connected to the machine.&lt;br /&gt;
===DeviceIDs===&lt;br /&gt;
is a list of device serials (typically in &amp;quot;&#039;&#039;&#039;NB-20XX.XX.XX&#039;&#039;&#039;&amp;quot; format) which corresponds to the devices to record channels from.  One of these serials must be specified as the master device in the &amp;quot;DeviceIDMaster&amp;quot; parameter.  This parameter can also be set to &amp;quot;&#039;&#039;&#039;auto&#039;&#039;&#039;&amp;quot; if there is only one g.Nautilus device connected to the machine.  &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; &amp;lt;span style=&amp;quot;text-decoration: underline;&amp;quot;&amp;gt;Device slaving has not been tested. &amp;lt;/span&amp;gt;&lt;br /&gt;
===RefChList===&lt;br /&gt;
is a list of channels which can act as &amp;quot;Reference&amp;quot; channels for each device.  If left blank, no channel will be used as a reference, and the raw signal will be recorded in the output.  &amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE:&#039;&#039;&#039; &amp;lt;span style=&amp;quot;text-decoration: underline;&amp;quot;&amp;gt;If specifying reference channels, there must be one reference channel per device specified in &amp;quot;DeviceIDs&amp;quot; in the same order. &amp;lt;/span&amp;gt;&lt;br /&gt;
===SourceChList===&lt;br /&gt;
===FilterEnabled===&lt;br /&gt;
===FilterHighPass===&lt;br /&gt;
===FilterLowPass===&lt;br /&gt;
===FilterModelOrder===&lt;br /&gt;
===FilterType===&lt;br /&gt;
===NotchEnabled===&lt;br /&gt;
===NotchHighPass===&lt;br /&gt;
===NotchLowPass===&lt;br /&gt;
===NotchModelOrder===&lt;br /&gt;
===NotchType===&lt;br /&gt;
===SourceBufferSize===&lt;br /&gt;
===EnableAccelerationData===&lt;br /&gt;
is a toggle button to enable acceleration data and store them in synchronous states AccelerationX1, AcceleratioY1, and AccelerationZ1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; &amp;lt;span style= &amp;quot;text-decoration: underline;&amp;quot;&amp;gt; To record acceleration data, at least one analog channel must also be recorded. &amp;lt;/span&amp;gt;&lt;br /&gt;
===EnableCounterInput===&lt;br /&gt;
is a toggle button to enable the counter data and store it in the synchronous state Counter1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; &amp;lt;span style= &amp;quot;text-decoration: underline;&amp;quot;&amp;gt; To record counter data, at least one analog channel must also be recorded. &amp;lt;/span&amp;gt;&lt;br /&gt;
===EnableLinkQuality===&lt;br /&gt;
is a toggle button to enable the link quality data and store it in the synchronous state LinkQuality1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; &amp;lt;span style= &amp;quot;text-decoration: underline;&amp;quot;&amp;gt; To record link quality data, at least one analog channel must also be recorded. &amp;lt;/span&amp;gt;&lt;br /&gt;
===EnableBatteryLevel===&lt;br /&gt;
is a toggle button to enable the battery level data and store it in the synchronous state Battery1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; &amp;lt;span style= &amp;quot;text-decoration: underline;&amp;quot;&amp;gt; To record battery level data, at least one analog channel must also be recorded. &amp;lt;/span&amp;gt;&lt;br /&gt;
===EnableDigitalInputs===&lt;br /&gt;
is a toggle button to enable both digital input ports and store them in synchronous states DigitalInput1 - DigitalInput8.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; &amp;lt;span style= &amp;quot;text-decoration: underline;&amp;quot;&amp;gt; To record digital input, at least one analog channel must also be recorded. &amp;lt;/span&amp;gt;&lt;br /&gt;
===EnableValidationIndicator===&lt;br /&gt;
is a toggle button to enable validation data and store it in the synchronous state Validation1.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; &amp;lt;span style= &amp;quot;text-decoration: underline;&amp;quot;&amp;gt; To record validation data, at least one analog channel must also be recorded. &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
===Acceleration===&lt;br /&gt;
Acceleration is stored in three separate states with the axis labeled, i.e. the acceleration on the x-axis is stored in AccelerationX1.&lt;br /&gt;
The g.Nautilus records the acceleration between -6g and 6g. It is then translated into a value between 0 and 65535 with the equation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\lfloor((acceleration + 6) / 12) * 65535\rfloor&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus if the acceleration was 0 then the state would have the value 32767.&lt;br /&gt;
&lt;br /&gt;
===Counter===&lt;br /&gt;
Counter is a value that is constantly increasing in value and then repeats starting at 0. It is stored in Counter1.&lt;br /&gt;
&lt;br /&gt;
===Link Quality===&lt;br /&gt;
Link quality is a value between 0 and 100. It is stored in LinkQuality1. When link quality falls bellow 10% the first time, BCI2000 will give a warning.&lt;br /&gt;
&lt;br /&gt;
===Battery Level===&lt;br /&gt;
Battery level is a value between 0 and 100. It is stored in Battery1. When battery falls bellow 10%, BCI2000 will give a warning and again when it falls below 5%.&lt;br /&gt;
&lt;br /&gt;
===Digital Input===&lt;br /&gt;
Digital input port is on the Base Station. The value is between 0 and 255 and then separated into to a binary number which is then saved in a state with the corresponding number of the bit, i.e. bit 5 is stored in DigitalInput5.&lt;br /&gt;
&lt;br /&gt;
[[File:gNautilusDigitalInput.jpg]]&lt;br /&gt;
&lt;br /&gt;
===Validation Indicator===&lt;br /&gt;
Validation indicator is a value of 0 or 1. It is stored in Validation1. If it is 0, then the data may not be valid. If it is 1, the data is valid.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:PersistantFunction.png&amp;diff=12338</id>
		<title>File:PersistantFunction.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:PersistantFunction.png&amp;diff=12338"/>
		<updated>2026-02-25T13:57:15Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:PersistantCommand.png&amp;diff=12337</id>
		<title>File:PersistantCommand.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:PersistantCommand.png&amp;diff=12337"/>
		<updated>2026-02-25T13:56:14Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:VolatileCommand.png&amp;diff=12336</id>
		<title>File:VolatileCommand.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:VolatileCommand.png&amp;diff=12336"/>
		<updated>2026-02-25T13:55:11Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12335</id>
		<title>Contributions:CortecADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:CortecADC&amp;diff=12335"/>
		<updated>2026-02-25T13:54:35Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:CorTec_BrainInterchange.png|400px|thumb|right|CorTec Brain Interchange Implant]]&lt;br /&gt;
&lt;br /&gt;
CortecADC is a source module that allows for intra-cranial recording and stimulating over 32 channels via a fully implantable device. It is intended for long-term measurement of neural activity and electrical stimulation of brain tissue. See the [https://www.cortec-neuro.com/solutions/complete-system/ CorTec site] for more information.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;See the [[CortecExperience]] page for user tutorials and a broad overview!&#039;&#039;&#039; After viewing the [[CortecExperience]] page, refer to this page for detailed instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* William Engelhardt (engelhardt@neurotechcenter.org)&lt;br /&gt;
* Alexander Belsten (belsten@neurotechcenter.org)&lt;br /&gt;
* Markus Adamek (adamek@neurotechcenter.org)&lt;br /&gt;
* Christian Stolle (christian.stolle@cortec-neuro.com)&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: 6266&lt;br /&gt;
*Tested under: 9282&lt;br /&gt;
*Known to compile under: 9282&lt;br /&gt;
*Broken since: --&lt;br /&gt;
&lt;br /&gt;
===BCI2000 Version History===&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Date !! Revision !! Note !! Contributor&lt;br /&gt;
|-&lt;br /&gt;
!11/29/2018&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R5829&lt;br /&gt;
|Initial untested version&lt;br /&gt;
|Adamek&lt;br /&gt;
|-&lt;br /&gt;
!04/19/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6271&lt;br /&gt;
|First working version&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!07/22/2021&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R6339&lt;br /&gt;
|Changed &#039;&#039;ImplantLostSample&#039;&#039; from a BCI2000 state to a stream, so it can record individual sample loss (instead of over the whole block)&lt;br /&gt;
|Belsten&lt;br /&gt;
|-&lt;br /&gt;
!01/01/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7133&lt;br /&gt;
|Updated API to version 1.0.200. &lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!03/08/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7251&lt;br /&gt;
|Stimulation functionality added&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!05/19/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7367&lt;br /&gt;
|Impedance measurement enabled&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!10/26/2023&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Stimulation latency vastly improved&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!02/20/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7847&lt;br /&gt;
|Version 1.0.230 added. Can change between versions in CMakeLists.txt file&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!08/09/2024&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8313&lt;br /&gt;
|Version 1.0.238 added&lt;br /&gt;
|Stolle&lt;br /&gt;
|-&lt;br /&gt;
!01/17/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R7679&lt;br /&gt;
|Interpolation filter added to interpolate lost samples&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
!06/25/2025&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|R8915&lt;br /&gt;
|All listener states were changed to events&lt;br /&gt;
|Engelhardt&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Cortec API Version History===&lt;br /&gt;
Cortec is continually updating their devices with new API versions. In BCI2000, we currently support versions 1.0.200, 1.0.230, and 1.0.238. Each Brain Interchange Communication unit (BIC) is only compatible with one API version. To find your compatible version, connect the USB drive that comes with your BIC. Look under:&lt;br /&gt;
# &#039;&#039;&#039;Software folder&#039;&#039;&#039;: Each executable has the API version. E.g., &amp;lt;code&amp;gt;Bicapi_setup_1.0.200-bicapi-setup-1.0.200-rev35926.exe&amp;lt;/code&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Manuals foder&#039;&#039;&#039;: &#039;&#039;Appendix1_BIC_Application_Software_Short_Manual.pdf&#039;&#039;. On page 3, in Table 1, the third row contains the compatible version.&lt;br /&gt;
&lt;br /&gt;
Here are some differences between the versions. As the device is always improving, the newest version will have the most features.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! Features !! 1.0.200 !! 1.0.230 !! 1.0.238 !! 1.0.260&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!Matlab API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!C/C++ API&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Stimulation modes&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!ASIC Noise Detection Mode&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Monopolar stimulation (Ch → GND)&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Measure GND impedances&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Self-tests&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
!Low noise recording&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:red&amp;quot;|✘&lt;br /&gt;
|style=&amp;quot;color:green&amp;quot;|✔&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Known Issues===&lt;br /&gt;
* Lost samples - The &amp;lt;code&amp;gt;ImplantLostSamples&amp;lt;/code&amp;gt; state records what samples are lost, and their locations. Lost samples are replaced with the previous valid sample for all channels. In offline analysis, be sure to remove these samples and replace them with interpolates.&lt;br /&gt;
* The Brain Interchange Communication Unit has been seen to work with certain USB inputs, and not with others. If you are experiencing connection issues, try using a different USB port.&lt;br /&gt;
&lt;br /&gt;
==Installation==&lt;br /&gt;
# Install BCI2000&lt;br /&gt;
# Insert the Cortec USB drive that comes with the Brain Interchange (BIC) device. Under &#039;&#039;Software&#039;&#039;, run the &#039;&#039;Bicapi_setup...&#039;&#039; executable&lt;br /&gt;
# Run a batch file with CortecADC as your Signal Source!&lt;br /&gt;
# If you receive an error, and it states your API version is incorrect, you need to change it. Locate the &#039;&#039;CMakeLists.txt&#039;&#039; under &amp;lt;code&amp;gt;BCI2000/src/private/SignalSource/Cortec&amp;lt;/code&amp;gt;. You must change Line 12, where it states &amp;lt;code&amp;gt;set(BICAPI_VERSION 200)&amp;lt;/code&amp;gt;. Change 200 to 230 or 238, depending on your device (see [[#Cortec Version History | details above]]).&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:CortecSourceParameters.jpg|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the CortecADC]]&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. In the current implementation, this parameter cannot be edited, and will default to how many channels are available from the implant. &lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. &lt;br /&gt;
Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated. For example, at 1000 Hz sampling and a SampleBlockSize of 20, the system (e.g., source signal display, signal processing, and stimulus presentation) will be updated 50 times per second.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. This parameter cannot be edited, and will default to the sampling rate available from the implant. &lt;br /&gt;
In case you are experiencing problems by higher sampling rates (e.g., data loss, jerky display, etc.), increase the SampleBlockSize so that you are updating the system less frequently (usually, updating the system 20-30 times per second is sufficient for most applications), and increase Visualize-&amp;gt;VisualizeSourceDecimation. This parameter will decrease the number of samples per second that are actually drawn in the Source display.&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel. &lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel.&lt;br /&gt;
&lt;br /&gt;
===ReferenceCh===&lt;br /&gt;
This list defines what channels will be used as reference. This list is uploaded to the device and set in hardware, effecting the raw bio-signal data that is recorded by BCI2000. If you do not want to effect the raw bio-signal data that is recorded, you can use the [https://www.bci2000.org/mediawiki/index.php/User_Reference:SpatialFilter spatial filter]. If this parameter is set to auto, no reference channels are used. It is strongly recommended to use at least one reference channel.&lt;br /&gt;
&lt;br /&gt;
===AmplificationFactor===&lt;br /&gt;
Amplification factor that is applied to the recorded data on the implant. The choices are 39.5, 45.5, 51.5, 57.5 db.&lt;br /&gt;
&lt;br /&gt;
===UseGround===&lt;br /&gt;
Enable to use the ground electrode while measuring. This setting can be overwritten during stimulation, depending if the ground electrode is being used or not. For example, if you have enabled this parameter but don&#039;t have &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; in your &amp;lt;code&amp;gt;Destination ch&amp;lt;/code&amp;gt; list in the StimulationTriggers parameter, when you are stimulating you will not be using the ground electrode. Once stimulation is done, this parameter&#039;s settings are used again.&lt;br /&gt;
&lt;br /&gt;
===SaveInfoFile===&lt;br /&gt;
Enable to save a text file, named the same as the data file run. It will contain the timestamp, amplification factor used in the run, and reference channels used. If the Impedance is measured, the impedance values will be saved to this file regardless of if this parameter is enabled.&lt;br /&gt;
&lt;br /&gt;
===LogPacketErrors===&lt;br /&gt;
Enable to save the packet loss errors to the System Log. Helpful for debugging, however can get overwhelming if there are a lot of lost samples. The System Log can be programmatically saved by appending &amp;lt;code&amp;gt;--SystemLogFile=SOME_FILE.TXT&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;Startup system localhost&amp;lt;/code&amp;gt; line in your batch file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab of the BCI2000 config window. &lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=300px heights=300px&amp;gt;&lt;br /&gt;
File:CortecADC_stimulation_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationpulses_parm.PNG&lt;br /&gt;
File:CortecADC_stimulationtriggers_parm1.PNG&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===EnableStimulation===&lt;br /&gt;
This parameter enables/disables stimulation. &lt;br /&gt;
&lt;br /&gt;
===StimulationMode===&lt;br /&gt;
The BIC has 3 stimulation modes. Each one has limitations. Here is a brief summary of how to use each one:&lt;br /&gt;
#Volatile Commands: The most flexible mode. The limitation is that the stimulation configuration is uploaded right before starting the stimulation, which increases the latency of the stimulation. This mode is best used in single pulse stimulation or stimulation burst applications. Can cause issues in longer stimulation trains due to the latency introduced by uploading commands repeatedly. &lt;br /&gt;
[[File:VolatileCommand.png|1000px|thumb|center|upright=2.5|Figure 1. Figure demonstrating volatile command functionality]]&lt;br /&gt;
#Persistent Command: There can only be one stimulation configuration (one column in StimulationPulses), which includes burst settings. You cannot change the source and destination channels without uploading a new command. This mode is useful for implementing stimulation trains, otherwise similar but less flexible when compared to volatile commands.&lt;br /&gt;
[[File:PersistantCommand.png|1000px|thumb|center|upright=2.5|Figure 2. Figure demonstrating Persistant Command functionality]]&lt;br /&gt;
&lt;br /&gt;
#Persistent Functions: This function allows you to preload multiple stimulation configurations allowing for the user to define different source and destination channels. The device executes only one of the stim configrations, and without repetition. This is best used for rapidly iterating over subsets of stimulation pulses in single-pulse stimulation settings. &lt;br /&gt;
[[File:PersistantFunction.png|1000px|thumb|center|upright=2.5|Figure 3. Figure demonstrating Persistant Function functionality]]&lt;br /&gt;
There cannot be any train settings (Train frequency and Train repetitions), so the StimulationTriggers must not have those rows. Also, StimulationTriggers must not have more than 16 columns, as that is the highest number of configurations that can be stored on the device.&lt;br /&gt;
&lt;br /&gt;
Persistent Command and Functions modes have a lower latency because the stimulation is pre-uploaded. All modes are available to give you the highest amount of flexiblity with the BIC. [[#Stimulation Latency|See below for more details on latency.]]&lt;br /&gt;
&lt;br /&gt;
===MeasureImpedance===&lt;br /&gt;
When enabled, the impedances of the used electrodes are printed when you set the configuration. All electrodes that are being recorded will conduct the impedance measurement. The impedances are shown to the user and also saved in the data directory.&lt;br /&gt;
&lt;br /&gt;
===StimulationPulses===&lt;br /&gt;
This parameter defines the shape of the charge balanced stimulation pulses, as described in Fig 1. The pulses are defined in one column of this parameter matrix, and it is possible to define an arbitrary number of pulses, each of which are associated with a user defined integer called a &#039;&#039;PulseID&#039;&#039;.  The rows are labeled and there are some limitations to the magnitudes and durations which are elaborated on in the subsequent section. &lt;br /&gt;
[[File:CortecADC_pulse_def.png|600px|thumb|center|upright=2.5|Figure 1. Pulse definition]]&lt;br /&gt;
====PulseID====&lt;br /&gt;
This must be an integer greater than or equal to zero. This ID will be used in the &#039;&#039;StimulationTriggers&#039;&#039; parameter. &lt;br /&gt;
&lt;br /&gt;
====Pulse Amplitude====&lt;br /&gt;
The pulse amplitude defines the amplitude of the main pulse in units of µA. The counter pulse will have a negative amplitude that is one-quarter of the magnitude of the main pulse. &lt;br /&gt;
&lt;br /&gt;
The valid values of this parameter are in the range 0 to 6120 µA. The granularity changes for smaller amplitudes as follows:&lt;br /&gt;
* amplitude &amp;lt;=  3060 µA: step size of 12&lt;br /&gt;
* amplitude &amp;gt;  3060 µA: step size of 24&lt;br /&gt;
This leads to a set of acceptable values that looks like: [0, 12, ..., 3048, 3060, 3084, ... 6096, 6120]&lt;br /&gt;
You can define this parameter not to be one of the acceptable values in this range, but it will be rounded to the nearest valid value, and other parameters will be varied to maintain charge balance. &lt;br /&gt;
&lt;br /&gt;
====Pulse Duration====&lt;br /&gt;
The pulse duration defines the duration of the main pulse in µs. The counter pulse will have a duration that is four times longer than the main pulse duration. Pulse duration values are set in steps of 10 µs. The acceptable range is between 10 and 2550 µs. Again, if the provided value is not a multiple of 10, it will be rounded to the nearest valid value, and other parameters will be modified to maintain charge balance. &lt;br /&gt;
&lt;br /&gt;
====Dead Zone 0====&lt;br /&gt;
Holds the duration of the pause between main and counter pulse in µs. Values can be set in steps of 10 µs. The acceptable range is between 10 and 2550 µs. The same duration dead zone will also occur after the counter pulse.&lt;br /&gt;
&lt;br /&gt;
====Dead Zone 1====&lt;br /&gt;
Holds the duration of the pause after the pulse was delivered. Values can be set in steps of 80 µs. The acceptable range goes from 10 to 20400 µs. Note that the steps are starting from 0 while the minimum value is 10 µs. This leads to a set of acceptable values that looks like: [10, 80, 160, 240, ... , 20400] µs.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
====Trigger====&lt;br /&gt;
This must be a [https://www.bci2000.org/mediawiki/index.php/User_Reference:Expression_Syntax BCI2000 expression]. When this expression evaluates true during the run, the stimulation is applied. &lt;br /&gt;
====PulseID====&lt;br /&gt;
The second row should contain a valid PulseID that is to be used. &lt;br /&gt;
====Source Ch====&lt;br /&gt;
The third row is an embedded list that defines the source electrodes. &lt;br /&gt;
====Destination Ch====&lt;br /&gt;
The fourth row is also an embedded list that defines the destination electrodes. Specify &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; to include the ground electrode as the destination channel.&lt;br /&gt;
====Pulse Repetition====&lt;br /&gt;
The fifth row defines how many times that pulse is repeated. The max is 255. In between each repeated pulse there is a 10 µs delay.&lt;br /&gt;
====Train Frequency (optional)====&lt;br /&gt;
The sixth row defines the frequency of the train. This is implemented by determining the amount of downtime after the pulses are done, in a resolution of microseconds. So if your desired frequency produces a desired wait time with a resolution of less than a microsecond, this will be rounded to the nearest microsecond.&lt;br /&gt;
====Train Repetition (optional)====&lt;br /&gt;
The seventh row defines how many times the entire train is repeated, at the frequency set by the previous row.&lt;br /&gt;
[[File:Cotec Stimulation Train.png|1000px|thumb|center|upright=2.5|Figure 1. Stimulation train definition]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Note&#039;&#039;: If a train is not desired, you can either set Train Frequency and Repetition to 0, or delete those 2 rows.&lt;br /&gt;
&lt;br /&gt;
===Hardware limitations===&lt;br /&gt;
{|style=&amp;quot;text-align: center;&amp;quot;&lt;br /&gt;
! !! Minimum !! Maximum&lt;br /&gt;
|-&lt;br /&gt;
!Pulse Amplitude (µA)&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|0&lt;br /&gt;
|6,120&lt;br /&gt;
|-&lt;br /&gt;
!Pulse Duration (µs)&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|10&lt;br /&gt;
|2,550&lt;br /&gt;
|-&lt;br /&gt;
!Dead Zone 0 (µs)&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|10&lt;br /&gt;
|2,550&lt;br /&gt;
|-&lt;br /&gt;
!Dead Zone 1 (µs)&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|10&lt;br /&gt;
|20,400&lt;br /&gt;
|-&lt;br /&gt;
!Pulse Repetitions&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|1&lt;br /&gt;
|255&lt;br /&gt;
|-&lt;br /&gt;
!Train Repetitions&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|0&lt;br /&gt;
|65,535&lt;br /&gt;
|-&lt;br /&gt;
!Pulse Frequency (Hz)&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;|43.57&lt;br /&gt;
|200&lt;br /&gt;
|-&lt;br /&gt;
!Train Frequency (Hz)&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;| ~0.02&lt;br /&gt;
|Pulse Frequency&lt;br /&gt;
|-&lt;br /&gt;
!Compliance Voltage (V)&lt;br /&gt;
|style=&amp;quot;border-left: solid 1px grey; border-right: solid 1px grey;&amp;quot;| -11&lt;br /&gt;
|5 &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, such as device type, device ID, and the firmware version. &lt;br /&gt;
&lt;br /&gt;
===StateInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information regarding state units and their multiplier. The device provides information such as humidity, temperature, control value, etc., which are recorded in BCI2000 states (see state information on this page for a complete enumeration of states). The device provides these values with floats, but BCI2000 states can only be integers. The multipliers defined in this parameter are used to increase the amount of precision in the state values. To approximately recover the original float values with the units defined in this parameter, divide each state by its corresponding multiplier.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information returned from the Cortec implant. The device provides this data in floating point numbers, however BCI2000 can only record integers to it&#039;s states. To maintain some precision, these floats are multiplied by constants, then recorded to the states as integers. To approximately recover the original data, divide the state by its corresponding constant. Constants are shown in the following table. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:right;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;font-weight:bold;&amp;quot;&lt;br /&gt;
! State&lt;br /&gt;
! style=&amp;quot;text-align:center;&amp;quot; | Constant&lt;br /&gt;
|-&lt;br /&gt;
| ImplantVoltage&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantHumidity&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantControlValue&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|-&lt;br /&gt;
| ImplantPrimaryCoilCurrent&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 1000&lt;br /&gt;
|-&lt;br /&gt;
| ImplantTemperature&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | 100&lt;br /&gt;
|}&lt;br /&gt;
===ImplantLostSample===&lt;br /&gt;
The communication protocol the device uses does not re-send lost data. This state annotates what samples were lost in the bio-signal data. Currently, lost samples are made up by duplicating the previous sample. &lt;br /&gt;
&lt;br /&gt;
===ImplantVoltage===&lt;br /&gt;
16 bit state that changes when new supply voltage value is received from the implant. After dividing the integer state value by the the voltage multiplier defined in the StateInfo parameter, the units are in volts.&lt;br /&gt;
&lt;br /&gt;
===ImplantHumidity===&lt;br /&gt;
16 bit state that changes when new humidity value is received from the implant. Units in %rh. &lt;br /&gt;
&lt;br /&gt;
===ImplantControlValue===&lt;br /&gt;
16 bit state that changes when new current control value is received from the external unit. The power of the implant is controlled by the external unit. The control value provides a measure of how good the coupling between the two coils is and how much more power can be provided if necessary.&lt;br /&gt;
The value is between 0.0 and 100.0 percent, where 0.0 translates to no power and 100.0 translates to maximum power applied.&lt;br /&gt;
&lt;br /&gt;
===ImplantPrimaryCoilCurrent===&lt;br /&gt;
16 bit state that change when new primary coil current value is received from the external unit. The primary coil refers to the coil inside the head piece of the external unit. Units are mA. &lt;br /&gt;
&lt;br /&gt;
===ImplantTemperature===&lt;br /&gt;
16 bit state that changes when new temperature value is received from the implant. Units are degrees Celsius. &lt;br /&gt;
&lt;br /&gt;
===ImplantStimulation===&lt;br /&gt;
Binary state that changes when the device reports that it is stimulating. &lt;br /&gt;
&lt;br /&gt;
===ImplantStimulationBursts===&lt;br /&gt;
Updates when the device reports that stimulation functions have finished. Should increment during a stimulation train.&lt;br /&gt;
&lt;br /&gt;
===ImplantRfQuality===&lt;br /&gt;
8 bit state that reports the antenna quality as reported from the rf-link in dBm. &#039;&#039;&#039;&#039;&#039;To obtain the original value, subtract by 128 (2^8)&#039;&#039;&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
===RequestedStimulation===&lt;br /&gt;
Binary state that records when a stimulation trigger expression evaluates true. State remains true for the duration triggered stimulation. This is useful for determining the latency between when stimulation is requested and when it is actually applied. This is done by computing the difference in time between the rising edges of &#039;&#039;ImplantStimulation&#039;&#039; and &#039;&#039;RequestedStimulation&#039;&#039; states.&lt;br /&gt;
&lt;br /&gt;
==[[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|SCIT]]==&lt;br /&gt;
To help out with creating the BCI2000 parameters, a GUI has been made which should make it easy to translate your stimulation specifications into BCI2000 parameter files. The GUI also visualizes the stimulation from three different perspectives, making it easy to tell if your parameters are really what you want. There is a [[User_Reference:StimulationConfigurationIntegrativeTool_(SCIT)|Stimulation Configuration tool user reference]] which will further tell you how to use this tool.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:CortecGUIimg.png|The Cortec GUI which creates BCI2000 parameters from stimulation specifications. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Stimulation Latency==&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; widths=500px heights=500px&amp;gt;&lt;br /&gt;
File:StimulationModesLatencyCortec.png|Stimulation Latencies for the specified Stimulation Modes. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Tests were conducted for 100 pulses, with an ISI of 10 seconds.&lt;br /&gt;
&lt;br /&gt;
Stimulation latency numbers:&lt;br /&gt;
*Persistent functions: &#039;&#039;&#039;13 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Persistent commands: &#039;&#039;&#039;11 ± 1 ms&#039;&#039;&#039;&lt;br /&gt;
*Volatile commands: &#039;&#039;&#039;60 ± 30 ms&#039;&#039;&#039;. Split into the 2 groups, the lower one is &#039;&#039;&#039;48 ± 3 ms&#039;&#039;&#039; and the higher one is &#039;&#039;&#039;174 ± 3 ms&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
As explained above, volatile commands are uploaded right before stimulation, which leads to the increased latency and jitter.&lt;br /&gt;
==µZeus==&lt;br /&gt;
In order to use the new µZeus headpiece simply change the BICVERSION number on line 12 of the CMakeList.txt located in the project folder to use version 274 of the API. ie.,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;set(BICAPI_VERSION 274)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12255</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12255"/>
		<updated>2025-12-20T00:33:38Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
* Luciano Branco (lrfbranco@gmail com)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
* 11/15/2025 - Added Luciano&#039;s Tool, added new important states, and improved Stimulation matrix configuration&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: 8600&lt;br /&gt;
* Tested under: 9072&lt;br /&gt;
* Known to compile under: 9072&lt;br /&gt;
* Broken since: --&lt;br /&gt;
==Dependencies==&lt;br /&gt;
Other than BCI2000, all you should need is the [https://rippleneuro.com/trellis-eeg-software/ Trellis software that comes with your Ripple device]&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool. Parameters are checked and will throw a warning if they exceed device&#039;s safety limits or capabilities in both BCI2000 and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
====Triggers====&lt;br /&gt;
This must be a [https://www.bci2000.org/mediawiki/index.php/User_Reference:Expression_Syntax BCI2000 expression]. When this expression evaluates true during the run, the stimulation is applied.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==Stimulation How-to==&lt;br /&gt;
We have implemented and are distributing two different methods of stimulation through the Ripple device. One is a native implementation within BCI2000. The more capable method of driving stimulation is through a tool made using Matlab. This tool was created by Luciano Branco at the Mayo Clinic. This tool is distributed with BCI2000 and should be accessible through our SVN under src/contrib/SignalSource/RippleADC/cnel_stim. The tool allows you to create a wide range of stimulation configurations while visualising it and driving the stimulation in tandem with BCI2000 so that all of the relevant information is recorded.&lt;br /&gt;
===Native BCI2000===&lt;br /&gt;
In order to use stimulation through BCI2000, you simply need to go into the configuration window after launching a batch file with the RippleADC as your source. There, all you need to do is go to the Source tab, then scroll down until you see the stimulation section, then click the checkbox to enable stimulation and configure your stimulation parameters. These stimulation parameters will allow you to specify step size, frequency, amplitude, duration, burst length, interburst length, pulse width, interpulse width, and the gap until the next stimulation (if you&#039;re setting things up for multiple blocks of stimulation). The final relevant parameter is the StimulationTriggers parameter which allows you to define a trigger for your different configured stimulation patterns. For example, one could use a state such as stimulusCode to trigger stimulation based on when a stimulus is presented, or one could use some signal as a threshold for stimulation. &lt;br /&gt;
A step by step tutorial with screenshots can be found here:&lt;br /&gt;
[https://scribehow.com/viewer/Macro_Raw__DSjk-3QJRxe7EQVS8cSx4A Stimulation instructions]&lt;br /&gt;
===Matlab GUI tool===&lt;br /&gt;
This tool, developed by Luciano Branco at the Mayo Clinic is a much more advanced tool for driving stimulation which allows you to inspect your stimulation trains visually and also drive stimulation. The parameters for stimulation are identical to those within BCI2000&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationParameters.png|800px|thumb|center|Image of settings possible to configure Ripple cnelStim tool]]&lt;br /&gt;
&lt;br /&gt;
After configuring your various stimulation configurations you can inspect each train of stimulations. &lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
&lt;br /&gt;
Once you are happy with your different waveforms and have confirmed that they are appropriate you can proceed to the Control Panel which allows you to define if you want to do bipolar stimulation, whether you want to drive stimulation from the cathode first, and other extra features. Once you are happy with the configuration and you have BCI2000 running you&#039;re ready to start stimulation. You can either drive the cnelStim tool by simply clicking the &amp;quot;Start Stimulation&amp;quot; button, or you can configure it to drive stimulation using a BCI2000 state which is pulled from BCI2000 using BCI2000Remote. &lt;br /&gt;
[[File:RippleControlPanel.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
&lt;br /&gt;
====Ripple GUI Configuration Files====&lt;br /&gt;
In order to easily configure and save complex stimulation parameters within the Matlab GUI tool, a CSV can be used to save and load desired stimulation parameters. You can find different example files [https://wustl.box.com/s/hl25jzr4ay5chhfmsw3g8ud219jn8m1l here.]&lt;br /&gt;
[[File:RippleCSV.png|800px|thumb|center|Image of an example CSV file for monophasic stimulation]]&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RipplePyADC&amp;diff=12254</id>
		<title>Contributions:RipplePyADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RipplePyADC&amp;diff=12254"/>
		<updated>2025-12-19T19:57:39Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Image:RippleDeviceImage.webp|thumb|Example Ripple set-up|450px]]&lt;br /&gt;
= &#039;&#039;&#039;THIS IS OUT OF DATE, PLEASE USE THIS &#039;&#039;&#039;[[Contributions:RippleADC|C++ IMPLEMENTATION]]&#039;&#039;&#039; = &lt;br /&gt;
==Introduction==&lt;br /&gt;
RipplePyADC is a source module that allows for utilization of the Ripple Grapevine and other Ripple devices within BCI2000 through BCPy2000.&lt;br /&gt;
&lt;br /&gt;
==Video Overview==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Dhruva Mehta (mehta@neurotechcenter.org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 9/22/2023 Initial Creation and Setup&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
*Initial development: &lt;br /&gt;
*Tested under: &lt;br /&gt;
*Known to compile under: &lt;br /&gt;
*Broken since: --&lt;br /&gt;
&lt;br /&gt;
===Known Issues===&lt;br /&gt;
&lt;br /&gt;
Stimulation has not been implemented yet.&lt;br /&gt;
&lt;br /&gt;
There may be some block timing issues only visually due to how data is being acquired in BCPy2000. In practice, the data acquired is valid.&lt;br /&gt;
&lt;br /&gt;
Some data streams may not be available depending on the device and the front-end used.&lt;br /&gt;
&lt;br /&gt;
==Using the RipplePyADC==&lt;br /&gt;
&lt;br /&gt;
To use the Ripple Python ADC, you will need to have a Ripple device that works with Trellis and Ripple&#039;s Python API. You will also need a computer set up with both BCI2000 and BCPy2000, which we will go over later.&lt;br /&gt;
&lt;br /&gt;
===Initial Setup===&lt;br /&gt;
&lt;br /&gt;
For the initial setup of your device, please follow the Ripple user manual for your specific device. &lt;br /&gt;
&lt;br /&gt;
====Trellis====&lt;br /&gt;
&lt;br /&gt;
Trellis is a user interface program that has been included with your device. Please use Trellis to test your connection with the device, such as stimulating and recording, as a means of debugging any connection issues or errors.&lt;br /&gt;
&lt;br /&gt;
====Python API====&lt;br /&gt;
&lt;br /&gt;
Ripple has developed a Python interface to Trellis and the Grapevine Neural Interface Processor (NIP) called Xipppy, which is being used in this source module. Xipppy is provided by Ripple, please contact them to obtain the API. If there is a functionality that is not implemented, please first check the Python API to see if Ripple has it implemented themselves. If it is missing from this source module but implemented in their API, please contact us to update the source module.&lt;br /&gt;
&lt;br /&gt;
==How to set up with BCPy2000==&lt;br /&gt;
&lt;br /&gt;
Now we will set up the research PC. First, follow the BCPy2000 installation guide found &#039;&#039;&#039;[[BCPy2000|here]]&#039;&#039;&#039; to install BCPy2000 and compile the solution on your PC.&lt;br /&gt;
&lt;br /&gt;
===Creating a Batch File===&lt;br /&gt;
&lt;br /&gt;
Creating a batch file with BCPy2000 is very straightforward. If you followed the guide, you will already have a few python batch files in the batch folder of your BCI2000 installation since you copied them over from your BCPy2000 installation. If you don&#039;t already have a batch file related to Ripple Python, you can create one by copying the template batch file, and editing it. All you need to do is change the values of &lt;br /&gt;
 start executable PythonSource           --local --PythonSrcClassFile=BciSource.py --PythonSrcShell=0 --PythonSrcLog=Srclogger.txt&lt;br /&gt;
 &lt;br /&gt;
 start executable PythonSignalProcessing --local --PythonSigClassFile=BciSignalProcessing.py --PythonSigShell=0 --PythonSigLog=Siglogger.txt&lt;br /&gt;
 &lt;br /&gt;
 start executable PythonApplication      --local --PythonAppClassFile=BciApplication.py --PythonAppShell=0 --PythonAppLog=Applogger.txt&lt;br /&gt;
to &lt;br /&gt;
 start executable PythonSource           --local --PythonSrcClassFile=ripple/ripplePC.py --PythonSrcShell=0 --PythonSrcLog=aaaaa.txt&lt;br /&gt;
 &lt;br /&gt;
 start executable DummySignalProcessing  --local &lt;br /&gt;
 &lt;br /&gt;
 start executable DummyApplication       --local &lt;br /&gt;
&lt;br /&gt;
Here, you can also manually change the logger files for use with debugging.&lt;br /&gt;
&lt;br /&gt;
===Installing the Python Module===&lt;br /&gt;
&lt;br /&gt;
To actually be able to use the Ripple&#039;s Python API with BCPy2000, it needs to be installed with your BCPy installation. First download and unzip the whl files provided by Ripple. Depending on your operating system, right-click and copy the path to the whl file. For reference, I used version 0.16.19 on Python 3.8.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; heights=500px&amp;gt;&lt;br /&gt;
File:Ripple_whl_path.png|Copying the path&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, open command prompt and navigate to the folder containing your BCPy2000 installation. Now, run the command&lt;br /&gt;
 python -m pip install &amp;quot;YOUR_PATH_HERE&amp;quot;&lt;br /&gt;
where &amp;quot;YOUR_PATH_HERE&amp;quot; is your path in quotations. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; heights=300px&amp;gt;&lt;br /&gt;
File:Ripple_api_install.png|Installing the module&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After installing, you should be good to test the source module!&lt;br /&gt;
&lt;br /&gt;
===Debugging===&lt;br /&gt;
&lt;br /&gt;
Before debugging with BCPy2000, please use Trellis to make sure a proper connection is established. Once you have done that, there are a few methods to test the functionality of both the source module and the underlying Python API.&lt;br /&gt;
&lt;br /&gt;
First we will test the Python API. The following is a simple script to test connecting to a device in both UDP and TCP:&lt;br /&gt;
&lt;br /&gt;
 #!/usr/bin/env python3&lt;br /&gt;
 # -*- coding: utf-8 -*-&lt;br /&gt;
 &lt;br /&gt;
 import xipppy as xp&lt;br /&gt;
 from time import sleep&lt;br /&gt;
 &lt;br /&gt;
 def connectToProcessor():&lt;br /&gt;
 &lt;br /&gt;
    # Close connection&lt;br /&gt;
    xp._close()&lt;br /&gt;
    sleep(0.001)&lt;br /&gt;
    # Connect to processor (Try UDP then TCP). &lt;br /&gt;
    try:&lt;br /&gt;
        xp._open()&lt;br /&gt;
    except:&lt;br /&gt;
        try:&lt;br /&gt;
            xp._open(use_tcp=True)&lt;br /&gt;
        except:&lt;br /&gt;
            print(&amp;quot;Failed to connect to processor.&amp;quot;)&lt;br /&gt;
        else:&lt;br /&gt;
            print(&amp;quot;Connected over TCP&amp;quot;)&lt;br /&gt;
    else:&lt;br /&gt;
        print(&amp;quot;Connected over UDP&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    sleep(0.001)&lt;br /&gt;
    &lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    connectToProcessor()&lt;br /&gt;
    xp._close()&lt;br /&gt;
&lt;br /&gt;
The following script can be used to test data acquisition:&lt;br /&gt;
&lt;br /&gt;
 import xipppy&lt;br /&gt;
 import numpy as np&lt;br /&gt;
 import time&lt;br /&gt;
 &lt;br /&gt;
 if __name__ == &#039;__main__&#039;:&lt;br /&gt;
    with xipppy.open(use_tcp=true):&lt;br /&gt;
        i = 0&lt;br /&gt;
        data_arrays = []&lt;br /&gt;
        while i &amp;lt; 10:&lt;br /&gt;
            ts = xipppy.time()&lt;br /&gt;
            time.sleep(1)&lt;br /&gt;
            array = xipppy.cont_hires(100, [0], ts)&lt;br /&gt;
            data_arrays.append(array)&lt;br /&gt;
            i += 1&lt;br /&gt;
        print(data_arrays)&lt;br /&gt;
&lt;br /&gt;
Most of the time, the error will be:&lt;br /&gt;
 xipppy.exception.XippPyException: Library already open or failed to initialize&lt;br /&gt;
It is hard to pinpoint exactly what caused the error in this case, and even Ripple&#039;s documentation states that this error lacks any additional information.&lt;br /&gt;
You can also manually edit the python source module and utilize print statements or write to a file within the program. The source module will print out to the designated logger file that was named in the batch file.&lt;br /&gt;
&lt;br /&gt;
==Running the Source Module==&lt;br /&gt;
&lt;br /&gt;
===Initial Parameters===&lt;br /&gt;
Now that you have installed the source module, you can begin testing to make sure that data is being acquired. Before you test the source module, you can make sure that a signal is being passed through by using the Trellis application provided by Ripple. This will eliminate any doubt about whether data is actually being acquired in the first place, since you will be able to see a signal generated in Trellis.&lt;br /&gt;
&lt;br /&gt;
Next, double click on the batch file to start the source module. Here you will be able to configure parameters and even save them as a file to load in for future experiment runs. &lt;br /&gt;
&lt;br /&gt;
First, you can decide the number of source channels. This is going to be the same as the number of electrodes that you would like a signal to be acquired and visualized from. &lt;br /&gt;
&lt;br /&gt;
Next, you can choose the number of samples to be acquired per acquisition block with the sample block size. &lt;br /&gt;
&lt;br /&gt;
Next, you must decide which data acquisition function you would like to choose. The six options are raw, lfp, hifreq, hires, emg, and status. The specifics of these data streams are covered in the Ripple manual. The important thing to note is that the choices for macro and micro are both &amp;quot;raw&amp;quot;. Macro and micro depends on which front-end you are using.&lt;br /&gt;
&lt;br /&gt;
Next, we must check that the sampling rate matches the sampling rate of the data acquisition function you choose. The frequencies are listed in the Parameters section of this wiki. It is important that they match otherwise you will get errors on data acquisition. &lt;br /&gt;
&lt;br /&gt;
The final thing to change would be which specific electrodes to acquire data from, via the specific channel parameter. Here, you set put the electrodes in a 0-indexed list (electrode 1 is 0, electrode 2 is 1, etc.). The length of this list must match the number of source channels you put earlier. Otherwise, this list will be overwritten during preflight.&lt;br /&gt;
&lt;br /&gt;
You can also change other parameters as detailed in the parameter guide.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; heights=500px&amp;gt;&lt;br /&gt;
File:Ripple_Source_Parameters.png|Source Parameters&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Stimulation===&lt;br /&gt;
&lt;br /&gt;
If you would like to use stimulation with your Ripple device, there is a separate parameter tab where you can create stimulation segments, sequences, triggers, and trains. This is still currently under development.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery mode=&amp;quot;packed&amp;quot; heights=500px&amp;gt;&lt;br /&gt;
File:Ripple_Stimulation_Parameters.png|Stimulation Parameters&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Parameters==&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. &lt;br /&gt;
Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated. For example, at 1000 Hz sampling and a SampleBlockSize of 20, the system (e.g., source signal display, signal processing, and stimulus presentation) will be updated 50 times per second.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. &#039;&#039;&#039;It is important that this parameter matches the sampling rate of the data acquisition function that you want to use. Otherwise, the two frequencies will be out of sync and you will eventually get either an error or a flat line in the signal visualizer.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel. &lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel.&lt;br /&gt;
&lt;br /&gt;
===ReferenceCh===&lt;br /&gt;
This list defines what channels will be used as reference. This list is uploaded to the device and set in hardware, effecting the raw bio-signal data that is recorded by BCI2000. If you do not want to effect the raw bio-signal data that is recorded, you can use the [https://www.bci2000.org/mediawiki/index.php/User_Reference:SpatialFilter spatial filter]. If this parameter is set to auto, no reference channels are used.&lt;br /&gt;
&lt;br /&gt;
===DataStream===&lt;br /&gt;
The type of data stream you would like to use for acquisition. There are six types of data streams you can use, each with different frequencies:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-right:auto; margin-left:10px; text-align:center;&amp;quot;&lt;br /&gt;
|+ Data Streams&lt;br /&gt;
|-&lt;br /&gt;
! Stream !! Frequency (kHz)&lt;br /&gt;
|-&lt;br /&gt;
| macro || 15&lt;br /&gt;
|-&lt;br /&gt;
| lfp || 1&lt;br /&gt;
|-&lt;br /&gt;
| hires || 2&lt;br /&gt;
|-&lt;br /&gt;
| hifreq || 15&lt;br /&gt;
|-&lt;br /&gt;
| emg || 15&lt;br /&gt;
|-&lt;br /&gt;
| status || 2&lt;br /&gt;
|-&lt;br /&gt;
| micro || 30&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Before trying to use a specific data stream, test to make sure you can acquire data from Trellis with it. If you don&#039;t see a signal in Trellis, you will not be able to see data in BcPy2000 either.&lt;br /&gt;
&lt;br /&gt;
===SpecificCh===&lt;br /&gt;
Here, you can choose which channels you want to actually acquire data from, just put the number of the channel you would like in a corresponding list section. Channel numbers start with 0. You can choose any number of channels by readjusting the list matrix size. Numbers do not need to be in ascending order, however the channels will appear in order they are put in the list from top to bottom. &#039;&#039;&#039;Make sure that the number of specific channels matches the SourceCh parameter.&#039;&#039;&#039; Otherwise, you will get thrown an error and the electrode list will automatically be changed to match the value of SourchCh.&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:Make-done-RPI.png&amp;diff=12253</id>
		<title>File:Make-done-RPI.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:Make-done-RPI.png&amp;diff=12253"/>
		<updated>2025-12-19T16:44:26Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12249</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12249"/>
		<updated>2025-12-19T16:19:12Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
== Raspberry Pi Performance ==&lt;br /&gt;
These instructions were created using a Raspberry Pi 3 model B running Debian GNU/Linux 13 (trixie). &lt;br /&gt;
While Running the signal generator, DummySignalProcessing, and Stimulus Presentation we observed a power draw of between 2.2 and 4.2 Watts.&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y \&lt;br /&gt;
build-essential \&lt;br /&gt;
cmake \&lt;br /&gt;
qtbase5-dev \&lt;br /&gt;
qt5-qmake \&lt;br /&gt;
qtbase5-dev-tools \&lt;br /&gt;
libdrm-dev \&lt;br /&gt;
libxcb1-dev \&lt;br /&gt;
libxcb-dev \&lt;br /&gt;
libxcb-cursor-dev \&lt;br /&gt;
libx11-dev \&lt;br /&gt;
libxext-dev \&lt;br /&gt;
libxrender-dev \&lt;br /&gt;
libxi-dev \&lt;br /&gt;
libxrandr-dev&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update &amp;amp;&amp;amp; sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Configure BCI2000 for Compilation==&lt;br /&gt;
&lt;br /&gt;
===Run the CMake GUI===&lt;br /&gt;
Double-click &amp;quot;Configure.sh.cmd&amp;quot; in your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-init-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Tell CMake which Qt installation to use===&lt;br /&gt;
Click &amp;quot;AddEntry&amp;quot; in the CMake window (&amp;lt;i&amp;gt;Note that checking off &amp;quot;Advanced&amp;quot; in CMake is optional and does not impact compilation&amp;lt;/i&amp;gt;) and enter the path to a Qt directory. &lt;br /&gt;
&amp;lt;!--If you installed Qt with homebrew, this can be found with&lt;br /&gt;
 brew list qt@6&lt;br /&gt;
The installation directory is only the part of the paths that are&lt;br /&gt;
 .../homebrew/Cellar/qt@6/&amp;lt;version&amp;gt;&lt;br /&gt;
Use everything up to the version and nothing past it.--&amp;gt;&lt;br /&gt;
Use CMAKE_PREFIX_PATH as the name for the new entry. Be aware that the entry&#039;s name is case sensitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-add-cache-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
In the CMake window, click &amp;quot;Configure&amp;quot; and choose a generator that is consistent with your compiler. This tutorial will be using Unix Makefiles.&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Done&amp;quot; to perform the configuration step. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-generators-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
You will see a list of targets scrolling by, and a number of new entries in the variable list at the top of the window, marked in red.&lt;br /&gt;
&lt;br /&gt;
===Choose Build Options===&lt;br /&gt;
Make sure the &amp;quot;Grouped&amp;quot; checkbox is checked, and configure the build by customizing values in the &amp;quot;BUILD&amp;quot; group, &amp;quot;EXTENSIONS&amp;quot; group,  and &amp;quot;USE&amp;quot; group. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Generate Makefiles===&lt;br /&gt;
Then, click &amp;quot;Generate&amp;quot; to create build files. When CMake displays its &amp;quot;Generating done&amp;quot; message, your BCI2000 build directory will now contain a Makefile (or a project file for your compiler of choice), as well as a number of additional CMake-generated files.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-configured-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
==Compile BCI2000==&lt;br /&gt;
===Open Terminal===&lt;br /&gt;
Open a new terminal window and navigate to your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:terminal-bulid-directory-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Build Executables===&lt;br /&gt;
Run:&lt;br /&gt;
 make -j4&lt;br /&gt;
from your BCI2000 build directory. Once this is finished your BCI2000 prog directory will contain a number of executables, one for each module, plus a few helper executables. Not everything works the same or, in some cases, at all on non-windows platforms. See [[Non-Windows Functionality]] for more information.&lt;br /&gt;
&lt;br /&gt;
[[File:Make-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
The build process is now complete. Run &lt;br /&gt;
 make -j4&lt;br /&gt;
again to recompile. Or&lt;br /&gt;
 make &amp;lt;target&amp;gt;&lt;br /&gt;
to recompile only a specific target.&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12247</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12247"/>
		<updated>2025-12-19T16:13:29Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
== Raspberry Pi Performance ==&lt;br /&gt;
While Running the signal generator, DummySignalProcessing, and Stimulus Presentation we observed a power draw of between 2.2 and 4.2 Watts.&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y \ build-essential \ cmake \ qtbase5-dev \ qt5-qmake \ qtbase5-dev-tools \ libdrm-dev \ libxcb1-dev \ libxcb-dev \ libxcb-cursor-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update &amp;amp;&amp;amp; sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Configure BCI2000 for Compilation==&lt;br /&gt;
&lt;br /&gt;
===Run the CMake GUI===&lt;br /&gt;
Double-click &amp;quot;Configure.sh.cmd&amp;quot; in your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-init-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Tell CMake which Qt installation to use===&lt;br /&gt;
Click &amp;quot;AddEntry&amp;quot; in the CMake window (&amp;lt;i&amp;gt;Note that checking off &amp;quot;Advanced&amp;quot; in CMake is optional and does not impact compilation&amp;lt;/i&amp;gt;) and enter the path to a Qt directory. &lt;br /&gt;
&amp;lt;!--If you installed Qt with homebrew, this can be found with&lt;br /&gt;
 brew list qt@6&lt;br /&gt;
The installation directory is only the part of the paths that are&lt;br /&gt;
 .../homebrew/Cellar/qt@6/&amp;lt;version&amp;gt;&lt;br /&gt;
Use everything up to the version and nothing past it.--&amp;gt;&lt;br /&gt;
Use CMAKE_PREFIX_PATH as the name for the new entry. Be aware that the entry&#039;s name is case sensitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-add-cache-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
In the CMake window, click &amp;quot;Configure&amp;quot; and choose a generator that is consistent with your compiler. This tutorial will be using Unix Makefiles.&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Done&amp;quot; to perform the configuration step. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-generators-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
You will see a list of targets scrolling by, and a number of new entries in the variable list at the top of the window, marked in red.&lt;br /&gt;
&lt;br /&gt;
===Choose Build Options===&lt;br /&gt;
Make sure the &amp;quot;Grouped&amp;quot; checkbox is checked, and configure the build by customizing values in the &amp;quot;BUILD&amp;quot; group, &amp;quot;EXTENSIONS&amp;quot; group,  and &amp;quot;USE&amp;quot; group. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Generate Makefiles===&lt;br /&gt;
Then, click &amp;quot;Generate&amp;quot; to create build files. When CMake displays its &amp;quot;Generating done&amp;quot; message, your BCI2000 build directory will now contain a Makefile (or a project file for your compiler of choice), as well as a number of additional CMake-generated files.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-configured-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
==Compile BCI2000==&lt;br /&gt;
===Open Terminal===&lt;br /&gt;
Open a new terminal window and navigate to your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:terminal-bulid-directory-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Build Executables===&lt;br /&gt;
Run:&lt;br /&gt;
 make -j4&lt;br /&gt;
from your BCI2000 build directory. Once this is finished your BCI2000 prog directory will contain a number of executables, one for each module, plus a few helper executables. Not everything works the same or, in some cases, at all on non-windows platforms. See [[Non-Windows Functionality]] for more information.&lt;br /&gt;
&lt;br /&gt;
[[File:Make-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
The build process is now complete. Run &lt;br /&gt;
 make -j4&lt;br /&gt;
again to recompile. Or&lt;br /&gt;
 make &amp;lt;target&amp;gt;&lt;br /&gt;
to recompile only a specific target.&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:Terminal-bulid-directory-RPI.png&amp;diff=12241</id>
		<title>File:Terminal-bulid-directory-RPI.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:Terminal-bulid-directory-RPI.png&amp;diff=12241"/>
		<updated>2025-12-19T15:50:19Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12240</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12240"/>
		<updated>2025-12-19T15:49:53Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y \ build-essential \ cmake \ qtbase5-dev \ qt5-qmake \ qtbase5-dev-tools \ libdrm-dev \ libxcb1-dev \ libxcb-dev \ libxcb-cursor-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Configure BCI2000 for Compilation==&lt;br /&gt;
&lt;br /&gt;
===Run the CMake GUI===&lt;br /&gt;
Double-click &amp;quot;Configure.sh.cmd&amp;quot; in your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-init-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Tell CMake which Qt installation to use===&lt;br /&gt;
Click &amp;quot;AddEntry&amp;quot; in the CMake window (&amp;lt;i&amp;gt;Note that checking off &amp;quot;Advanced&amp;quot; in CMake is optional and does not impact compilation&amp;lt;/i&amp;gt;) and enter the path to a Qt directory. &lt;br /&gt;
&amp;lt;!--If you installed Qt with homebrew, this can be found with&lt;br /&gt;
 brew list qt@6&lt;br /&gt;
The installation directory is only the part of the paths that are&lt;br /&gt;
 .../homebrew/Cellar/qt@6/&amp;lt;version&amp;gt;&lt;br /&gt;
Use everything up to the version and nothing past it.--&amp;gt;&lt;br /&gt;
Use CMAKE_PREFIX_PATH as the name for the new entry. Be aware that the entry&#039;s name is case sensitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-add-cache-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
In the CMake window, click &amp;quot;Configure&amp;quot; and choose a generator that is consistent with your compiler. This tutorial will be using Unix Makefiles.&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Done&amp;quot; to perform the configuration step. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-generators-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
You will see a list of targets scrolling by, and a number of new entries in the variable list at the top of the window, marked in red.&lt;br /&gt;
&lt;br /&gt;
===Choose Build Options===&lt;br /&gt;
Make sure the &amp;quot;Grouped&amp;quot; checkbox is checked, and configure the build by customizing values in the &amp;quot;BUILD&amp;quot; group, &amp;quot;EXTENSIONS&amp;quot; group,  and &amp;quot;USE&amp;quot; group. &lt;br /&gt;
[[File:Cmake-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Generate Makefiles===&lt;br /&gt;
Then, click &amp;quot;Generate&amp;quot; to create build files. When CMake displays its &amp;quot;Generating done&amp;quot; message, your BCI2000 build directory will now contain a Makefile (or a project file for your compiler of chioce), as well as a number of additional CMake-generated files.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-configured-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
==Compile BCI2000==&lt;br /&gt;
===Open Terminal===&lt;br /&gt;
Open a new terminal window and navigate to your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:terminal-bulid-directory-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Build Executables===&lt;br /&gt;
Run:&lt;br /&gt;
 make -j&lt;br /&gt;
from your BCI2000 build directory. Once this is finished your BCI2000 prog directory will contain a number of executables, one for each module, plus a few helper executables. Not everything works the same or, in some cases, at all on non-windows platforms. See [[Non-Windows Functionality]] for more information.&lt;br /&gt;
&lt;br /&gt;
[[File:Make-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
The build process is now complete. Run &lt;br /&gt;
 make -j&lt;br /&gt;
again to recompile. Or&lt;br /&gt;
 make &amp;lt;target&amp;gt;&lt;br /&gt;
to recompile only a specific target.&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-done-RPI.png&amp;diff=12239</id>
		<title>File:Cmake-done-RPI.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-done-RPI.png&amp;diff=12239"/>
		<updated>2025-12-19T15:48:50Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-configured-RPI.png&amp;diff=12238</id>
		<title>File:Cmake-configured-RPI.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-configured-RPI.png&amp;diff=12238"/>
		<updated>2025-12-19T15:48:13Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-generators-RPI.png&amp;diff=12237</id>
		<title>File:Cmake-generators-RPI.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-generators-RPI.png&amp;diff=12237"/>
		<updated>2025-12-19T15:47:46Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-add-cache-RPI.png&amp;diff=12236</id>
		<title>File:Cmake-add-cache-RPI.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-add-cache-RPI.png&amp;diff=12236"/>
		<updated>2025-12-19T15:47:20Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-init-RPI.png&amp;diff=12235</id>
		<title>File:Cmake-init-RPI.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:Cmake-init-RPI.png&amp;diff=12235"/>
		<updated>2025-12-19T15:46:46Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12234</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12234"/>
		<updated>2025-12-19T15:46:12Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y \ build-essential \ cmake \ qtbase5-dev \ qt5-qmake \ qtbase5-dev-tools \ libdrm-dev \ libxcb1-dev \ libxcb-dev \ libxcb-cursor-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Configure BCI2000 for Compilation==&lt;br /&gt;
&lt;br /&gt;
===Run the CMake GUI===&lt;br /&gt;
Double-click &amp;quot;Configure.sh.cmd&amp;quot; in your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-init-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Tell CMake which Qt installation to use===&lt;br /&gt;
Click &amp;quot;AddEntry&amp;quot; in the CMake window (&amp;lt;i&amp;gt;Note that checking off &amp;quot;Advanced&amp;quot; in CMake is optional and does not impact compilation&amp;lt;/i&amp;gt;) and enter the path to a Qt directory. &lt;br /&gt;
&amp;lt;!--If you installed Qt with homebrew, this can be found with&lt;br /&gt;
 brew list qt@6&lt;br /&gt;
The installation directory is only the part of the paths that are&lt;br /&gt;
 .../homebrew/Cellar/qt@6/&amp;lt;version&amp;gt;&lt;br /&gt;
Use everything up to the version and nothing past it.--&amp;gt;&lt;br /&gt;
Use CMAKE_PREFIX_PATH as the name for the new entry. Be aware that the entry&#039;s name is case sensitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-add-cache-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
In the CMake window, click &amp;quot;Configure&amp;quot; and choose a generator that is consistent with your compiler. This tutorial will be using Unix Makefiles.&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Done&amp;quot; to perform the configuration step. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-generators-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
You will see a list of targets scrolling by, and a number of new entries in the variable list at the top of the window, marked in red.&lt;br /&gt;
&lt;br /&gt;
===Choose Build Options===&lt;br /&gt;
Make sure the &amp;quot;Grouped&amp;quot; checkbox is checked, and configure the build by customizing values in the &amp;quot;BUILD&amp;quot; group, &amp;quot;EXTENSIONS&amp;quot; group,  and &amp;quot;USE&amp;quot; group. &lt;br /&gt;
[[File:Cmake-configured-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Generate Makefiles===&lt;br /&gt;
Then, click &amp;quot;Generate&amp;quot; to create build files. When CMake displays its &amp;quot;Generating done&amp;quot; message, your BCI2000 build directory will now contain a Makefile (or a project file for your compiler of chioce), as well as a number of additional CMake-generated files.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
==Compile BCI2000==&lt;br /&gt;
===Open Terminal===&lt;br /&gt;
Open a new terminal window and navigate to your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:terminal-bulid-directory-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Build Executables===&lt;br /&gt;
Run:&lt;br /&gt;
 make -j&lt;br /&gt;
from your BCI2000 build directory. Once this is finished your BCI2000 prog directory will contain a number of executables, one for each module, plus a few helper executables. Not everything works the same or, in some cases, at all on non-windows platforms. See [[Non-Windows Functionality]] for more information.&lt;br /&gt;
&lt;br /&gt;
[[File:Make-done-RPI.png|700px]]&lt;br /&gt;
&lt;br /&gt;
The build process is now complete. Run &lt;br /&gt;
 make -j&lt;br /&gt;
again to recompile. Or&lt;br /&gt;
 make &amp;lt;target&amp;gt;&lt;br /&gt;
to recompile only a specific target.&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12232</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12232"/>
		<updated>2025-12-18T21:59:25Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y \ build-essential \ cmake \ qtbase5-dev \ qt5-qmake \ qtbase5-dev-tools \ libdrm-dev \ libxcb1-dev \ libxcb-dev \ libxcb-cursor-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop (local monitor) ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Configure BCI2000 for Compilation==&lt;br /&gt;
&lt;br /&gt;
===Run the CMake GUI===&lt;br /&gt;
Double-click &amp;quot;Configure.sh.cmd&amp;quot; in your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-init-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Tell CMake which Qt installation to use===&lt;br /&gt;
Click &amp;quot;AddEntry&amp;quot; in the CMake window (&amp;lt;i&amp;gt;Note that checking off &amp;quot;Advanced&amp;quot; in CMake is optional and does not impact compilation&amp;lt;/i&amp;gt;) and enter the path to a Qt directory. &lt;br /&gt;
&amp;lt;!--If you installed Qt with homebrew, this can be found with&lt;br /&gt;
 brew list qt@6&lt;br /&gt;
The installation directory is only the part of the paths that are&lt;br /&gt;
 .../homebrew/Cellar/qt@6/&amp;lt;version&amp;gt;&lt;br /&gt;
Use everything up to the version and nothing past it.--&amp;gt;&lt;br /&gt;
Use CMAKE_PREFIX_PATH as the name for the new entry. Be aware that the entry&#039;s name is case sensitive.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-add-cache-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
In the CMake window, click &amp;quot;Configure&amp;quot; and choose a generator that is consistent with your compiler. This tutorial will be using Unix Makefiles.&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Done&amp;quot; to perform the configuration step. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-generators-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
You will see a list of targets scrolling by, and a number of new entries in the variable list at the top of the window, marked in red.&lt;br /&gt;
&lt;br /&gt;
===Choose Build Options===&lt;br /&gt;
Make sure the &amp;quot;Grouped&amp;quot; checkbox is checked, and configure the build by customizing values in the &amp;quot;BUILD&amp;quot; group, &amp;quot;EXTENSIONS&amp;quot; group,  and &amp;quot;USE&amp;quot; group. &lt;br /&gt;
[[File:Cmake-configured-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Generate Makefiles===&lt;br /&gt;
Then, click &amp;quot;Generate&amp;quot; to create build files. When CMake displays its &amp;quot;Generating done&amp;quot; message, your BCI2000 build directory will now contain a Makefile (or a project file for your compiler of chioce), as well as a number of additional CMake-generated files.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-done-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
==Compile BCI2000==&lt;br /&gt;
===Open Terminal===&lt;br /&gt;
Open a new terminal window and navigate to your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:terminal-bulid-directory-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Build Executables===&lt;br /&gt;
Run:&lt;br /&gt;
 make -j&lt;br /&gt;
from your BCI2000 build directory. Once this is finished your BCI2000 prog directory will contain a number of executables, one for each module, plus a few helper executables. Not everything works the same or, in some cases, at all on non-windows platforms. See [[Non-Windows Functionality]] for more information.&lt;br /&gt;
&lt;br /&gt;
[[File:Make-done-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
The build process is now complete. Run &lt;br /&gt;
 make -j&lt;br /&gt;
again to recompile. Or&lt;br /&gt;
 make &amp;lt;target&amp;gt;&lt;br /&gt;
to recompile only a specific target.&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12231</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12231"/>
		<updated>2025-12-18T21:58:08Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y \ build-essential \ cmake \ qtbase5-dev \ qt5-qmake \ qtbase5-dev-tools \ libdrm-dev \ libxcb1-dev \ libxcb-dev \ libxcb-cursor-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop (local monitor) ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Configure BCI2000 for Compilation==&lt;br /&gt;
&lt;br /&gt;
===Run the CMake GUI===&lt;br /&gt;
Double-click &amp;quot;Configure.sh.cmd&amp;quot; in your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-init-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Tell CMake which Qt installation to use===&lt;br /&gt;
Click &amp;quot;AddEntry&amp;quot; in the CMake window (&amp;lt;i&amp;gt;Note that checking off &amp;quot;Advanced&amp;quot; in CMake is optional and does not impact compilation&amp;lt;/i&amp;gt;) and enter the path to a Qt directory. &lt;br /&gt;
&amp;lt;!--If you installed Qt with homebrew, this can be found with&lt;br /&gt;
 brew list qt@6&lt;br /&gt;
The installation directory is only the part of the paths that are&lt;br /&gt;
 .../homebrew/Cellar/qt@6/&amp;lt;version&amp;gt;&lt;br /&gt;
Use everything up to the version and nothing past it.--&amp;gt;&lt;br /&gt;
If you installed Qt using the Qt online installer, the path will look like /Users/foo/Qt/6.9.0/macos.&lt;br /&gt;
Use CMAKE_PREFIX_PATH as the name for the new entry. Be aware that the entry&#039;s name is case sensitive.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Also, currently, on non-windows platforms, Qt 6 is the only version that is supported.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-add-cache-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Configuration===&lt;br /&gt;
In the CMake window, click &amp;quot;Configure&amp;quot; and choose a generator that is consistent with your compiler. This tutorial will be using Unix Makefiles.&lt;br /&gt;
&lt;br /&gt;
Then click &amp;quot;Done&amp;quot; to perform the configuration step. &lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-generators-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
You will see a list of targets scrolling by, and a number of new entries in the variable list at the top of the window, marked in red.&lt;br /&gt;
&lt;br /&gt;
===Choose Build Options===&lt;br /&gt;
Make sure the &amp;quot;Grouped&amp;quot; checkbox is checked, and configure the build by customizing values in the &amp;quot;BUILD&amp;quot; group, &amp;quot;EXTENSIONS&amp;quot; group,  and &amp;quot;USE&amp;quot; group. &lt;br /&gt;
[[File:Cmake-configured-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Generate Makefiles===&lt;br /&gt;
Then, click &amp;quot;Generate&amp;quot; to create build files. When CMake displays its &amp;quot;Generating done&amp;quot; message, your BCI2000 build directory will now contain a Makefile (or a project file for your compiler of chioce), as well as a number of additional CMake-generated files.&lt;br /&gt;
&lt;br /&gt;
[[File:Cmake-done-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
==Compile BCI2000==&lt;br /&gt;
===Open Terminal===&lt;br /&gt;
Open a new terminal window and navigate to your BCI2000 build directory.&lt;br /&gt;
&lt;br /&gt;
[[File:terminal-bulid-directory-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
===Build Executables===&lt;br /&gt;
Run:&lt;br /&gt;
 make -j&lt;br /&gt;
from your BCI2000 build directory. Once this is finished your BCI2000 prog directory will contain a number of executables, one for each module, plus a few helper executables. Not everything works the same or, in some cases, at all on non-windows platforms. See [[Non-Windows Functionality]] for more information.&lt;br /&gt;
&lt;br /&gt;
[[File:Make-done-non-windows.png|700px]]&lt;br /&gt;
&lt;br /&gt;
The build process is now complete. Run &lt;br /&gt;
 make -j&lt;br /&gt;
again to recompile. Or&lt;br /&gt;
 make &amp;lt;target&amp;gt;&lt;br /&gt;
to recompile only a specific target.&lt;br /&gt;
&lt;br /&gt;
[[Category:Howto]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12230</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12230"/>
		<updated>2025-12-18T20:52:57Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y \ build-essential \ cmake \ qtbase5-dev \ qt5-qmake \ qtbase5-dev-tools \ libdrm-dev \ libxcb1-dev \ libxcb-dev \ libxcb-cursor-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop (local monitor) ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12229</id>
		<title>RaspberryPi</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=RaspberryPi&amp;diff=12229"/>
		<updated>2025-12-18T20:51:10Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: Created page with &amp;quot;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =  This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &amp;#039;&amp;#039;OperatorQt&amp;#039;&amp;#039;, &amp;#039;&amp;#039;StimulusPresentation&amp;#039;&amp;#039;, &amp;#039;&amp;#039;BCI2000Viewer&amp;#039;&amp;#039;).  == Dependencies observed during build troubleshooting ==  During compilation, missing headers/libraries were resolved by installing the following packages:  &amp;#039;&amp;#039;&amp;#039;libdrm-dev&amp;#039;&amp;#039;&amp;#039; — Direct Rendering Manager development files (graphic...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Raspberry Pi (Linux) Build Dependencies (BCI2000 GUI build) =&lt;br /&gt;
&lt;br /&gt;
This section documents system packages needed to compile BCI2000 on a Raspberry Pi with GUI components enabled (e.g., &#039;&#039;OperatorQt&#039;&#039;, &#039;&#039;StimulusPresentation&#039;&#039;, &#039;&#039;BCI2000Viewer&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
== Dependencies observed during build troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
During compilation, missing headers/libraries were resolved by installing the following packages:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libdrm-dev&#039;&#039;&#039; — Direct Rendering Manager development files (graphics stack)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-dev&#039;&#039;&#039; / &#039;&#039;&#039;libxcb1-dev&#039;&#039;&#039; — XCB (X11) client library development files&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;libxcb-cursor-dev&#039;&#039;&#039; — XCB cursor support (required by Qt/X11)&lt;br /&gt;
&lt;br /&gt;
These are consistent with building Qt-based GUI applications on Linux/ARM.&lt;br /&gt;
&lt;br /&gt;
== Recommended minimal install command (GUI build) ==&lt;br /&gt;
&lt;br /&gt;
The following is a practical minimal set for a Raspberry Pi OS / Debian-like system when building BCI2000 with Qt GUI components:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y \ build-essential \ cmake \ qtbase5-dev \ qt5-qmake \ qtbase5-dev-tools \ libdrm-dev \ libxcb1-dev \ libxcb-dev \ libxcb-cursor-dev \ libx11-dev \ libxext-dev \ libxrender-dev \ libxi-dev \ libxrandr-dev &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
Qt on Linux typically depends on X11/XCB libraries, so missing XCB/DRM packages commonly block Qt GUI builds.&lt;br /&gt;
&lt;br /&gt;
If you are doing a headless build (no GUI), you may be able to omit Qt and X11/XCB packages.&lt;br /&gt;
&lt;br /&gt;
== Verify GUI dependency availability ==&lt;br /&gt;
&lt;br /&gt;
To confirm the GUI-related packages are installed:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; dpkg -l | egrep &amp;quot;libdrm-dev|libxcb|qtbase5-dev|cmake&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Running the CMake GUI on Raspberry Pi (cmake-gui) =&lt;br /&gt;
&lt;br /&gt;
The CMake GUI executable is &#039;&#039;&#039;cmake-gui&#039;&#039;&#039;, provided by Debian’s &#039;&#039;&#039;cmake-qt-gui&#039;&#039;&#039; package. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 1) Install the CMake GUI package ==&lt;br /&gt;
&lt;br /&gt;
On Raspberry Pi OS / Debian Bookworm-like systems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; sudo apt update sudo apt install -y cmake-qt-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This installs the &#039;&#039;&#039;cmake-gui&#039;&#039;&#039; executable. &lt;br /&gt;
Debian Packages&lt;br /&gt;
+1&lt;br /&gt;
&lt;br /&gt;
== 2) Run cmake-gui on the Pi desktop (local monitor) ==&lt;br /&gt;
&lt;br /&gt;
If your Pi is running a desktop environment and you are logged in locally:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt; cmake-gui &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If launched from a terminal within the Pi desktop, it should open normally.&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:RippleCSV.png&amp;diff=12223</id>
		<title>File:RippleCSV.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:RippleCSV.png&amp;diff=12223"/>
		<updated>2025-12-09T15:44:24Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12222</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12222"/>
		<updated>2025-12-09T15:42:21Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
* 11/15/2025 - Added Luciano&#039;s Tool, added new important states, and improved Stimulation matrix configuration&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
==Dependencies==&lt;br /&gt;
Other than BCI2000, all you should need is the [https://rippleneuro.com/trellis-eeg-software/ Trellis software that comes with your Ripple device]&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool. Parameters are checked and will throw a warning if they exceed device&#039;s safety limits or capabilities in both BCI2000 and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
====Triggers====&lt;br /&gt;
This must be a [https://www.bci2000.org/mediawiki/index.php/User_Reference:Expression_Syntax BCI2000 expression]. When this expression evaluates true during the run, the stimulation is applied.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==Stimulation How-to==&lt;br /&gt;
We have implemented and are distributing two different methods of stimulation through the Ripple device. One is a native implementation within BCI2000. The more capable method of driving stimulation is through a tool made using Matlab. This tool was created by Luciano Branco at the Mayo Clinic. This tool is distributed with BCI2000 and should be accessible through our SVN under src/contrib/SignalSource/RippleADC/cnel_stim. The tool allows you to create a wide range of stimulation configurations while visualising it and driving the stimulation in tandem with BCI2000 so that all of the relevant information is recorded.&lt;br /&gt;
===Native BCI2000===&lt;br /&gt;
In order to use stimulation through BCI2000, you simply need to go into the configuration window after launching a batch file with the RippleADC as your source. There, all you need to do is go to the Source tab, then scroll down until you see the stimulation section, then click the checkbox to enable stimulation and configure your stimulation parameters. These stimulation parameters will allow you to specify step size, frequency, amplitude, duration, burst length, interburst length, pulse width, interpulse width, and the gap until the next stimulation (if you&#039;re setting things up for multiple blocks of stimulation). The final relevant parameter is the StimulationTriggers parameter which allows you to define a trigger for your different configured stimulation patterns. For example, one could use a state such as stimulusCode to trigger stimulation based on when a stimulus is presented, or one could use some signal as a threshold for stimulation. &lt;br /&gt;
A step by step tutorial with screenshots can be found here:&lt;br /&gt;
[https://scribehow.com/viewer/Macro_Raw__DSjk-3QJRxe7EQVS8cSx4A Stimulation instructions]&lt;br /&gt;
===Matlab GUI tool===&lt;br /&gt;
This tool, developed by Luciano Branco at the Mayo Clinic is a much more advanced tool for driving stimulation which allows you to inspect your stimulation trains visually and also drive stimulation. The parameters for stimulation are identical to those within BCI2000&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationParameters.png|800px|thumb|center|Image of settings possible to configure Ripple cnelStim tool]]&lt;br /&gt;
&lt;br /&gt;
After configuring your various stimulation configurations you can inspect each train of stimulations. &lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
&lt;br /&gt;
Once you are happy with your different waveforms and have confirmed that they are appropriate you can proceed to the Control Panel which allows you to define if you want to do bipolar stimulation, whether you want to drive stimulation from the cathode first, and other extra features. Once you are happy with the configuration and you have BCI2000 running you&#039;re ready to start stimulation. You can either drive the cnelStim tool by simply clicking the &amp;quot;Start Stimulation&amp;quot; button, or you can configure it to drive stimulation using a BCI2000 state which is pulled from BCI2000 using BCI2000Remote. &lt;br /&gt;
[[File:RippleControlPanel.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
&lt;br /&gt;
====Ripple GUI Configuration Files====&lt;br /&gt;
In order to easily configure and save complex stimulation parameters within the Matlab GUI tool, a CSV can be used to save and load desired stimulation parameters. You can find different example files [https://wustl.box.com/s/hl25jzr4ay5chhfmsw3g8ud219jn8m1l here.]&lt;br /&gt;
[[File:RippleCSV.png|800px|thumb|center|Image of an example CSV file for monophasic stimulation]]&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=File:RippleControlPanel.png&amp;diff=12221</id>
		<title>File:RippleControlPanel.png</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=File:RippleControlPanel.png&amp;diff=12221"/>
		<updated>2025-12-05T20:22:00Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12220</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12220"/>
		<updated>2025-12-05T20:21:48Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Native BCI2000 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
* 11/15/2025 - Added Luciano&#039;s Tool, added new important states, and improved Stimulation matrix configuration&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool. Parameters are checked and will throw a warning if they exceed device&#039;s safety limits or capabilities in both BCI2000 and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==Stimulation How-to==&lt;br /&gt;
We have implemented and are distributing two different methods of stimulation through the Ripple device. One is a native implementation within BCI2000. The more capable method of driving stimulation is through a tool made using Matlab. This tool was created by Luciano Branco at the Mayo Clinic. This tool is distributed with BCI2000 and should be accessible through our SVN under src/contrib/SignalSource/RippleADC/cnel_stim. The tool allows you to create a wide range of stimulation configurations while visualising it and driving the stimulation in tandem with BCI2000 so that all of the relevant information is recorded.&lt;br /&gt;
===Native BCI2000===&lt;br /&gt;
In order to use stimulation through BCI2000, you simply need to go into the configuration window after launching a batch file with the RippleADC as your source. There, all you need to do is go to the Source tab, then scroll down until you see the stimulation section, then click the checkbox to enable stimulation and configure your stimulation parameters. These stimulation parameters will allow you to specify step size, frequency, amplitude, duration, burst length, interburst length, pulse width, interpulse width, and the gap until the next stimulation (if you&#039;re setting things up for multiple blocks of stimulation). The final relevant parameter is the StimulationTriggers parameter which allows you to define a trigger for your different configured stimulation patterns. For example, one could use a state such as stimulusCode to trigger stimulation based on when a stimulus is presented, or one could use some signal as a threshold for stimulation. &lt;br /&gt;
A step by step tutorial with screenshots can be found here:&lt;br /&gt;
[https://scribehow.com/viewer/Macro_Raw__DSjk-3QJRxe7EQVS8cSx4A Stimulation instructions]&lt;br /&gt;
===Matlab GUI tool===&lt;br /&gt;
This tool, developed by Luciano Branco at the Mayo Clinic is a much more advanced tool for driving stimulation which allows you to inspect your stimulation trains visually and also drive stimulation. The parameters for stimulation are identical to those within BCI2000&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationParameters.png|800px|thumb|center|Image of settings possible to configure Ripple cnelStim tool]]&lt;br /&gt;
&lt;br /&gt;
After configuring your various stimulation configurations you can inspect each train of stimulations. &lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
&lt;br /&gt;
Once you are happy with your different waveforms and have confirmed that they are appropriate you can proceed to the Control Panel which allows you to define if you want to do bipolar stimulation, whether you want to drive stimulation from the cathode first, and other extra features. Once you are happy with the configuration and you have BCI2000 running you&#039;re ready to start stimulation. You can either drive the cnelStim tool by simply clicking the &amp;quot;Start Stimulation&amp;quot; button, or you can configure it to drive stimulation using a BCI2000 state which is pulled from BCI2000 using BCI2000Remote. &lt;br /&gt;
[[File:RippleControlPanel.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12219</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12219"/>
		<updated>2025-12-05T20:20:31Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
* 11/15/2025 - Added Luciano&#039;s Tool, added new important states, and improved Stimulation matrix configuration&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool. Parameters are checked and will throw a warning if they exceed device&#039;s safety limits or capabilities in both BCI2000 and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==Stimulation How-to==&lt;br /&gt;
We have implemented and are distributing two different methods of stimulation through the Ripple device. One is a native implementation within BCI2000. The more capable method of driving stimulation is through a tool made using Matlab. This tool was created by Luciano Branco at the Mayo Clinic. This tool is distributed with BCI2000 and should be accessible through our SVN under src/contrib/SignalSource/RippleADC/cnel_stim. The tool allows you to create a wide range of stimulation configurations while visualising it and driving the stimulation in tandem with BCI2000 so that all of the relevant information is recorded.&lt;br /&gt;
===Native BCI2000===&lt;br /&gt;
In order to use stimulation through BCI2000, you simply need to go into the configuration window after launching a batch file with the RippleADC as your source. There, all you need to do is go to the Source tab, then scroll down until you see the stimulation section, then click the checkbox to enable stimulation and configure your stimulation parameters. These stimulation parameters will allow you to specify step size, frequency, amplitude, duration, burst length, interburst length, pulse width, interpulse width, and the gap until the next stimulation (if you&#039;re setting things up for multiple blocks of stimulation). The final relevant parameter is the StimulationTriggers parameter which allows you to define a trigger for your different configured stimulation patterns. For example, one could use a state such as stimulusCode to trigger stimulation based on when a stimulus is presented, or one could use some signal as a threshold for stimulation. &lt;br /&gt;
A step by step tutorial with screenshots can be found here:&lt;br /&gt;
[https://scribehow.com/viewer/Macro_Raw__DSjk-3QJRxe7EQVS8cSx4A Stimulation instructions]&lt;br /&gt;
===Matlab GUI tool==-&lt;br /&gt;
This tool, developed by Luciano Branco at the Mayo Clinic is a much more advanced tool for driving stimulation which allows you to inspect your stimulation trains visually and also drive stimulation. The parameters for stimulation are identical to those within BCI2000&lt;br /&gt;
&lt;br /&gt;
[[File:RippleGUISettings.png|800px|thumb|center|Image of settings possible to configure Ripple cnelStim tool]]&lt;br /&gt;
&lt;br /&gt;
After configuring your various stimulation configurations you can inspect each train of stimulations. &lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
&lt;br /&gt;
Once you are happy with your different waveforms and have confirmed that they are appropriate you can proceed to the Control Panel which allows you to define if you want to do bipolar stimulation, whether you want to drive stimulation from the cathode first, and other extra features. Once you are happy with the configuration and you have BCI2000 running you&#039;re ready to start stimulation. You can either drive the cnelStim tool by simply clicking the &amp;quot;Start Stimulation&amp;quot; button, or you can configure it to drive stimulation using a BCI2000 state which is pulled from BCI2000 using BCI2000Remote. &lt;br /&gt;
[[File:RippleControlPanel.png|800px|thumb|center|Image of example monophasic waveform]]&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12212</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12212"/>
		<updated>2025-11-18T03:35:08Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Version History */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
* 11/15/2025 - Added Luciano&#039;s Tool, added new important states, and improved Stimulation matrix configuration&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool. Parameters are checked and will throw a warning if they exceed device&#039;s safety limits or capabilities in both BCI2000 and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12211</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12211"/>
		<updated>2025-11-15T06:34:39Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Stimulation Parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool. Parameters are checked and will throw a warning if they exceed device&#039;s safety limits or capabilities in both BCI2000 and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12210</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12210"/>
		<updated>2025-11-15T06:33:37Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* StimEnable */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12209</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12209"/>
		<updated>2025-11-15T06:33:31Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Stimulation Parameters */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and in both the BCI2000 config window and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Step Size===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the amplitude resolution of the stimulator in µA.&lt;br /&gt;
It indicates the granularity with which the stimulation amplitude may be adjusted. The allowed values depend on the hardware and are typically fixed by the front-end.&lt;br /&gt;
&lt;br /&gt;
===Frequency===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the frequency of stimulation pulses in Hz.&lt;br /&gt;
It specifies how many biphasic pulses occur per second during stimulation. Controls the pulse rate within a stimulation train. Higher frequencies produce temporally denser stimulation.&lt;br /&gt;
Unit: Hz&lt;br /&gt;
&lt;br /&gt;
===Amplitude===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the stimulation amplitude in mA.&lt;br /&gt;
It sets the magnitude of the delivered current for each pulse in the stimulation train. Primary determinant of stimulation intensity.&lt;br /&gt;
Unit: mA&lt;br /&gt;
===Duration===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the total duration of the stimulation train in seconds.&lt;br /&gt;
It specifies how long stimulation continues once triggered.&lt;br /&gt;
Unit: s&lt;br /&gt;
&lt;br /&gt;
===Burst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the length of each stimulation burst in seconds.&lt;br /&gt;
If burst-mode stimulation is used, pulses are grouped into bursts separated by silent periods.&lt;br /&gt;
&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Controls how long each burst remains active before an interburst pause occurs.&lt;br /&gt;
&lt;br /&gt;
===Interburst Length===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the silent interval between bursts in milliseconds. Sets the recovery or idle period between active bursts; used to generate patterned or duty-cycled stimulation.&lt;br /&gt;
&lt;br /&gt;
Unit: ms&lt;br /&gt;
&lt;br /&gt;
===Pulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the width of each stimulation phase in microseconds (µs).&lt;br /&gt;
It corresponds to the duration of the main pulse phase. Affects charge delivery per pulse.&lt;br /&gt;
Unit: µs&lt;br /&gt;
&lt;br /&gt;
===Interpulse Width===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the interval of time between pulses in microseconds. Controls how tightly pulses are packed in time; together with Pulse Width and Frequency, shapes the temporal profile of stimulation.&lt;br /&gt;
Unit: µs&lt;br /&gt;
===Gap Until Next===&lt;br /&gt;
&lt;br /&gt;
This parameter defines the delay between this stimulation block and the next block in seconds.&lt;br /&gt;
Unit: s&lt;br /&gt;
Significance: Used in multi-step or sequential stimulation programs to introduce timing gaps before the next configured stimulation event.&lt;br /&gt;
&lt;br /&gt;
===StimulationTriggers===&lt;br /&gt;
This parameter defines when stimulation is applied, what pulse is used, how many pulses are applied, and the source and destination locations of the stimulation. These parameters are defined in the rows of this matrix with labels&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
	<entry>
		<id>https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12208</id>
		<title>Contributions:RippleADC</title>
		<link rel="alternate" type="text/html" href="https://www.bci2000.org/mediawiki/index.php?title=Contributions:RippleADC&amp;diff=12208"/>
		<updated>2025-11-15T06:17:35Z</updated>

		<summary type="html">&lt;p&gt;Nluczak: /* Supported Front Ends */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:RippleDeviceImage.webp|400px|thumb|right|Ripple Neural Interface Processor]]&lt;br /&gt;
&lt;br /&gt;
RippleADC is a source module that allows for neural recording and stimulation using Ripple&#039;s Grapevine Neural Interface Processor. It supports high-channel-count recording and precise electrical stimulation capabilities. See the [https://rippleneuro.com/ Ripple site] for more information.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==[https://scribehow.com/page/Using_a_Ripple_device_with_BCI2000__fqrBfPskSSGBQPLttTlx2A Detailed installation instructions]==&lt;br /&gt;
&lt;br /&gt;
==Versioning==&lt;br /&gt;
&lt;br /&gt;
===Authors===&lt;br /&gt;
* Nicholas Luczak (luczak@neurotechcenter org)&lt;br /&gt;
&lt;br /&gt;
===Version History===&lt;br /&gt;
* 04/29/2025 - Initial version &lt;br /&gt;
* 06/10/2025 - Added stimulation support&lt;br /&gt;
&lt;br /&gt;
===Source Code Revisions===&lt;br /&gt;
* Initial development: XXXX&lt;br /&gt;
* Tested under: XXXX&lt;br /&gt;
* Known to compile under: XXXX&lt;br /&gt;
* Broken since: --&lt;br /&gt;
&lt;br /&gt;
==Source Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Source&amp;quot; tab of the BCI2000 config window.&lt;br /&gt;
[[File:Ripple_Source_Parameters.png|600px|thumb|center|upright=2.5|Figure 1. The default source parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===SourceCh===&lt;br /&gt;
The total number of digitized and stored channels. This can be set manually or left as &amp;quot;auto&amp;quot; to detect all available channels.&lt;br /&gt;
&lt;br /&gt;
===SampleBlockSize===&lt;br /&gt;
Samples per channel per digitized block. Together with the sampling rate, this parameter determines how often per second data are collected, processed, and feedback is updated.&lt;br /&gt;
&lt;br /&gt;
===SamplingRate===&lt;br /&gt;
The sample rate of the system. Supported rates are:&lt;br /&gt;
* 30,000 Hz (RAW)&lt;br /&gt;
* 15,000 Hz (HiFreq)&lt;br /&gt;
* 2,000 Hz (HiRes/EMG)&lt;br /&gt;
* 1,000 Hz (LFP)&lt;br /&gt;
&lt;br /&gt;
===SourceChOffset===&lt;br /&gt;
Offset for each channel in raw A/D units.&lt;br /&gt;
&lt;br /&gt;
===SourceChGain===&lt;br /&gt;
Gain for each channel in physical units per raw A/D unit (typically µV).&lt;br /&gt;
&lt;br /&gt;
===ChannelNames===&lt;br /&gt;
Names of each channel in the format &amp;quot;FrontendName_ChannelNumber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===SourceChList===&lt;br /&gt;
List of channels to actually transmit (subset of available channels).&lt;br /&gt;
&lt;br /&gt;
==Stimulation Parameters==&lt;br /&gt;
These parameters can be found in the &amp;quot;Stimulation&amp;quot; tab and matrixes of the BCI2000 config window and the Ripple Stimulation Tool.&lt;br /&gt;
[[File:RippleStimulationParameters.png|600px|thumb|center|upright=2.5|Figure 2. Stimulation parameters for the RippleADC]]&lt;br /&gt;
&lt;br /&gt;
===StimEnable===&lt;br /&gt;
Enable/disable stimulation functionality (0 or 1).&lt;br /&gt;
&lt;br /&gt;
===StimElectrode===&lt;br /&gt;
Electrode number (1-based index) to stimulate on.&lt;br /&gt;
&lt;br /&gt;
===StimFrequency===&lt;br /&gt;
Frequency of stimulation pulses in Hz (1-1000 range).&lt;br /&gt;
&lt;br /&gt;
===StimDuration===&lt;br /&gt;
Duration of each stimulation phase in milliseconds (0.01-10 range).&lt;br /&gt;
&lt;br /&gt;
===StimAmplitude===&lt;br /&gt;
Stimulation amplitude in milliamps.&lt;br /&gt;
&lt;br /&gt;
===StimTrainLength===&lt;br /&gt;
Total length of stimulation train in milliseconds.&lt;br /&gt;
&lt;br /&gt;
===StimDelay===&lt;br /&gt;
Delay before stimulation starts in milliseconds.&lt;br /&gt;
&lt;br /&gt;
==Device Parameters==&lt;br /&gt;
&lt;br /&gt;
===DeviceInfo===&lt;br /&gt;
This parameter cannot be edited and is automatically populated with information returned from the device, including:&lt;br /&gt;
* Processor type&lt;br /&gt;
* Firmware version&lt;br /&gt;
* Network address&lt;br /&gt;
* Available front ends&lt;br /&gt;
&lt;br /&gt;
===ConnectionSettings===&lt;br /&gt;
Advanced TCP/IP connection settings for the Grapevine processor.&lt;br /&gt;
&lt;br /&gt;
==States==&lt;br /&gt;
The states encode auxiliary information about the system status and stimulation events.&lt;br /&gt;
&lt;br /&gt;
===Timestamp===&lt;br /&gt;
16-bit state containing the processor timestamp for each sample block.&lt;br /&gt;
&lt;br /&gt;
===StimulusCode===&lt;br /&gt;
16-bit state that records the amplitude of active stimulation.&lt;br /&gt;
&lt;br /&gt;
===StimulusType===&lt;br /&gt;
16-bit state that indicates stimulation status.&lt;br /&gt;
&lt;br /&gt;
===ConnectionStatus===&lt;br /&gt;
8-bit state reporting the network connection quality.&lt;br /&gt;
&lt;br /&gt;
==Technical Details==&lt;br /&gt;
&lt;br /&gt;
===Supported Front Ends===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Front End Type !! Channels !! Supported Sampling Rates&lt;br /&gt;
|-&lt;br /&gt;
| Stimulation || 32 || HiRes (2kHz), HiFreq (15kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Raw || 32 || LFP (1kHz), HiRes (2kHz), Raw (30kHz)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Stimulation Waveforms===&lt;br /&gt;
Pulse parameters are converted to Ripple&#039;s stimulation command format as described in XippStimCmd.h.&lt;br /&gt;
&lt;br /&gt;
[[File:RippleStimulationWaveform.png|800px|thumb|center|Figure 3. Example monophasic stimulation waveform]]&lt;br /&gt;
&lt;br /&gt;
===Network Protocol===&lt;br /&gt;
The module uses Ripple&#039;s xipplib library to communicate with the Grapevine processor over TCP/IP. All data is transmitted in real-time with timestamps for synchronization.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[[User Reference:Filters]], [[Contributions:ADCs]]&lt;br /&gt;
[[Category:Contributions]][[Category:Data Acquisition]]&lt;/div&gt;</summary>
		<author><name>Nluczak</name></author>
	</entry>
</feed>