If else condition for Sound or Heart Symbol

Hi
I have a psychopy experiment for EEG experiment where i am tellling people to focus on heartbeat or hearing based on two images shown on screen.I want to add a functionality with code for the loop in the “real trials” and “real ratings” boxes in psychopy that tells the EEG system whether the subjects saw either the heart symbol or the headphone symbol (i.e. whether we instructed them to focus on their heartbeat or on the noise).

The codes are as follows

Real trials

— Prepare to start Routine “real_trials” —

    # create an object to store info about Routine real_trials
    real_trials = data.Routine(
        name='real_trials',
        components=[text_53, sound_24, image],
    )
    real_trials.status = NOT_STARTED
    continueRoutine = True
    # update component parameters for each repeat
    sound_24.setSound('Brownnoise2.flac', secs=20, hamming=True)
    sound_24.setVolume(1.0, log=False)
    sound_24.seek(0)
    image.setImage(image_instruction)
    # store start times for real_trials
    real_trials.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
    real_trials.tStart = globalClock.getTime(format='float')
    real_trials.status = STARTED
    thisExp.addData('real_trials.started', real_trials.tStart)
    real_trials.maxDuration = None
    # keep track of which components have finished
    real_trialsComponents = real_trials.components
    for thisComponent in real_trials.components:
        thisComponent.tStart = None
        thisComponent.tStop = None
        thisComponent.tStartRefresh = None
        thisComponent.tStopRefresh = None
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED
    # reset timers
    t = 0
    _timeToFirstFrame = win.getFutureFlipTime(clock="now")
    frameN = -1
    
    # --- Run Routine "real_trials" ---
    # if trial has changed, end Routine now
    if isinstance(trials, data.TrialHandler2) and thisTrial.thisN != trials.thisTrial.thisN:
        continueRoutine = False
    real_trials.forceEnded = routineForceEnded = not continueRoutine
    while continueRoutine:
        # get current time
        t = routineTimer.getTime()
        tThisFlip = win.getFutureFlipTime(clock=routineTimer)
        tThisFlipGlobal = win.getFutureFlipTime(clock=None)
        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
        
        # *text_53* updates
        
        # if text_53 is starting this frame...
        if text_53.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
            # keep track of start time/frame for later
            text_53.frameNStart = frameN  # exact frame index
            text_53.tStart = t  # local t and not account for scr refresh
            text_53.tStartRefresh = tThisFlipGlobal  # on global time
            win.timeOnFlip(text_53, 'tStartRefresh')  # time at next scr refresh
            # add timestamp to datafile
            thisExp.timestampOnFlip(win, 'text_53.started')
            # update status
            text_53.status = STARTED
            text_53.setAutoDraw(True)
        
        # if text_53 is active this frame...
        if text_53.status == STARTED:
            # update params
            pass
        
        # if text_53 is stopping this frame...
        if text_53.status == STARTED:
            # is it time to stop? (based on global clock, using actual start)
            if tThisFlipGlobal > text_53.tStartRefresh + isi_time-frameTolerance:
                # keep track of stop time/frame for later
                text_53.tStop = t  # not accounting for scr refresh
                text_53.tStopRefresh = tThisFlipGlobal  # on global time
                text_53.frameNStop = frameN  # exact frame index
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'text_53.stopped')
                # update status
                text_53.status = FINISHED
                text_53.setAutoDraw(False)
        
        # *sound_24* updates
        
        # if sound_24 is starting this frame...
        if sound_24.status == NOT_STARTED and tThisFlip >= isi_time-frameTolerance:
            # keep track of start time/frame for later
            sound_24.frameNStart = frameN  # exact frame index
            sound_24.tStart = t  # local t and not account for scr refresh
            sound_24.tStartRefresh = tThisFlipGlobal  # on global time
            # add timestamp to datafile
            thisExp.addData('sound_24.started', tThisFlipGlobal)
            # update status
            sound_24.status = STARTED
            sound_24.play(when=win)  # sync with win flip
        
        # if sound_24 is stopping this frame...
        if sound_24.status == STARTED:
            # is it time to stop? (based on global clock, using actual start)
            if tThisFlipGlobal > sound_24.tStartRefresh + 20-frameTolerance or sound_24.isFinished:
                # keep track of stop time/frame for later
                sound_24.tStop = t  # not accounting for scr refresh
                sound_24.tStopRefresh = tThisFlipGlobal  # on global time
                sound_24.frameNStop = frameN  # exact frame index
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'sound_24.stopped')
                # update status
                sound_24.status = FINISHED
                sound_24.stop()
        
        # *image* updates
        
        # if image is starting this frame...
        if image.status == NOT_STARTED and tThisFlip >= isi_time-frameTolerance:
            # keep track of start time/frame for later
            image.frameNStart = frameN  # exact frame index
            image.tStart = t  # local t and not account for scr refresh
            image.tStartRefresh = tThisFlipGlobal  # on global time
            win.timeOnFlip(image, 'tStartRefresh')  # time at next scr refresh
            # add timestamp to datafile
            thisExp.timestampOnFlip(win, 'image.started')
            # update status
            image.status = STARTED
            image.setAutoDraw(True)
        
        # if image is active this frame...
        if image.status == STARTED:
            # update params
            pass
        
        # if image is stopping this frame...
        if image.status == STARTED:
            # is it time to stop? (based on global clock, using actual start)
            if tThisFlipGlobal > image.tStartRefresh + 20-frameTolerance:
                # keep track of stop time/frame for later
                image.tStop = t  # not accounting for scr refresh
                image.tStopRefresh = tThisFlipGlobal  # on global time
                image.frameNStop = frameN  # exact frame index
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'image.stopped')
                # update status
                image.status = FINISHED
                image.setAutoDraw(False)
        
        # check for quit (typically the Esc key)
        if defaultKeyboard.getKeys(keyList=["escape"]):
            thisExp.status = FINISHED
        if thisExp.status == FINISHED or endExpNow:
            endExperiment(thisExp, win=win)
            return
        # pause experiment here if requested
        if thisExp.status == PAUSED:
            pauseExperiment(
                thisExp=thisExp, 
                win=win, 
                timers=[routineTimer], 
                playbackComponents=[sound_24]
            )
            # skip the frame we paused on
            continue
        
        # check if all components have finished
        if not continueRoutine:  # a component has requested a forced-end of Routine
            real_trials.forceEnded = routineForceEnded = True
            break
        continueRoutine = False  # will revert to True if at least one component still running
        for thisComponent in real_trials.components:
            if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                continueRoutine = True
                break  # at least one component has not yet finished
        
        # refresh the screen
        if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
            win.flip()
    
    # --- Ending Routine "real_trials" ---
    for thisComponent in real_trials.components:
        if hasattr(thisComponent, "setAutoDraw"):
            thisComponent.setAutoDraw(False)
    # store stop times for real_trials
    real_trials.tStop = globalClock.getTime(format='float')
    real_trials.tStopRefresh = tThisFlipGlobal
    thisExp.addData('real_trials.stopped', real_trials.tStop)
    sound_24.pause()  # ensure sound has stopped at end of Routine
    # the Routine "real_trials" was not non-slip safe, so reset the non-slip timer
    routineTimer.reset()

