All functions of this toolbox involved in the presentation of stimuli on the screen (e.g. words and images) will display their results immediately. This means that everything the function is told to present will be presented on the screen right after the function is called (for advanced users: the ‘Flip’ command from the Psychophysics Toolbox is executed in every function call).
All functions of this toolbox involved in the presentation of stimuli on the screen (e.g. words and images) will display their results immediately. This means that everything the function is told to present will be presented on the screen right after the function is called (for advanced users: the 'Flip' command from the Psychophysics Toolbox is executed in every function call).
A problem here may occur when you want to combine different presenting functions, e.g. to present text and an image or different texts on different locations on the screen. That is why most presenting functions have the option to use the input argument ‘dontFlip’. When this option is used, the stimulus presentation happens off-screen one after the other (for advanced users: everything will be saved to an internal buffer). As soon as a presenting function is called without the ‘dontFlip’ option everything that was stored internally will be displayed at once. This makes it possible to build up a presentation screen consisting of different input arguments. It also makes possible the combination of images and text. This process works pretty fast and you won’t have any problems of making several ‘dontFlip’ calls and displaying them all within the next frame.
A problem here may occur when you want to combine different presenting functions, e.g. to present text and an image or different texts on different locations on the screen. That is why most presenting functions have the option to use the input argument 'dontFlip'. When this option is used, the stimulus presentation happens off-screen one after the other (for advanced users: everything will be saved to an internal buffer). As soon as a presenting function is called without the 'dontFlip' option everything that was stored internally will be displayed at once. This makes it possible to build up a presentation screen consisting of different input arguments. It also makes possible the combination of images and text. This process works pretty fast and you won’t have any problems of making several 'dontFlip' calls and displaying them all within the next frame.
**Example (2)**
~~~matlab
...
...
@@ -40,17 +40,17 @@ If you want to use a Raspberry as a remote device, you are able to do that witho
The first step is similar to the procedure described above: download the image file for the Raspberry Pi and flash an SD card. After the Raspberry is up and running modify one file to change the behavior of the Raspberry:
Modify the Octave internal file ‘/home/pi/.octaverc’. This file is called when Octave starts. You can open it with a simple text editor and enter matlab code at the end of the file. This code will then be called directly after starting Octave and before any user input can be made. Use this option to call [initOTBR](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/initOTBR.m) in this file followed by [connect2ControlComputer](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Network/ExperimentalComputer/connect2ControlComputer.m)(see[section 14.1.](/Network-remote-computer#connect2controlcomputer)). This will initialize the toolbox on the raspberry system. With this changes the Raspberry will now wait for input from the control computer after a reboot.
Modify the Octave internal file ‘/home/pi/.octaverc’. This file is called when Octave starts. You can open it with a simple text editor and enter matlab code at the end of the file. This code will then be called directly after starting Octave and before any user input can be made. Use this option to call [initOTBR](/Initialization#initotbr) in this file followed by [connect2ControlComputer](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Network/ExperimentalComputer/connect2ControlComputer.m)(see[section 14.1.](/Network-remote-computer#connect2controlcomputer)). This will initialize the toolbox on the raspberry system. With this changes the Raspberry will now wait for input from the control computer after a reboot.
Before rebooting the Raspberry Pi make sure to check the IP address of the Raspberry. Therefore we created a Link on the Desktop “Change IP address here” that helps you to modify the IP address if necessary.
All other steps can now be performed on the control computer. First make sure to enter all remote host IP addresses in section 10 of [myHardwareSetup](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/myHardwareSetup.m). In case you use only one Raspberry Pi of course only one IP address is needed. In your experimental script you now need to call [connect2Host](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Network/ControlComputer/connect2Host.m) to establish a network communication to all remote host (Raspberry Pi) that are defined in [myHardwareSetup.m](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/myHardwareSetup.m).
All other steps can now be performed on the control computer. First make sure to enter all remote host IP addresses in section 10 of [myHardwareSetup](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/myHardwareSetup.m). In case you use only one Raspberry Pi of course only one IP address is needed. In your experimental script you now need to call [connect2Host](/Network-control-computer#connect2host) to establish a network communication to all remote host (Raspberry Pi) that are defined in [myHardwareSetup.m](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/myHardwareSetup.m).
To run an actual experiment the Raspberry system needs the experimental files first. That includes stimuli, commands and a place to put results. Send your entire experimental folder by using the [sendExperiment2Host](Network/ControlComputer/sendExperiment2Host.m) command.
To run an actual experiment the Raspberry system needs the experimental files first. That includes stimuli, commands and a place to put results. Send your entire experimental folder by using the [sendExperiment2Host](/Network-control-computer#sendexperiment2host) command.
The next thing you want to do is to send a command to the remote host. Call [sendCommand2Host](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Network/ControlComputer/sendCommand2Host.m) for this. This function enables you to send any matlab command you like to the host via the established communication. Be aware that the commands need to be entered as strings. The function [printCmd](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/printCmd.m) will do this for you. Use the output from [printCmd](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/printCmd.m) as input for [sendCommand2Host](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Network/ControlComputer/sendCommand2Host.m). E.g. sendCommand2Host(_printCmd([], 'keyBuffer', 10, 'goodkey', (1:3), 'badkey', 4)_);
The next thing you want to do is to send a command to the remote host. Call [sendCommand2Host](/Network-control-computer#sendcommand2host) for this. This function enables you to send any matlab command you like to the host via the established communication. Be aware that the commands need to be entered as strings. The function [printCmd](/Network-control-computer#printcmd) will do this for you. Use the output from [printCmd](/Network-control-computer#printcmd) as input for [sendCommand2Host](/Network-control-computer#sendcommand2host). E.g. sendCommand2Host(_printCmd([], 'keyBuffer', 10, 'goodkey', (1:3), 'badkey', 4)_);
During the experiment your [keyBuffer](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/IO/keyBuffer.m) results will now be saved as variables on the remote host (Raspberry Pi). Do not forget to call [getKeyBufferResults](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Network/ControlComputer/getKeyBufferResult.m) on your control computer to transfer these results, otherwise you will not be able to save it. After finishing an experiment and transferring your results always call [disconnectFromHost](/Network-control-computer#disconnectfromhost)(as implied in [1.4. Function Tree](/Getting-started#function-tree)) to shut down the connection as well as the remote host. After disconnecting from a remote host we recommend to reboot the Raspberry before starting a new experiment. Call disconnectFromHost(‘reboot’) to reboot and consider to restart MATLAB or Octave on your local computer.
During the experiment your [keyBuffer](/User-or-animal-response#keybuffer-animal) results will now be saved as variables on the remote host (Raspberry Pi). Do not forget to call [getKeyBufferResults](/Network-control-computer#getkeybufferresult) on your control computer to transfer these results, otherwise you will not be able to save it. After finishing an experiment and transferring your results always call [disconnectFromHost](/Network-control-computer#disconnectfromhost)(as implied in [1.4. Function Tree](/Getting-started#function-tree)) to shut down the connection as well as the remote host. After disconnecting from a remote host we recommend to reboot the Raspberry before starting a new experiment. Call disconnectFromHost('reboot') to reboot and consider to restart MATLAB or Octave on your local computer.
You can include all of the commands mentioned above in your experimental script on your control computer. When everything is set up you don’t need to do more than running this scrip to conduct an experiment.
...
...
@@ -110,13 +110,13 @@ This makes sure that Octave starts and calls the function [connect2ControlComput
This toolbox comprises the option to communicate between an MRI scanner and an experimental computer. To use this option you need to connect the devices via parallel port and call the functions described below in the correct order.
At first you need to initialize basic functions. Therefore you call [initMRIChatPart1](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/initMRIChatPart1.m). This will start the program triggerCounter2_MCR9-2.exe, which organizes the communication with the parallel port. The program will open an own window displaying user information and the number of triggers sent, their timing and the intervals between scans. After the experiment is done and the window is closed properly the trigger information will be saved to a specific file using the date and time of the experiment as name. The application can be stopped by pressing escape.
At first you need to initialize basic functions. Therefore you call [initMRIChatPart1](/MRI-or-trigger#initmrichatpart1). This will start the program triggerCounter2_MCR9-2.exe, which organizes the communication with the parallel port. The program will open an own window displaying user information and the number of triggers sent, their timing and the intervals between scans. After the experiment is done and the window is closed properly the trigger information will be saved to a specific file using the date and time of the experiment as name. The application can be stopped by pressing escape.
Before continuing you need to open a presentation window ([initWindow](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Screen/initWindow.m)), this is mandatory for the following functions. After you initialized the presentation window you can call [initMRIChatPart2](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/initMRIChatPart2.m). Here you define the number of scans you want to wait before actually starting the experiment. User information about the overall process will appear on the presentation window automatically.
Before continuing you need to open a presentation window ([initWindow](/Stimuli-Display#initwindow)), this is mandatory for the following functions. After you initialized the presentation window you can call [initMRIChatPart2](/MRI-or-trigger#initmrichatpart2). Here you define the number of scans you want to wait before actually starting the experiment. User information about the overall process will appear on the presentation window automatically.
Lastly if you have to send triggers from the experimental computer to external devices you have to use the function [sendTriggerMRI](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/sendTriggerMRI.m). During an MRI experiment you will not be able to use parChat or parChatWord for trigger events. That is because these functions directly connect to the parallel port, which in this case is being occupied by the program triggerCounter2. In contrast [sendTriggerMRI](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/sendTriggerMRI.m) uses the triggerCounter2 application to send triggers via the parallel port.
Lastly if you have to send triggers from the experimental computer to external devices you have to use the function [sendTriggerMRI](/MRI-or-trigger#sendtriggermri). During an MRI experiment you will not be able to use [parChat](/MRI-or-trigger#parchat) or [parChatWord](/MRI-or-trigger#parchatword) for trigger events. That is because these functions directly connect to the parallel port, which in this case is being occupied by the program triggerCounter2. In contrast [sendTriggerMRI](/MRI-or-trigger#sendtriggermri) uses the triggerCounter2 application to send triggers via the parallel port.
The following example provides a very simple MRI experiment that contains all features necessary, as well as the use of [sendTriggerMRI](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/sendTriggerMRI.m) connected to the display of user information. You can use it as baseline for your own experiments.
The following example provides a very simple MRI experiment that contains all features necessary, as well as the use of [sendTriggerMRI](/MRI-or-trigger#sendtriggermri) connected to the display of user information. You can use it as baseline for your own experiments.
~~~matlab
%% Example for Scanner
...
...
@@ -157,9 +157,9 @@ closeWindow
## Event-codes
When your experiment focuses on a specific time course it may be helpful to mark specific events, such as a stimulus display, with certain event codes, for example triggers. Especially in EEG and MRI experiments it can be very helpful for connecting recordings to behavioral responses. The OTBR toolbox can send triggers from e.g. an experimental computer to a control computer using a parallel port or other supported IO devices. Functions that are capable of using the parallel port directly are [sendTriggerMRI](https://gitlab.ruhr-uni-bochum.de/ikn/OTBR/-/blob/master/Tools/sendTriggerMRI.m), parChat and parChatWord. The first one has been explained in the previous chapter. The other two can be used for example during EEG or other behavioral experiments that use external devices.
When your experiment focuses on a specific time course it may be helpful to mark specific events, such as a stimulus display, with certain event codes, for example triggers. Especially in EEG and MRI experiments it can be very helpful for connecting recordings to behavioral responses. The OTBR toolbox can send triggers from e.g. an experimental computer to a control computer using a parallel port or other supported IO devices. Functions that are capable of using the parallel port directly are [sendTriggerMRI](/MRI-or-trigger#sendtriggermri), [parChat](/MRI-or-trigger#parchat) and [parChatWord](/MRI-or-trigger#parchatword). The first one has been explained in the previous chapter. The other two can be used for example during EEG or other behavioral experiments that use external devices.
The function parChat can activate or deactivate single pins of the parallel port, which can be used as trigger. The function requires one or two input arguments. When two arguments are given the function can be used to activate or deactivate pin 2-9 of the parallel port. The first argument defines the pin (‘1’=pin2, ‘2’=pin3, etc.) the second argument defines the status (on/off). If only one argument is given it can be used to listen to pin 10-15 of the parallel port (‘1’=pin10, ‘2’=pin11, etc.). The following list shows all possible outcomes and the necessary arguments to achieve them.
The function [parChat](/MRI-or-trigger#parchat) can activate or deactivate single pins of the parallel port, which can be used as trigger. The function requires one or two input arguments. When two arguments are given the function can be used to activate or deactivate pin 2-9 of the parallel port. The first argument defines the pin (‘1’=pin2, ‘2’=pin3, etc.) the second argument defines the status (on/off). If only one argument is given it can be used to listen to pin 10-15 of the parallel port (‘1’=pin10, ‘2’=pin11, etc.). The following list shows all possible outcomes and the necessary arguments to achieve them.
**Examples**
~~~matlab
...
...
@@ -177,34 +177,34 @@ Listen to Pin 12: parChat(3)
ListentoPin13:parChat(4)
ListentoPin15:parChat(5)
~~~
In contrast to parChat the function parChatWord has the advantage to activate several pins at once. Therefor it uses all 8 bits of the data port (pin 2-9). It needs only one input argument, which is the decimal value of an array representing a binary number. Using this option takes several steps:
In contrast to [parChat](/MRI-or-trigger#parchat) the function [parChatWord](/MRI-or-trigger#parchatword) has the advantage to activate several pins at once. Therefor it uses all 8 bits of the data port (pin 2-9). It needs only one input argument, which is the decimal value of an array representing a binary number. Using this option takes several steps:
First you should think about which pin you want to activate and convert this into an array with 8 digits.
**Example**
>You want to activate pin 8, 6 and 2 at the same time. Converted to an 8 digit array it would look like this: ‘01010001’. The first digit represents pin 9, the second pin 8 etc. and the last digit represents pin 2. That means the numerical order of the pins is inverted.
>You want to activate pin 8, 6 and 2 at the same time. Converted to an 8 digit array it would look like this: '01010001'. The first digit represents pin 9, the second pin 8 etc. and the last digit represents pin 2. That means the numerical order of the pins is inverted.
Next you have to convert your array into a decimal value. You can use the matlab internal function bin2dec for this.
Next you have to convert your array into a decimal value. You can use the matlab internal function [bin2dec](https://de.mathworks.com/help/matlab/ref/bin2dec.html?s_tid=doc_ta) for this.
**Example**
~~~matlab
bin2dec(‘01010001’)
bin2dec('01010001')
ans=81
~~~
This also works the opposite way, therefore you need to use dec2bin.
This also works the opposite way, therefore you need to use [dec2bin](https://de.mathworks.com/help/matlab/ref/dec2bin.html).
**Example**
~~~matlab
dec2bin(81,8)
ans=‘01010001’
ans='01010001'
% the first input argument in the decimal value, the second argument is the minimal amount of digits
~~~
Now you can use this decimal number as input for parChatWord.
Now you can use this decimal number as input for [parChatWord](/MRI-or-trigger#parchatword).
**Example**
...
...
@@ -213,7 +213,7 @@ parChatWord(81)
~~~
:arrow_right: activate pin 2, 6 and 8
Finally, you can deactivate all pins at once using ‘0’ as input argument.
Finally, you can deactivate all pins at once using '0' as input argument.