Record string response from keyboard and use Enter key to continue loop

Thank you for your help @dvbridges. I tried using your code and now the issue is that the routine is stuck on the first image presented. Regardless of whether I enter other keys before pressing the Enter key, the first image remains on the screen and no feedback is presented.

Following is how I replaced some of my codes with yours. I totally get your logic and I am surprised why I don’t get the desired output:

# set up handler to look after randomisation of conditions etc
prac_tr = data.TrialHandler(nReps=1, method='sequential', 
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions('prac_trials.csv'),
seed=None, name='prac_tr')
thisExp.addLoop(prac_tr)  # add the loop to the experiment
thisPrac_tr = prac_tr.trialList[0]  # so we can initialise stimuli with some values
# abbreviate parameter names if possible (e.g. rgb = thisPrac_tr.rgb)
if thisPrac_tr != None:
for paramName in thisPrac_tr:
    exec('{} = thisPrac_tr[paramName]'.format(paramName))

for thisPrac_tr in prac_tr:
currentLoop = prac_tr
# abbreviate parameter names if possible (e.g. rgb = thisPrac_tr.rgb)
if thisPrac_tr != None:
    for paramName in thisPrac_tr:
        exec('{} = thisPrac_tr[paramName]'.format(paramName))

# ------Prepare to start Routine "prac"-------
t = 0
pracClock.reset()  # clock
frameN = -1
continueRoutine = True
# update component parameters for each repeat
prac_faces.setOpacity(1)
prac_faces.setPos((0, 0))
prac_faces.setSize((1, 1))
prac_faces.setOri(0)
prac_faces.setImage(fix_face)
resp = event.BuilderKeyResponse()
drawFeedback = []
feedbackTextStart = 0
tooSoon = False
tooLate = False
# keep track of which components have finished
pracComponents = [prac_faces, prac_text, resp]
for thisComponent in pracComponents:
    if hasattr(thisComponent, 'status'):
        thisComponent.status = NOT_STARTED

# -------Start Routine "prac"-------
while continueRoutine:
    # get current time
    t = pracClock.getTime()
    frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
    # update/draw components on each frame
    
    # *prac_faces* updates
    if t >= 0.0 and prac_faces.status == NOT_STARTED:
        # keep track of start time/frame for later
        prac_faces.tStart = t
        prac_faces.frameNStart = frameN  # exact frame index
        prac_faces.setAutoDraw(True)
    if prac_faces.status == STARTED and bool(resp.status == STOPPED):
        prac_faces.setAutoDraw(False)
    
    # *prac_text* updates
    if t >= 2 and prac_text.status == NOT_STARTED:
        # keep track of start time/frame for later
        prac_text.tStart = t
        prac_text.frameNStart = frameN  # exact frame index
        prac_text.setAutoDraw(True)
    if prac_text.status == STARTED and bool(resp.status == STOPPED):
        prac_text.setAutoDraw(False)
    
    # *resp* updates
    if t >= 0 and resp.status == NOT_STARTED:
        # keep track of start time/frame for later
        resp.tStart = t
        resp.frameNStart = frameN  # exact frame index
        resp.status = STARTED
        # keyboard checking is just starting
        win.callOnFlip(resp.clock.reset)  # t=0 on next screen flip
    if resp.status == STARTED:
        theseKeys = event.getKeys(keyList=['q', 'w', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'z', 'x', 'c', 'v', 'b', 'n', 'm', 'return'])
        
        # check for quit:
        if "escape" in theseKeys:
            endExpNow = True
    if resp.keys:
            # Scenerio 1
        if resp.keys[0] == 'return':
            resp.keys, resp.rt = [], []  # reset key presses and rts
        if len(resp.keys) > 1:
            # Scenerio 2 
            if resp.keys[1] == 'return' and t <=.5 and not drawFeedback:
                feedbackText.setText("You must wait until stim appears")
                feedbackText.setColor(u'red', colorSpace='rgb')
                drawFeedback.append(True)
                feedbackTextStart = t + 2  # Set time for feedback
                tooSoon = True
                resp.keys, resp.rt = [], [] # reset key presses and rts
            # Scenerio 3
            elif resp.keys[-1] == 'return' and t >= 6 and not drawFeedback:
                feedbackText.setText("Please respond faster")
                feedbackText.setColor(u'red', colorSpace='rgb')
                drawFeedback.append(True)
                feedbackTextStart = t + 2
                tooLate = True
            # Scenario - everything fine and end routine
            elif resp.keys[-1] == 'return' and not np.any([tooSoon, tooLate]):
                continueRoutine = False
    # After feedback drawn for 2 seconds
    if feedbackTextStart != 0 and True in drawFeedback:
        if t >= feedbackTextStart:
            feedbackText.setText("")
            # If too soon, carry on and allow more responses
            tooSoon = False
            # End routine if received response but took too long
            if tooLate == True:
                continueRoutine = False
    
    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in pracComponents:
        if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
            continueRoutine = True
            break  # at least one component has not yet finished
    
    # check for quit (the Esc key)
    if endExpNow or event.getKeys(keyList=["escape"]):
        core.quit()
    
    # refresh the screen
    if continueRoutine:  # don't flip if this routine is over or we'll get a blank screen
        win.flip()

# -------Ending Routine "prac"-------
for thisComponent in pracComponents:
    if hasattr(thisComponent, "setAutoDraw"):
        thisComponent.setAutoDraw(False)
# check responses
if resp.keys in ['', [], None]:  # No response was made
    resp.keys=None
prac_tr.addData('resp.keys',resp.keys)
if resp.keys != None:  # we had a response
    prac_tr.addData('resp.rt', resp.rt)
# the Routine "prac" was not non-slip safe, so reset the non-slip timer
routineTimer.reset()
thisExp.nextEntry()

I hope I made the changes appropriately. Also not mentioned in my initial post, there is a 500 ms interval between the end of one trial and the beginning of another. If continueRoutine = False based on the keyboard response then I am not sure how to incorporate the 500 ms interval.

Hope this issue is not too complicated to solve!

Mo