Real Ratings

    # --- Prepare to start Routine "real_ratings" ---
    # create an object to store info about Routine real_ratings
    real_ratings = data.Routine(
        name='real_ratings',
        components=[slider_23, text_54],
    )
    real_ratings.status = NOT_STARTED
    continueRoutine = True
    # update component parameters for each repeat
    slider_23.reset()
    text_54.setText(questions_ratings)
    # store start times for real_ratings
    real_ratings.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
    real_ratings.tStart = globalClock.getTime(format='float')
    real_ratings.status = STARTED
    thisExp.addData('real_ratings.started', real_ratings.tStart)
    real_ratings.maxDuration = None
    # keep track of which components have finished
    real_ratingsComponents = real_ratings.components
    for thisComponent in real_ratings.components:
        thisComponent.tStart = None
        thisComponent.tStop = None
        thisComponent.tStartRefresh = None
        thisComponent.tStopRefresh = None
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED
    # reset timers
    t = 0
    _timeToFirstFrame = win.getFutureFlipTime(clock="now")
    frameN = -1
    
    # --- Run Routine "real_ratings" ---
    # if trial has changed, end Routine now
    if isinstance(trials, data.TrialHandler2) and thisTrial.thisN != trials.thisTrial.thisN:
        continueRoutine = False
    real_ratings.forceEnded = routineForceEnded = not continueRoutine
    while continueRoutine:
        # get current time
        t = routineTimer.getTime()
        tThisFlip = win.getFutureFlipTime(clock=routineTimer)
        tThisFlipGlobal = win.getFutureFlipTime(clock=None)
        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
        
        # *slider_23* updates
        
        # if slider_23 is starting this frame...
        if slider_23.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
            # keep track of start time/frame for later
            slider_23.frameNStart = frameN  # exact frame index
            slider_23.tStart = t  # local t and not account for scr refresh
            slider_23.tStartRefresh = tThisFlipGlobal  # on global time
            win.timeOnFlip(slider_23, 'tStartRefresh')  # time at next scr refresh
            # add timestamp to datafile
            thisExp.timestampOnFlip(win, 'slider_23.started')
            # update status
            slider_23.status = STARTED
            slider_23.setAutoDraw(True)
        
        # if slider_23 is active this frame...
        if slider_23.status == STARTED:
            # update params
            pass
        
        # Check slider_23 for response to end Routine
        if slider_23.getRating() is not None and slider_23.status == STARTED:
            continueRoutine = False
        
        # *text_54* updates
        
        # if text_54 is starting this frame...
        if text_54.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
            # keep track of start time/frame for later
            text_54.frameNStart = frameN  # exact frame index
            text_54.tStart = t  # local t and not account for scr refresh
            text_54.tStartRefresh = tThisFlipGlobal  # on global time
            win.timeOnFlip(text_54, 'tStartRefresh')  # time at next scr refresh
            # add timestamp to datafile
            thisExp.timestampOnFlip(win, 'text_54.started')
            # update status
            text_54.status = STARTED
            text_54.setAutoDraw(True)
        
        # if text_54 is active this frame...
        if text_54.status == STARTED:
            # update params
            pass
        
        # check for quit (typically the Esc key)
        if defaultKeyboard.getKeys(keyList=["escape"]):
            thisExp.status = FINISHED
        if thisExp.status == FINISHED or endExpNow:
            endExperiment(thisExp, win=win)
            return
        # pause experiment here if requested
        if thisExp.status == PAUSED:
            pauseExperiment(
                thisExp=thisExp, 
                win=win, 
                timers=[routineTimer], 
                playbackComponents=[]
            )
            # skip the frame we paused on
            continue
        
        # check if all components have finished
        if not continueRoutine:  # a component has requested a forced-end of Routine
            real_ratings.forceEnded = routineForceEnded = True
            break
        continueRoutine = False  # will revert to True if at least one component still running
        for thisComponent in real_ratings.components:
            if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                continueRoutine = True
                break  # at least one component has not yet finished
        
        # refresh the screen
        if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
            win.flip()
    
    # --- Ending Routine "real_ratings" ---
    for thisComponent in real_ratings.components:
        if hasattr(thisComponent, "setAutoDraw"):
            thisComponent.setAutoDraw(False)
    # store stop times for real_ratings
    real_ratings.tStop = globalClock.getTime(format='float')
    real_ratings.tStopRefresh = tThisFlipGlobal
    thisExp.addData('real_ratings.stopped', real_ratings.tStop)
    trials.addData('slider_23.response', slider_23.getRating())
    trials.addData('slider_23.rt', slider_23.getRT())
    # the Routine "real_ratings" was not non-slip safe, so reset the non-slip timer
    routineTimer.reset()
    thisExp.nextEntry()

