Welcome!

Sign in with your CogSci, Facebook, Google, or Twitter account.

Or register to create a new account.

We'll use your information only for signing in to this forum.

Supported by

[open] Reading and sending triggers from loop item list

absurdabsurd Posts: 54
edited August 2012 in OpenSesame

This is a follow up question to this earlier post on sending triggers to an eeg recording device.

I try to send out triggers that are read out from a loop item. I added two columns in the loop variable list (trig1 and trig2) and filled them with numbers to be used as triggers.
I used these variables within the python inline script that sends out the triggers. Here as an example trig1:


global io
trigger = '[trig1]'
port = 0x378
try:
io.DlPortWritePortUchar(port, trigger)
except:
print 'Failed to send trigger!'

But this produced weird results.
The triggers from the list were:


trig1 trig2
122 7
223 3
134 6
144 3
133 6
244 8
221 3

...and this was the outcome in the eeg recodring software:


84 148
180 244
20 180
116 244
116 244
116 20
84 212

What am I doing wrong here? How can I get the right triggers sent out?

Furthermore, is it possible to send out a certain (static) trigger for a correct response and another one for an incorrect reponse?
Something like:


global io
if response == '[correct_response]':
trigger = 99
else:
trigger = 88
port = 0x378
try:
io.DlPortWritePortUchar(port, trigger)
except:
print 'Failed to send trigger!'

Thanks in advance for your help,

Best wishes,

Johannes

