Sending triggers: how to best invoke them?

Brandon Cernicky brandon_cernicky at yahoo.com
Tue Oct 3 12:41:17 UTC 2006


Hi J. Scott / Fabrizio,

In E-Prime 1.x, the best way to achieve accurate port
signaling at the onset/offset should use the
.OnetSignal or OffsetSignal properties.  Use of
WritePort should only be done in the cases where
required.  For the Onset of an object this is critical
since performing a WritePort just prior to the object
will not be accurate of the onset since the object
will delay to wait for the vertical blank.

Any time custom logging, port signaling, or multiple
responses is necessary, the following should be setup:

1)	The object should have a zero duration.  This will
allow it to immediately be processed by the processing
InLine
2)	A device input mask that has an extended input
(time limit) needs to be setup so that the following
InLine can use IsPending while the responses are being
collected
3)	All input masks MUST have an end response action of
none.  If you set Terminate/Jump, unexpected
termination of the NEXT object will occur.
4)	Set the MaxCount > 0 for multiple responses in
Advanced
5)	Use Stimulus.InputMasks.IsPending in a loop to
determine if responses are still being processed. 
IsPending will return false when the MaxCount,
TerminationResponse, or TimeLimit reach successful
conditions.
6)	Use Stimulus.InputMasks.Responses collection to
determine if any new responses have come in and
process them.
7)	Use Stimulus.InputMasks.Terminate to manually break
out of the loop if a script condition calls for it.

The following script below is the heart Inline in the
ProcessResponsesTemplate.es sample experiment
available from PST.  
PST recommends starting with this template and cutting
out or adding custom actions to this InLine as other
attempts at this skeleton template can either cause
unexpected issues to occur or are non-standard and
typically end up going this route after a number of
iterations.

Note that this is an example, so for your paradigm,
you can cut out the color section.  And you can
determine what value you want to send via the
WritePort call.  You can also determined using a
comparison of theResponseData.RESP = “x” to determine
if a WritePort should be sent or not.  The additional
portions of the script are used to log each response
and can be cut or customized to  your paradigm as
well.

To insert this into your paradigm, create an InLine
and paste the script below.  If the object you wish to
collect responses from is not named Stimulus, then you
only need to change the first line to the appropriate
name of the object in question. Doing the dynamic
lookup like this script does makes your InLine more
portable to other experiments so you don’t have to
search and replace things.

When writing InLine code, you want to avoid directly
accessing an input mask by ordinal (i.e.
Stimulus.InputMasks(1)) because it prohibits
copy/paste amongst experiments where the keyboard
maybe #1 in one experiment and #2 in others.  Using
the more abstract Responses collection and then using
casting/conversion functions such as
CKeyboardResponseData will make your InLine code more
portable.   In addition, always use
Stimulus.InputMasks.IsPending to determine when
response collection is over versus Stimulus.RT <> 0 or
Stimulus.RESP <> “” type of checks.

See Also:

http://www.pstnet.com/e-prime/support/kb.asp?TopicID=2599
(2599 - INFO: E-Basic Style
Guidelines/Recommendations)
http://www.pstnet.com/e-prime/support/kb.asp?TopicID=2575
(2575 - FEATURE: OnsetSignalDataPort and
OffsetSignalDataPort permit wider range of values)
http://www.pstnet.com/e-prime/support/kb.asp?TopicID=1318
(1318 - INFO: How do I notify external equipment at
the exact time that an event occurs in E-Prime?)
http://www.pstnet.com/e-prime/support/kb.asp?TopicID=1320
(1320 - INFO: General Parallel Port Information)

-Brandon

~~~~~~~~~~~~~~~~~~~~~~~~~~
Brandon S. Cernicky
Senior Software Engineer
Psychology Software Tools

===================================================
	
	'Declare a variable that can be assigned to the
stimulus object.
	' This is done to aid when copying this script to
another experiment
	'  where the author would only have to change the
name here instead
	' of search and replace through the rest of the
script.
	Dim theResponseObject As RteRunnableInputObject
	Set theResponseObject =
CRteRunnableInputObject(Rte.GetObject("Stimulus"))

	'NOTE: If this assert fires, then the object named
	' above is not in your experiment
	Debug.Assert Not theResponseObject Is Nothing

	'If the duration is not zero, then this script may
not be processing properly
	If theResponseObject.Duration <> 0 Then Debug.Print
"WARNING: " & theResponseObject.Name & ".Duration is
not zero.  The ProcessResponses InLine may not
function properly!"

	'If the end response action on any of the input masks
is anything but (none), then
	' the script may not behave properly since terminate