I am a little clueless on how to do this
I understand we need to add a code segment on psychopy by copying relevant variables and working on it.
Can you give me an idea how to proceed

Depends a bit on which specific EEG system you’re using. This looks like a builder study, so if you open the PsychoPy builder there are components for both serial port and parallel port EEG outputs. You can add one and then make the “start signal” a variable, and define the variable in a code component depending on which image is displayed.

You can also search for the EEG brand on this forum (e.g., EGI, Brainvision, whatever you’re using) and you’ll probably find something useful.

The output is parallel.
We use an EEG from Brainvision and the system itself is called actiCAP.
It does look like a builder study.
Can you give an example of your idea i am very new to this and completely clueless.

So you start with one of these: Parallel Port Out Component — PsychoPy v2024.2.4

Getting that set up might require a bit of trial and error for your specific system, but basically you just add this component to the trial where you want to send the signal to the EEG system.

In the “Start data” field of the component, you want to put $ followed by a variable name, e.g., $stimcode

Then create a code component in the same routine. It looks like the heart vs. sound is determined by image_instruction. In the “Begin routine” part of your code component, you should be able to put something like:

if image_instruction == "heart.png": # or whatever the image file is actually called
    stimcode = 1
else:
    stimcode = 2

Then, when the parallel port component actually triggers it will send “1” for the heart and “2” for the other option.

