I have recently started working with fNIRS as opposed to fMRI as my primary mode of neuroimaging. As a result I found myself needing a way to send trigger pulses to my fNIRS unit (NinjaNIRS 2021). After substantial searching the cheapest ready-made solution I could find for this purpose was still hundreds of dollars.
I thought about this for a bit and came to the conclusion that I should just make such a device. My fNIRS unit relies on a standard trigger pulse sent over a BNC connection. Most such pulses are 5v and I was already familiar with a microcontroller board
that could easily do this - Arduino Uno!
In this blog post I detail the steps for making this device yourself - from creating the actual unit to making it communicate with PsychoPy (the presentation software I am using). This was a bit of a challenge at first so I figured I would make a tutorial/walkthrough on how to make your own trigger box for $30 or less! Although this build uses a BNC connector, you can do this with basically any type of connection you need excepting certain cases (things needing different volatges, proprietary connectors, etc).
Please keep in mind that this was developed with a very specific use case in mind and may need to be further modified to suit your purposes. That said, the Arduino program shouldn’t need changing – all changes are most likely to be done in PsychoPy. This approach also works with ePrime, but I do not have access to ePrime at the moment to give specific instructions. Realistically this should work with any software that is customizable and sends triggers over serial ports.
Assuming you have none of the needed items, you will need to purchase the following:
1x Arduino Uno and USB cable - https://store.arduino.cc/products/arduino-uno-rev3 (the smaller Arduino Nano will also work)
1x Male BNC terminal block - https://www.adafruit.com/product/2888
Some jumper wires - https://www.adafruit.com/product/758
1x Project enclosure of your choice (for finishing)
Arduino Steps
Attach a jumper wire to each terminal of the BNC block
Plug the positive into digital pin 2 on the Arduino
Plug the negative into the GND on the same side of the board
Upload the sketch (bottom of this page)
Find/confirm the COM port (or address if not using windows) of your Arduino and note it for later
PsychoPy Steps
Add a “Serial” component to your routine loop that has your task trials
Set start and stop as “Condition” and in the field use $stimulus.status == STARTED (NOTE: you need to rename the “stimulus” part of “stimulus.status” to your actual stim name!)
The “Stop” command will be different from study to study – I am just waiting on their response to send the stop trigger in my study (indicated by a mouse click) and so the stop field reads $mouse.getPressed()[0]==1
Enter your Arduino location as the “Port” field (e.g., “COM4”) – if using Windows check your device manager to confirm the port location of your Arduino.
Make start data A1 and stop data A0 unless you altered the Arduino sketch.
If you run into any frustrating errors about not having permission to “COM4” etc., check your version of PsychoPy. I spent 4 hours trying to overcome this just to learn that PsychoPy v2022.2.5 had some gnarly bug in it that makes it unable to communicate with serial ports.
However, version 2023.1.0 has corrected the issue, so make sure you’re running with that!
Here is the specific installation I used while developing this: https://github.com/psychopy/psychopy/releases/tag/2023.1.0
Arduino Sketch Code
Note - I did not write this Arduino program myself. I took code for a very similar device created by Theodore Huppert in 2018 - mine is just simplified a bit.
//This sketch is for making a simple single-port BNC device trigger
//Developed for use with PsychoPy (but should work with others)
//See sjwest.io/my-blog for more information
// pins for the LEDs:
const int Pin1 = 2;
const int LED = LED_BUILTIN;
String content;
void setup() {
// initialize serial:
Serial.begin(9600);
// make the pins outputs:
pinMode(Pin1, OUTPUT);
digitalWrite(LED, LOW);
digitalWrite(Pin1, LOW);
content = "";
}
void loop() {
// if there's any serial available, read it:
digitalWrite(LED, LOW);
while (Serial.available() > 0) {
delay(3);
char c = Serial.read();
content += c;
}
if (content.length() > 0) {
Serial.println(content);
if (content.indexOf("A1") >= 0) {
digitalWrite(Pin1, HIGH);
digitalWrite(LED, HIGH);
Serial.print("A-on\n");
}
if (content.indexOf("A0") >= 0) {
digitalWrite(Pin1, LOW);
digitalWrite(LED, LOW);
Serial.print("A-off\n");
}
content = "";
}
}
Comments