would cause the next object after
	' this script to terminate.
	Dim nMask As Long
	For nMask = 1 To theResponseObject.InputMasks.Count		
		Dim theInputMask As InputMask
		Set theInputMask =
theResponseObject.InputMasks(nMask)
		If Not theInputMask Is Nothing Then			
			If theInputMask.EndResponseAction <>
ebEndResponseActionNone Then Debug.Print "WARNING: " &
theResponseObject.Name & " has an input mask with an
end response action that is not (none).  The object
after ProcessResponses InLine may be terminated not as
expected!"
			If theInputMask.MaxCount = 1 Then Debug.Print
"WARNING: " & theResponseObject.Name & " has an input
mask that has a MaxCount=1.  The ProcessResponses
InLine won't handle multiple responses"
			If theInputMask.TimeLimit = 0 Then Debug.Print
"WARNING: " & theResponseObject.Name & " has an input
mask with a zero duration time limit and is
effectively ignored!"
		End If
	Next

	Dim nResponseCount As Long
	Dim theResponseData As ResponseData

	'Loop while there are input pending.  This will
return
	' TRUE so long as the time limit has not elapsed, the
	' max count on the input mask(s) has not been reached
	' ot the termination response has not been accepted.
	While theResponseObject.InputMasks.IsPending()

	   'If the counts don't match, there are responses to
process
		If nResponseCount <>
theResponseObject.InputMasks.Responses.Count Then
      
			'Increment
			nResponseCount = nResponseCount + 1

			Set theResponseData =
theResponseObject.InputMasks.Responses(nResponseCount)
			If Not theResponseData Is Nothing Then

				'''''''''''''''''''''''''''''''''''''''''''''''
				'''''''''''''''''''''''''''''''''''''''''''''''
				' Insert custom action here.  
				' This part will be unique to your experiment.
				'''''''''''''''''''''''''''''''''''''''''''''''
				'''''''''''''''''''''''''''''''''''''''''''''''

				'In this example, we will log each response
				' to the context.  We'll also draw a box
				' that will change color depending on what
				' key was pressed.  We then write a value 
				' to the parallel port indicating the response
value

				'Write a value to the port to let external
equipment
				' know a response came in
				WritePort &H378, theResponseData.Data

				'Log the response to the context
				c.SetAttrib theResponseObject.Name & ".RESP_" &
nResponseCount, theResponseData.RESP
				c.SetAttrib theResponseObject.Name & ".RT_" &
nResponseCount, theResponseData.RT

				'We fill an array of color strings which we'll
choose from randomly
				Dim arrColors(17) As String
				arrColors(0) = "black"
				arrColors(1) = "white"
				arrColors(2) = "red"
				arrColors(3) = "green"
				arrColors(4) = "blue"
				arrColors(5) = "gray"
				arrColors(6) = "cyan"
				arrColors(7) = "magenta"
				arrColors(8) = "yellow"
				arrColors(9) = "maroon"
				arrColors(10) = "olive"
				arrColors(11) = "navy"
				arrColors(12) = "purple"
				arrColors(13) = "teal"
				arrColors(14) = "silver"
				arrColors(15) = "lime"
				arrColors(16) = "fuschia"
				arrColors(17) = "aqua"

				'Create an offscreen canvas
				' Find a random color and fill it				
				Dim theCanvas As Canvas
				Set theCanvas = Display.CreateCanvas
				theCanvas.FillColor =
CColor(arrColors(Random(LBound(arrColors),
UBound(arrColors))))
				theCanvas.Clear

				'Define a rectangle that is middle of screen
				Const BLOCK_SIZE = 50
				Dim rc As Rect
				rc.Left = (Display.XRes / 2) - (BLOCK_SIZE / 2)
				rc.Top = (Display.YRes / 2) - (BLOCK_SIZE / 2)
				rc.Right = rc.Left + BLOCK_SIZE
				rc.Bottom = rc.Top + BLOCK_SIZE

				'Copy the canvas to the display canvas
				Display.WaitForVerticalBlank
				Display.Canvas.Copy theCanvas, rc, rc

				'Cleanup - this is very important to do
				' or video memory resources will get eaten
				Set theCanvas = Nothing


				'''''''''''''''''''''''''''''''''''''''''''''''
				'''''''''''''''''''''''''''''''''''''''''''''''
				'
				'''''''''''''''''''''''''''''''''''''''''''''''
				'''''''''''''''''''''''''''''''''''''''''''''''


	      End If

	   End If

	   'Give some time back (required)
	   Sleep 10
	   DoEvents

	Wend


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



More information about the Eprime mailing list