That’s the basic idea at least. I’m not sure if this is exactly what you need, but the bottom line is that you use a variable in the parallel port component’s start signal, and set the value of that variable based on which image is presented using a code component.

Hi thanks for the reply i think i understood…
So right now in my builder i have three inputs… text_53 which shows a ±

sound_24 which has input as brown_noise in option sound
and image which has input as image_instruction in option image

duration is from 0 to $isi_time in the builder…same for sound and image.
So if i make a parallel port i did like you suggested…the duration i am keeping like its for other variables…
But what should i keep for stop_data here?i assume u meant to keep start_data as stimcode in your example…
What i am aiming for is that i need a code in the loop corresponding to the this block to tell me if the input is a sound or image.I have a picture attached.
Also where do i make this code component?Should it beginning of routine?

Also seeing my inputs are brown_noise and image_instruction how do i make the condition?
Is it going to be like
if sound =“brown_noise”
stimcode = 1
else if image == " image_instruction"
stimcode = 2


How will this tell the eeg system the heart symbol or sound symbol is gettin displayed?

would be great if you can clarify this

Start_data sends a code to mark the beginning of a time period in your data, stop_data is just another code sent at the end at the period. Usually your stop_data is just “0”. So, if you set the duration of the parallel port component to be the same as your other stimuli, in the EEG data, it will have whatever you put for stimcode as an event flag while the stimulus is present, and “0” when the stimulus stops.

You just put the code component in the routine. It doesn’t have timing like the other components. When you open the code component there are several tabs that say “Before Experiment”, “Begin Experiment”, “Before Routine”, “Each Frame”, “End Routine”, and “End Experiment”. You will want to put the code I described in the “Before Routine” tab so that it runs at the very start of the trial before things are actually presented on the screen.

So on any given trial you have either the sound or the image? What does the conditions file you are using for the loop look like?

If you are using a condition file anyway, you could just put a column called “stimcode” in the condition file with values of 1 and 2 for their respective lines in the condition file, and avoid using the code component altogether.

Alternately you could do something like this in your code component.

if sound_24.sound == "Brownnoise2.flac": # Or whatever the filename is
    stimcode = 1
else:
    stimcode = 2

The bottom line is that whatever you are using in the loop to control which option is presented can also be used to control what code is sent, whether you put it in the condition file directly or use a code component.