Comments

  • EdwinEdwin Posts: 631
    edited August 2012

    Hi Johannes!

    If you are using the following notation within an inline_script...

    trigger = '[trig1]'

    ...I suggest you try the following:

    trigger = self.get("trig1")

    The '[varname]' notation can be used within OpenSesame's items, but not in an inline_script, where Python-code is expected (for more information, see here).

    On your second question: this is possible and your code is almost spot on. OpenSesame's keyboard_response and mouse_response produce a variable 'correct' that is either 1 on a correct response or 0 on an incorrect response. If you use one of those two (or the joystick plugin), you can use the following:

    global io
    if self.get("correct"):
        trigger = 99
    else:
        trigger = 88
    port = 0x378
    try:
        io.DlPortWritePortUchar(port, trigger)
    except:
        print 'Failed to send trigger!'

    If you use something else, but keep track of the variables 'response' and 'correct_response', you can use this:

    global io
    if self.get("response") == self.get("correct_response"):
        trigger = 99
    else:
        trigger = 88
    port = 0x378
    try:
        io.DlPortWritePortUchar(port, trigger)
    except:
        print 'Failed to send trigger!'

    Please let me know if it works!

    Edwin

  • absurdabsurd Posts: 54
    edited August 2012

    Hello Edwin,

    Thanks for your quick reply. The code you posted worked perfectly. As regards the second question (dynamic answer triggers) only the second bit of code worked for me (although I currently use keyboard response for testing).

    However, I have some new problems with a) the triggers actually sent and b) the timing.

    a) In my test experiment (which I rebuilt alike in Presentation) I send the following triggers (in the following order):


    99 (fixation cross at trialstart)
    1|2|3|4|5|6|7|8 (one of these for a word presented on screen)
    111|112|113|114|121|122|123|124|131|132|133|134|141|142|143|144|211|212|213|214|221|222|223|224|231|232|233|234|241|242|243|244 (one of these for a sound presented)
    70|77 (one of these for (in)correct answer)

    When I look at the trigger file of the EEG recording software, I see the following for the experiment run with Presentation (the last column are the triggers):


    38.102002 1260591 99
    38.634002 1278147 7
    39.850002 1318275 122
    45.458002 1503339 70
    47.466002 1569603 99
    47.996002 1587093 3
    49.264002 1628937 223
    54.810003 1811955 70
    56.828003 1878549 99
    ....

    OpenSesame, however, creates this:


    39.606002 1310223 103
    39.608002 1310289 99
    40.258002 1331739 7
    40.758002 1348239 127
    40.760002 1348305 122
    47.618002 1574619 126
    47.620002 1574685 70
    50.172002 1658901 103
    50.174002 1658967 99
    50.826002 1680483 3
    51.324002 1696917 223
    57.662003 1906071 70
    60.184003 1989297 111
    60.186003 1989363 99
    60.834003 2010747 103
    ....

    I wonder what all these other triggers are. Are they presented automatically by OpenSesame? Is there a way to get rid of them? If not this would be bad, as sometimes these "unexpected" triggers are just the same as the ones I use to trigger my events, so there would be no easy way to filter them out post hoc via a script.

    b) I have a totally different timing (of triggers) in OpenSesame and Presentation, although I think I use the same timing instructions in both (but here I may be wrong as I don't have that much experience with OpenSesame).
    So here is what I want:


    500 ms fixation cross (trigger 99)
    650 ms visual stimulus (trigger 1-8)
    500 ms fixation cross (no trigger)
    soundlength auditory stimulus (trigger 111-244)
    max. 2000 ms answer from participant (2000 ms timeout, trigger 70/77
    for pressed button or 77 for timeout)
    2000ms intertrial interval (no trigger)

    In OpenSesame I set up this (using Psychopy back-end, I set the Inline scripts after visual events as Lotje suggested but before the sound (as I want to know where the sound started)):


    Sketchpad fixation cross (500ms)
    Inline script trigger 99
    Sketchpad visual stimulus (650ms)
    Inline script trigger 1-8
    Sketchpad fixation cross (500ms, differently named than the first one)
    Inline script trigger 111-244
    Sampler auditory stimulus (soundlength)
    Sketchpad judge_now_symbol (duration 0, start response interval)
    Keyboard Response (timeout 2000ms)
    Inline script response trigger 70/77
    Logger
    Advanced Delay intertrial interval (2000ms, 0ms Jitter)

    Now I used the EEG-trigger files of Presentation and OpenSesame to compare the intended timing with the one that actually is in the EEG recording (I calculated the differences between the trigger times in the trigger files of the EEG recording software):

    For Presentation (not that good either):


    timing fixation cross - visual stimulus (intended: 500ms):
    mean: 529 ms
    sd: 32 timing visual stimulus - auditory stimulus (intended: 1150ms):
    mean: 1224 ms
    sd: 26

    For OpenSesame:


    timing fixation cross - visual stimulus (intended: 500ms):
    mean: 651 ms
    sd: 0.9 timing visual stimulus - auditory stimulus (intended: 1150ms):
    mean: 500 ms
    sd: 1.2

    So while the standard deviations are much better than in Presentation the timing is weird (but stable).
    What's going on here? Could you help me out?

    Cheers,
    Johannes

    Add:
    As I'm looking at my own post. The OpenSesame timing makes sense somehow. The trigger is sent out after the visual events, so for the timing fix. cross-visual stim. that is 650ms and for visual stim.-auditory stim. that is 500ms. So the triggers should be sent before the visual stimuli?

  • lvanderlindenlvanderlinden Posts: 292
    edited 12:47AM

    Hi Johannes,

    We will respond to your questions shortly.

    Best,

    Lotje

    ITA

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • lvanderlindenlvanderlinden Posts: 292
    edited 12:47AM

    Hi Johannes,

    With regard to your first question, OpenSesame does not generate triggers automatically. This should therefore be caused by something in one of your inline scripts. It's difficult for me to tell where in your code the additional triggers are sent exactly. So, if you would like to, you could upload your experiment (for example on pastebin.com) or send it by mail.

    With regard to your second question, what you mentioned in your edit seems to be exactly what is going on. Instead of sending a trigger just after fixation and stimulus presentation, respectively,

    Image and video hosting by TinyPic

    the trigger is sent after fixation presentation + its duration (i.e. after 500 ms), and after stimulus presentation + its duration (i.e. after 650 ms).

    Image and video hosting by TinyPic

    This is probably because you set the duration of your fixation sketchpad and stimulus sketchpad to 500 and 650 respectively, right? So OpenSesame first presents the sketchpad for the given duration and only then sends the trigger.

    Sending the triggers before the visual stimuli is not a good idea, as mentioned previously.

    Image and video hosting by TinyPic

    However, you can easily make the time stamps correspond to the stimulus onsets (instead of their offsets) in the following way:

    1) Set the durations of the to-be-time-stamped sketchpads to 0 ms.

    2) Send the trigger right after those

    3) And then, to keep your sketchpads presented for the intended period of time, there are two possible solutions:

    • Add a sleep command after your trigger code:
    # Your trigger code goes here
    self.sleep(500)
    • Alternatively, you could add the advanced_delay item (Items → Timing → Add advanced_timing) after the inline script with the trigger code.

    I think your analysis of the mean and SDs of the differences between the different triggers is an excellent idea. So perhaps you could do this again after applying the above suggestions and see whether you get the intended results).

    Finally, I want to point out (perhaps obviously) that the SDs you report for Presentation are way too high for carrying out trigger-locked analyses; the SD of the duration should not be much more than 1 ms.

    Good luck!

    Lotje

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • absurdabsurd Posts: 54
    edited 12:47AM

    Hi Lotje,

    Thanks for your reply and your instructions, I have a clearer understanding on how and when to send the triggers with OpenSesame now. I'll try that out soon and post the results.

    You are right concerning the Presentation SDs. I took a second look on it and have found out, that there were some rather extreme outliers within the trigger data, which have distorted the means and sds. So when I exclude these outliers I get the following results for Presentation:


    fix.cross - visual stimulus
    mean: 531 ms
    sd: 2 visual stimulus - auditory stimulus
    mean: 1266 ms
    sd: 10

    Anyway, the stimulus events themselves and the trigger are in sync. So the SDs are not for differences between stimulus and trigger but between two pairs of stimulus and trigger. So these SDs would of course not be good for e.g. reaction time studies but for designs where you just lay onsets over each other and average afterwards this will not be a concern as long as the triggers are in sync with their stimulus or am I wrong?

    As regards the strange additional triggers in OpenSesame I will send you an email with the code I ran. I really need to get them out.

    Thanks for your help and patience,

    Cheers,
    Johannes

  • lvanderlindenlvanderlinden Posts: 292
    edited August 2012

    Hi Johannes,

    Thank you for sending us your experiment. Your code looks very good and it took
    us a while to find out what could be causing the unintended triggers.

    But I think we found it. The function DlPortWritePortUchar(), which is not a native Python module, expects the parameter
    'trigger' to be an unsigned byte (called a 'ubyte' or 'uchar'). This is a specific data type that is used by low-level programming languages such as C.
    And possibly this is where it goes wrong, for some very technical reasons.

    Our suggestion is therefore to try whether your problem is solved when you force
    the parameter 'trigger'
    to be a ubyte by adding two lines in all your inline scripts for sending the triggers
    in the following way:

    # Import module needed to convert values to ubytes:
    import ctypes
    
    global io
    
    # The function ctypes.c_ubyte(x) converts x to a ubyte:
    trigger = ctypes.c_ubyte(99)
    port = 0x4cf8 
    
    try:
        # Now the parameter trigger is a ubyte:
        io.DlPortWritePortUchar(port, trigger)
    except:
        print 'Failed to send trigger!'

    We cannot test this direclty because we don't have the necessary equipment right now. So we would be
    very glad to hear whether this solution worked for you, such that we can edit the
    documentation if necessary.

    If you still encounter the same problem after trying the above, please let us know and we'll
    have a further look at how it could be solved.

    Have a good weekend!

    Lotje

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • absurdabsurd Posts: 54
    edited 12:47AM

    Hi Lotje,

    Thanks for your reply and suggestions.

    I tried that out, but unfortunately that makes no difference, I still have these additional triggers. What I may have to add, these triggers do not appear in the window with the live recording (only the intended triggers appear) but as soon as I look inside the recordings later on, these additional triggers appear. Do you have any suggestions on what else I could try out?

    Just some additional questions about triggers and sound stimuli:
    You mentioned, that it is not a good idea (because of the monitor refresh time jitter) to send a trigger out before a stimulus event. Is this true as well for auditory stimuli?

    In my test experiment I need to trigger the onset of the sound. Therefore I send out a trigger right before the sound is played.
    Or would it be a better solution to send it after the stimulus as well? The problem then is, all the sounds presented have a slightly different length, so I cannot just use the self.sleep(x) solution as for the visual stimuli without the risk that some sounds are not fully played, or am I wrong here?

    It is most important for me that the sound onset and the corresponding trigger are in sync. Do you know a way to test this?

    I'm sorry to bother you with so many questions but I really need to understand these things to make use of OpenSesame.

    Cheers,

    Johannes

  • lvanderlindenlvanderlinden Posts: 292
    edited August 2012

    Hi Johannes,

    It's no problem at all to ask a lot of questions! On the contrary; that's what the forum is for!
    Our discussions could be informative for others and at the same time your information is very helpful for the documentation on OpenSesame (such as your explanation on how to install DLPortIO on Windows 7).

    It's too bad our suggestion did not solve your problem. As a further test I recommend to
    execute a very brief experiment which sends triggers with the values 0 to 255 in two
    different runs: Once in the old way, and once by first converting the trigger values to ubytes.
    I uploaded a mini experiment with which you can easily do this (it only takes a few seconds to run):

    [gist:3503485]

    (Right click on the button 'raw' and 'save as'.)

    If you could send us the recordings afterwards we can find out whether converting the values
    to ubytes made any difference at all.

    With regard to the auditory stimuli I think your solution is very good: First send the trigger and
    then play the sound (and set the duration in the sampler item to [sound]).
    In contrast to visual output, sound output is continuous, and therefore does not suffer from a refresh-rate-like issue.
    This is why in general it doesn't matter whether such stimuli are presented before or after the trigger.
    Yet, like you said, the duration of your sounds is variable and therefore the order of your items is
    optimal as it is now!

    On the downside, the timing for auditory playback is much less accurate than for visual output. The only way to test to what extent your triggers and sound onsets are in sync is by doing some kind of benchmark experiment, like the one reported here but you'll need special equipment for this. (Without doing external measurements you will not be able to determine the real delay.)

    As far as the software is concerned, the results of the above benchmark experiment will also hold for OpenSesame because the same libraries are used to handle audio playback.
    Unfortunately, the delay will largely depend on the set up of your hardware, and, most notably, the sound card. So its difficult to say what the delay will be in your case.
    The benchmark experiment was done by using a reasonably good external sound card (Soundblaster Audigy), so the timing will probably not be as good when you just use a built-in sound card.

    Finally, I just want to emphasise two things. Firstly, both the refresh-rate jitter and the delay between code and actual sound are not specific for OpenSesame. Experiment builders can try to minise those issues
    as far as the software is concerned (e.g. by allowing for different back-ends to use), but they cannot solve the limitations of the hardware.
    And secondly, the above-mentioned issues in time-stamping sound stimuli are just meant as 'things to keep in mind'. Of course it's very well possible to carry out
    EEG experiments with sound stimuli; the timing is just less accurate than with visual stimuli.

    Best wishes,

    Lotje

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • lvanderlindenlvanderlinden Posts: 292
    edited 12:47AM

    Hi Johannes,

    Thanks for your email and explanation!

    First off, the failure of test script cannot be related to the fact that only trigger changes are recognised because this is exactly what the test script does: looping through a range of triggers (from 0 to 255) such that every trigger differs from the previous one (see also the comments in the script).

    As you have probably noticed, the trigger-sending piece of code uses 'try..except' statements.
    In general this is convenient because it enables you to run your experiment on computers that don't have DLPortIO installed too. Yet, in the current situation handing such exceptions has a disadvantage too: Any errors in this particular part of the script will not cause a crash and therefore no error messages (which are always informative).

    Therefore we adapted the previous test script by removing the exceptions. We also added a self.sleep() statement after the trigger signal, because after looking at the literature you attached we realised that the triggers were possibly sent too rapidly, that is, faster than the sampling rate. (Note that the latter only holds for the test script, not for your script.)

    So perhaps you could try to run the test script once more, and send us either the output (if the script turns out to work), or the error message(s) you get in the debug window (if the script causes a crash).

    You could do this by creating a new experiment with a single inline script and just insert the following code in the run phase of the inline script:

    [gist:3597692]

    Hopefully this will help you further!

    Lotje

    Lotje van der Linden - http://www.cogsci.nl
    FACEBOOK

  • absurdabsurd Posts: 54
    edited September 2012

    Hi Lotje,

    Great that script worked. And it ran without any errors.
    However, I have additional triggers in both unsigned bytes and normal.
    I'll send you an email with the whole trigger file, so you can take a look.
    Well that's strange, isn't it. Do you have an idea what to do now?

    Best wishes,
    Johannes

  • sebastiaansebastiaan Posts: 2,516
    edited 12:47AM

    Hi Johannes,

    Lotje told me about your mysterious extra triggers, and sent me the results of the test script. I'm pretty sure we figured out the core of the issue, but it's one of the strangest problems I have ever encountered.

    Let's first take a look at a snippet of your trigger file:

    9.564000    318837   1
    9.680000    322665   3
    9.682000    322731   2

    The correct order is 1-2, so the 3 shouldn't be there. Now let us consider the binary representation of 1, 2, and 3:

    1 -> 0001
    2 -> 0010
    3 -> 0011

    The point to note here is that 3 contains all the bits that are enabled in 1 and/or 2. More formally, you could say that 3 = 1 OR 2. Try it in a Python terminal:

    Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
    [GCC 4.6.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 1 | 2
    3

    This is not a coincidence. As far as I can tell, all extraneous triggers can be explained this way. For example the mysterious 127, in between 111 and 112:

    22.410001    742755 111
    22.526001    746583 127
    22.528001    746649 112

    Let's look at the binary representation:

    111 -> 0110 1111
    112 -> 0111 0000
    127 -> 0111 1111

    Again, 127 = 111 OR 112.

    So something like the following might be going on: When a trigger changes, first all the bits that should be switched on are switched on, and only a tiny bit later the bits that should be switched off are switched off. The result is that just before a new trigger is registered, there is very brief 'ghost' trigger that is the bitwise OR of the old and the new trigger. Does this make sense?

    The question is whether this issue is related to OpenSesame. To a certain extent it apparently is, because you report that the same thing doesn't happen with Presentation. But I strongly suspect that DLPortIO (the DLL used for sending triggers) does not, in fact, send those ghost triggers, but that they are a quirk of the EEG apparatus. Why the problem sometimes occurs, and sometimes not, I couldn't say.

    So what can you do?

    • First off all, don't worry too much. I recommend that you record the correct order of the triggers to a separate log file, and you will be able to filter out the ghost triggers afterwards.
    • Contact the EEG vendor and explain to them what happens, and what appears to be the problem. If it is indeed a quirk with the apparatus, they will want to know. And if it is not, they may be able to shed light on the issue.

    Cheers,
    Sebastiaan

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

  • absurdabsurd Posts: 54
    edited 12:47AM

    Hi Sebastian,

    Great you found out the reason of these ghost triggers. It seems to me that this even explains when the triggers do not appear:


    ...
    216 (correct) binary: 11011000
    217 (correct) binary: 11011001
    219 (ghost) binary: 11011011
    218 (correct) binary: 11011010
    ...

    So switching from 217 to 218 would involve switching the final 1 to 0. This does not happen (at least fast enough) with the result 219. Switching from 216 to 217 does not involve any switching down to 0. That is why there appears no ghost between them.

    So the problem is that activated bits are not deactivated (fast enough). I checked this with two different computers (with totally different hardware, one is a Win7 laptop with a parallel express card the other a winxp sp3 desktop with a pci parallel card) running OpenSesame and in both setups the ghost triggers occur, so it does not seem to be a hardware problem related to the parallel card.

    Ok, filtering the ghost triggers out post hoc would be an option but I also contacted the manufacturers of the amplifier and recording software and sent them a test recording.

    Well, in reply to this they asked me some questions I cannot answer right now as I just do not know, so I repeat them here:

    What is the trigger length sent out by OpenSesame (can this be determined?)?
    With a sampling rate of the recording set to 500Hz the trigger must be at least 2ms or 5ms (the official support and the documentation of the software differ here) long.

    Are the triggers high activ or low active? (I think this means is an "on" bit set by 5V or 0V?)

    Are the "pulses"/triggers then completely closed after sending, as it seems that the ports just remain open after trigger activation?

    Is there a way to determine this or can this be manipulated from within OpenSesame?

    Thanks a lot for your help.

    Cheers,

    Johannes

  • sebastiaansebastiaan Posts: 2,516
    edited 12:47AM
    So switching from 217 to 218 would involve switching the final 1 to 0. This does not happen (at least fast enough) with the result 219. Switching from 216 to 217 does not involve any switching down to 0. That is why there appears no ghost between them.

    Indeed! The bitwise OR of 216 and 217 is 217, so no additional trigger appears:

    >>> 216 | 217
    217


    What is the trigger length sent out by OpenSesame (can this be determined?)? With a sampling rate of the recording set to 500Hz the trigger must be at least 2ms or 5ms (the official support and the documentation of the software differ here) long.

    Each trigger is sent for 100ms, so that should be plenty. (To my understanding, the trigger event itself does not have a length. The length of a trigger is simply the interval between to subsequent triggers.)

    Are the triggers high activ or low active? (I think this means is an "on" bit set by 5V or 0V?)

    I don't know, to be honest. This is not explicitly set, and I do not see any mention of this in DLPortIO. My guess is therefore that this is a property of the operating system, in which case DLPortIO just uses the system default (whatever that may be).

    Are the "pulses"/triggers then completely closed after sending, as it seems that the ports just remain open after trigger activation?

    I'm not sure what they mean here? As far as I understand it, the parallel port always carries some value. Sending a trigger simply changes that value, and that's pretty much all there is to it. So (as far as I know) the parallel port cannot be closed, like you can close, say, an internet connection. That being said, my understanding is incomplete and I might be wrong.

    But with the necessary equipment, the vendor guys can easily check all of this themselves, of course. As you know, OpenSesame does not have any custom code to handle the parallel port. It just uses DLPortIO.dll, which is in turn a pretty simple (and widely used) library.

    Good luck!

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

  • absurdabsurd Posts: 54
    edited 12:47AM

    Hi Lotje, hi Sebastian!

    I'm happy to report that I found a solution!

    The trick is to send a second trigger that just sends a 0 before the next trigger is sent out. Further, it is crucial that behind both triggers there has to be a self.sleep() phase of at least 2ms (no upper border) if you record with a sample rate of 500 Hz or at least 1ms if you record with 1000 Hz.

    A trigger value of 0 is not interpreted at all by BrainVisionRecorder (so simply nothing appears) but it resets all the activated bits to zero/0V/low. With this no ghost triggers appear any more!

    Here is the code I ran:

    [gist:3716574]

    I have also tried out inpout.dll (another free parallel driver) and this works as well. This driver is also available as inpout64.dll for Windows 7, but I had no time to try that out right now (I currently test on an XP machine). I'll check the timing an report if there are differences to dlportio.dll. The code is nearly identical, you just replace:


    io = windll.dlportio

    with

    io = windll.inpout32

    and the triggers are sent with

    io.Out32(port, trigger)

    instead of

    io.DlPortWritePortUchar(port, trigger)

    However, the same issue appears with inpout32.dll. One has to send a zero trigger here as well.

    Additional questions arise now:

    If I have to send an additional zero trigger after each 'normal' trigger, I can't control the timing of the preceding visual stimulus (sketchpad) just by e.g. self.sleep(500), or can I do this?

    The same thing vice versa with sound stimuli: I have an additional 2ms delay if I send the stimulus trigger right before the sound, or am I wrong here?

    How could I solve this?

    Best wishes,
    Johannes

  • sebastiaansebastiaan Posts: 2,516
    edited 12:47AM
    The trick is to send a second trigger that just sends a 0 before the next trigger is sent out. Further, it is crucial that behind both triggers there has to be a self.sleep() phase of at least 2ms (no upper border) if you record with a sample rate of 500 Hz or at least 1ms if you record with 1000 Hz.

    Right, that's a clever solution! The binary or of 0 and X is always X, so there are no ghost triggers when switching to and from 0. If the EEG apparatus disregards 0-value triggers, you can thus use a 0-value trigger as a reset.

    I have also tried out inpout.dll (another free parallel driver) and this works as well.

    Thanks, that's useful to know.

    If I have to send an additional zero trigger after each 'normal' trigger, I can't control the timing of the preceding visual stimulus (sketchpad) just by e.g. self.sleep(500), or can I do this?

    You could send the extra trigger halfway the delay period, like so:

    io.DlPortWritePortUchar(port, my_trigger)
    self.sleep(250)
    io.DlPortWritePortUchar(port, 0)
    self.sleep(250)

    This should work, I believe. Of course you can use different delays, as long as they add up to 500. (As an aside, it is a good idea to choose a delay that is just a few milliseconds short of the delay that you actually want to have. The reason is that the display presentation will block until the next display refresh, which essentially 'rounds up' the delay interval. Does that make sense?)

    The same thing vice versa with sound stimuli: I have an additional 2ms delay if I send the stimulus trigger right before the sound, or am I wrong here?

    Right, so you could send the 0-value trigger after the sound. If I understand correctly it doesn't matter if the 0-value trigger is sent right after the regular trigger, or only some time later. As long as there is a 0-value trigger somewhere in between each pair of regular triggers you should be good.

    io.DlPortWritePortUchar(port, my_trigger)
    # Start sound playback, either using a sampler or an inline script
    self.sleep(2) # Only necessary if sound playback duration is set to 0
    io.DlPortWritePortUchar(port, 0)

    Thanks for being so patient and persistent! I'm sure this discussion will be helpful to a lot of people!

    Cheers!

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

  • meldiwinymeldiwiny Posts: 17
    edited 12:47AM

    please could any one help me in linking between Emotive EEG and opensesame via serial port , i supposed to make VEP

Sign In or Register to comment.