thanks for the clarificiation.
i looked at the code again
I think this portion is the part relevant to the code blocks

    trials = data.TrialHandler2(
        name='trials',
        nReps=1.0, 
        method='sequential', 
        extraInfo=expInfo, 
        originPath=-1, 
        trialList=data.importConditions('attention_task_randomization_v2.xlsx'), 
        seed=None, 
    )
    thisExp.addLoop(trials)  # add the loop to the experiment
    thisTrial = trials.trialList[0]  # so we can initialise stimuli with some values
    # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
    if thisTrial != None:
        for paramName in thisTrial:
            globals()[paramName] = thisTrial[paramName]
    if thisSession is not None:
        # if running in a Session with a Liaison client, send data up to now
        thisSession.sendExperimentData()
    
    for thisTrial in trials:
        currentLoop = trials
        thisExp.timestampOnFlip(win, 'thisRow.t', format=globalClock.format)
        if thisSession is not None:
            # if running in a Session with a Liaison client, send data up to now
            thisSession.sendExperimentData()
        # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
        if thisTrial != None:
            for paramName in thisTrial:
                globals()[paramName] = thisTrial[paramName]
        
        # --- Prepare to start Routine "real_trials" ---
        # create an object to store info about Routine real_trials
        real_trials = data.Routine(
            name='real_trials',
            components=[text_53, sound_24, image],
        )
        real_trials.status = NOT_STARTED
        continueRoutine = True
        # update component parameters for each repeat
        sound_24.setSound('Brownnoise2.flac', secs=20, hamming=True)
        sound_24.setVolume(1.0, log=False)
        sound_24.seek(0)
        image.setImage(image_instruction)
        # store start times for real_trials
        real_trials.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
        real_trials.tStart = globalClock.getTime(format='float')
        real_trials.status = STARTED
        thisExp.addData('real_trials.started', real_trials.tStart)
        real_trials.maxDuration = None
        # keep track of which components have finished
        real_trialsComponents = real_trials.components
        for thisComponent in real_trials.components:
            thisComponent.tStart = None
            thisComponent.tStop = None
            thisComponent.tStartRefresh = None
            thisComponent.tStopRefresh = None
            if hasattr(thisComponent, 'status'):
                thisComponent.status = NOT_STARTED
        # reset timers
        t = 0
        _timeToFirstFrame = win.getFutureFlipTime(clock="now")
        frameN = -1
        
        # --- Run Routine "real_trials" ---
        # if trial has changed, end Routine now
        if isinstance(trials, data.TrialHandler2) and thisTrial.thisN != trials.thisTrial.thisN:
            continueRoutine = False
        real_trials.forceEnded = routineForceEnded = not continueRoutine
        while continueRoutine:
            # get current time
            t = routineTimer.getTime()
            tThisFlip = win.getFutureFlipTime(clock=routineTimer)
            tThisFlipGlobal = win.getFutureFlipTime(clock=None)
            frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
            # update/draw components on each frame
            
            # *text_53* updates
            
            # if text_53 is starting this frame...
            if text_53.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
                # keep track of start time/frame for later
                text_53.frameNStart = frameN  # exact frame index
                text_53.tStart = t  # local t and not account for scr refresh
                text_53.tStartRefresh = tThisFlipGlobal  # on global time
                win.timeOnFlip(text_53, 'tStartRefresh')  # time at next scr refresh
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'text_53.started')
                # update status
                text_53.status = STARTED
                text_53.setAutoDraw(True)
            
            # if text_53 is active this frame...
            if text_53.status == STARTED:
                # update params
                pass
            
            # if text_53 is stopping this frame...
            if text_53.status == STARTED:
                # is it time to stop? (based on global clock, using actual start)
                if tThisFlipGlobal > text_53.tStartRefresh + isi_time-frameTolerance:
                    # keep track of stop time/frame for later
                    text_53.tStop = t  # not accounting for scr refresh
                    text_53.tStopRefresh = tThisFlipGlobal  # on global time
                    text_53.frameNStop = frameN  # exact frame index
                    # add timestamp to datafile
                    thisExp.timestampOnFlip(win, 'text_53.stopped')
                    # update status
                    text_53.status = FINISHED
                    text_53.setAutoDraw(False)
            
            # *sound_24* updates
            
            # if sound_24 is starting this frame...
            if sound_24.status == NOT_STARTED and tThisFlip >= isi_time-frameTolerance:
                # keep track of start time/frame for later
                sound_24.frameNStart = frameN  # exact frame index
                sound_24.tStart = t  # local t and not account for scr refresh
                sound_24.tStartRefresh = tThisFlipGlobal  # on global time
                # add timestamp to datafile
                thisExp.addData('sound_24.started', tThisFlipGlobal)
                # update status
                sound_24.status = STARTED
                sound_24.play(when=win)  # sync with win flip
            
            # if sound_24 is stopping this frame...
            if sound_24.status == STARTED:
                # is it time to stop? (based on global clock, using actual start)
                if tThisFlipGlobal > sound_24.tStartRefresh + 20-frameTolerance or sound_24.isFinished:
                    # keep track of stop time/frame for later
                    sound_24.tStop = t  # not accounting for scr refresh
                    sound_24.tStopRefresh = tThisFlipGlobal  # on global time
                    sound_24.frameNStop = frameN  # exact frame index
                    # add timestamp to datafile
                    thisExp.timestampOnFlip(win, 'sound_24.stopped')
                    # update status
                    sound_24.status = FINISHED
                    sound_24.stop()
            
            # *image* updates
            
            # if image is starting this frame...
            if image.status == NOT_STARTED and tThisFlip >= isi_time-frameTolerance:
                # keep track of start time/frame for later
                image.frameNStart = frameN  # exact frame index
                image.tStart = t  # local t and not account for scr refresh
                image.tStartRefresh = tThisFlipGlobal  # on global time
                win.timeOnFlip(image, 'tStartRefresh')  # time at next scr refresh
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'image.started')
                # update status
                image.status = STARTED
                image.setAutoDraw(True)
            
            # if image is active this frame...
            if image.status == STARTED:
                # update params
                pass
            
            # if image is stopping this frame...
            if image.status == STARTED:
                # is it time to stop? (based on global clock, using actual start)
                if tThisFlipGlobal > image.tStartRefresh + 20-frameTolerance:
                    # keep track of stop time/frame for later
                    image.tStop = t  # not accounting for scr refresh
                    image.tStopRefresh = tThisFlipGlobal  # on global time
                    image.frameNStop = frameN  # exact frame index
                    # add timestamp to datafile
                    thisExp.timestampOnFlip(win, 'image.stopped')
                    # update status
                    image.status = FINISHED
                    image.setAutoDraw(False)
            
            # check for quit (typically the Esc key)
            if defaultKeyboard.getKeys(keyList=["escape"]):
                thisExp.status = FINISHED
            if thisExp.status == FINISHED or endExpNow:
                endExperiment(thisExp, win=win)
                return
            # pause experiment here if requested
            if thisExp.status == PAUSED:
                pauseExperiment(
                    thisExp=thisExp, 
                    win=win, 
                    timers=[routineTimer], 
                    playbackComponents=[sound_24]
                )
                # skip the frame we paused on
                continue
            
            # check if all components have finished
            if not continueRoutine:  # a component has requested a forced-end of Routine
                real_trials.forceEnded = routineForceEnded = True
                break
            continueRoutine = False  # will revert to True if at least one component still running
            for thisComponent in real_trials.components:
                if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                    continueRoutine = True
                    break  # at least one component has not yet finished
            
            # refresh the screen
            if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
                win.flip()
        
        # --- Ending Routine "real_trials" ---
        for thisComponent in real_trials.components:
            if hasattr(thisComponent, "setAutoDraw"):
                thisComponent.setAutoDraw(False)
        # store stop times for real_trials
        real_trials.tStop = globalClock.getTime(format='float')
        real_trials.tStopRefresh = tThisFlipGlobal
        thisExp.addData('real_trials.stopped', real_trials.tStop)
        sound_24.pause()  # ensure sound has stopped at end of Routine
        # the Routine "real_trials" was not non-slip safe, so reset the non-slip timer
        routineTimer.reset()
        
        # --- Prepare to start Routine "real_ratings" ---
        # create an object to store info about Routine real_ratings
        real_ratings = data.Routine(
            name='real_ratings',
            components=[slider_23, text_54],
        )
        real_ratings.status = NOT_STARTED
        continueRoutine = True
        # update component parameters for each repeat
        slider_23.reset()
        text_54.setText(questions_ratings)
        # store start times for real_ratings
        real_ratings.tStartRefresh = win.getFutureFlipTime(clock=globalClock)
        real_ratings.tStart = globalClock.getTime(format='float')
        real_ratings.status = STARTED
        thisExp.addData('real_ratings.started', real_ratings.tStart)
        real_ratings.maxDuration = None
        # keep track of which components have finished
        real_ratingsComponents = real_ratings.components
        for thisComponent in real_ratings.components:
            thisComponent.tStart = None
            thisComponent.tStop = None
            thisComponent.tStartRefresh = None
            thisComponent.tStopRefresh = None
            if hasattr(thisComponent, 'status'):
                thisComponent.status = NOT_STARTED
        # reset timers
        t = 0
        _timeToFirstFrame = win.getFutureFlipTime(clock="now")
        frameN = -1
        
        # --- Run Routine "real_ratings" ---
        # if trial has changed, end Routine now
        if isinstance(trials, data.TrialHandler2) and thisTrial.thisN != trials.thisTrial.thisN:
            continueRoutine = False
        real_ratings.forceEnded = routineForceEnded = not continueRoutine
        while continueRoutine:
            # get current time
            t = routineTimer.getTime()
            tThisFlip = win.getFutureFlipTime(clock=routineTimer)
            tThisFlipGlobal = win.getFutureFlipTime(clock=None)
            frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
            # update/draw components on each frame
            
            # *slider_23* updates
            
            # if slider_23 is starting this frame...
            if slider_23.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
                # keep track of start time/frame for later
                slider_23.frameNStart = frameN  # exact frame index
                slider_23.tStart = t  # local t and not account for scr refresh
                slider_23.tStartRefresh = tThisFlipGlobal  # on global time
                win.timeOnFlip(slider_23, 'tStartRefresh')  # time at next scr refresh
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'slider_23.started')
                # update status
                slider_23.status = STARTED
                slider_23.setAutoDraw(True)
            
            # if slider_23 is active this frame...
            if slider_23.status == STARTED:
                # update params
                pass
            
            # Check slider_23 for response to end Routine
            if slider_23.getRating() is not None and slider_23.status == STARTED:
                continueRoutine = False
            
            # *text_54* updates
            
            # if text_54 is starting this frame...
            if text_54.status == NOT_STARTED and tThisFlip >= 0.0-frameTolerance:
                # keep track of start time/frame for later
                text_54.frameNStart = frameN  # exact frame index
                text_54.tStart = t  # local t and not account for scr refresh
                text_54.tStartRefresh = tThisFlipGlobal  # on global time
                win.timeOnFlip(text_54, 'tStartRefresh')  # time at next scr refresh
                # add timestamp to datafile
                thisExp.timestampOnFlip(win, 'text_54.started')
                # update status
                text_54.status = STARTED
                text_54.setAutoDraw(True)
            
            # if text_54 is active this frame...
            if text_54.status == STARTED:
                # update params
                pass
            
            # check for quit (typically the Esc key)
            if defaultKeyboard.getKeys(keyList=["escape"]):
                thisExp.status = FINISHED
            if thisExp.status == FINISHED or endExpNow:
                endExperiment(thisExp, win=win)
                return
            # pause experiment here if requested
            if thisExp.status == PAUSED:
                pauseExperiment(
                    thisExp=thisExp, 
                    win=win, 
                    timers=[routineTimer], 
                    playbackComponents=[]
                )
                # skip the frame we paused on
                continue
            
            # check if all components have finished
            if not continueRoutine:  # a component has requested a forced-end of Routine
                real_ratings.forceEnded = routineForceEnded = True
                break
            continueRoutine = False  # will revert to True if at least one component still running
            for thisComponent in real_ratings.components:
                if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
                    continueRoutine = True
                    break  # at least one component has not yet finished
            
            # refresh the screen
            if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
                win.flip()
        
        # --- Ending Routine "real_ratings" ---
        for thisComponent in real_ratings.components:
            if hasattr(thisComponent, "setAutoDraw"):
                thisComponent.setAutoDraw(False)
        # store stop times for real_ratings
        real_ratings.tStop = globalClock.getTime(format='float')
        real_ratings.tStopRefresh = tThisFlipGlobal
        thisExp.addData('real_ratings.stopped', real_ratings.tStop)
        trials.addData('slider_23.response', slider_23.getRating())
        trials.addData('slider_23.rt', slider_23.getRT())
        # the Routine "real_ratings" was not non-slip safe, so reset the non-slip timer
        routineTimer.reset()
        thisExp.nextEntry()
        

So there is an excel file where there is a column image_instruction which stores either heart.png or sound.png file.
i think its getting stored in the variable trial list if i understood it correctly.
Would it be feasible to do the condition based on this?
i couldnt pinpoint exactly where what to do

I think the easy solution is to do this all in the condition file. You won’t need a code component at all.

Your condition file currently has a column called “image_instruction” with two rows, “heart.png” and “sound.png”. In the same file, you just create a new column next to it called “stimcode” with two rows, 1 and 2.

In the parallel component, you just put stimcode (no quotes or symbols) in the “start_signal” box and 0 in the “stop_signal” box.

Now, it should just automatically make it so that it sends a signal 1 when heart.png is presented and 2 when sound.png is presented, and these will be recorded in your EEG data as event codes.

Hi
I tried this approach
But this is not working for the moment
i get some errors
p_port = parallel.ParallelPort(address=‘0x0378’)
TypeError: ‘NoneType’ object is not callable
4.4996 WARNING psychopy.parallel has been imported but no parallel port driver found. Install either inpout32, inpoutx64 or dlportio
9.9351 WARNING launchHubServer: If using the iohub mouse or eyetracker devices, fullScr should be True.
13.9843 DEPRECATION No speaker device found with index 8
2.9152 WARNING Monitor specification not found. Creating a temporary one…
ioHub Server Process Completed With Code: 0
################ Experiment ended with exit code 1 [pid:16536] #################

Do i need eeg connection here?

Yeah, you’ll need to actually be connected to the system for this to work. If the parallel port isn’t connected or the address is wrong this is the error you’ll get. Unfortunately this is the part that is very specific to each individual system, so I can’t be of much help.

alright
I try this out with the system later.Thanks for the help anyways.

Hi there
Tried to do this with eeg system.
The error now is that no port is detected. With the parallel port, it seems that the code has to go to the “correct number (corresponding to 1, 2, …,9).Any idea on how to locate this?

Sorry, missed this reply. Afraid not, this is really system-by-system. You might be able to find the information from the hardware manager (on windows) and looking at the properties for the parallel ports.

Thats ok no worries.
My code is now working, but unfortunately the first trigger is not sent
through the parallel port, the later triggers all arrive at BrainVision.

If I insert a parallel port component at the beginning of the task,
which simply sends a random trigger, then both this (random) trigger and
the later first trigger, which does not work (without the random
parallel port component), arrive.

Any idea how can i fix this?
Is there a code i can do to see if all pins work?

You’re not the only one to have this problem, from the post below, but unfortunately I don’t see a solution. It might have to do with frame skips, or that the signal is sent for too short a time. There’s a “sync timing to screen refresh” option in the parallel port component, you could see if checking that helps.

The only way I can think of testing each individual pin is to make a dummy experiment that tries sending a signal from each pin in sequence.

How would the dummy experiment be made?I will check the other options as well

Make a completely new experiment in PsychoPy that is just the parts you want to test, basically. You can make an experiment with only a couple of trials and put in a bunch of parallel port events at different times in those trials, hook it into the system, and see how it works.