Hi community,
I recently acquired a simple button box (blackbox toolkit, 1000hz sampling) that can be easily interfaced using the new psychopy’s keyboard component linked to the USB HID library. The button box contains two buttons, detected as ‘1’ and ‘2’ by keyboard.getKeys() respectively. So far, so good.
Here is the issue. I am planning to record the EMG activity of response muscles in a random dot motion experiment, so I need to send a trigger synchronized to the button press. Of course I could do that in my psychopy loop (see code below), but I would loose some temporal resolution (the trigger would be tethered to the refresh rate, and would not reflect the time at which the button was pressed). My question is thus very simple, but probably hard to solve. Is there a way I could easily modify the code below to send a trigger synchronized with the button press ? Of course I could use a thread to monitor my button box, or the iohub module, but I’d prefer using the (much simpler) keyboard component.
All the best
from psychopy import core, data, event, visual, gui
import numpy as np
import os
from pathlib import Path
from psychopy.hardware import keyboard
import serial
port = serial.Serial("COM3",baudrate =115200)
#######################Parameters for RDK stimuli
framerate = 60.0
speed_deg_sec =8.#8.0 #in degrees/s 12 in Pilly in Seitz
dot_density = 16.7#in deg-2 s-1
rayon_cercle = 9.0#in deg
number_of_dots = int(np.round(dot_density * np.pi * np.square(rayon_cercle) * (1/framerate)))
#######################
expName="RDK_SAT_task"
expInfo={'participant':''}
expName='RDK_task'
expInfo={'participant':''}
dlg=gui.DlgFromDict(dictionary=expInfo,title=expName)
if dlg.OK==False: core.quit() #user pressed cancel
win = visual.Window(fullscr=True, monitor='mathieu',size=(1920, 1080), color=[0,0,0], colorSpace='rgb255', units='deg')
police = 'Consolas'
win.setMouseVisible(False)
# initialize keyboards
resp = keyboard.Keyboard()
defaultKeyboard = keyboard.Keyboard()#for escaping only
dots=visual.DotStim(win=win, name='random_dots',
nDots= number_of_dots,
dotSize=4,
units = 'deg',
speed= speed_deg_sec/framerate,
dir= 0,
coherence= 0.0,
fieldPos=[0.0, 0.0],
fieldSize=rayon_cercle*2,
fieldShape='circle',
signalDots='different',
noiseDots='position',
dotLife= -1,
color=[255,255,255], colorSpace='rgb255')
kb_delay=0
dots.setFieldCoherence(0.2)
dots.setDir(0)#0 (right) or 180 (left)
win.callOnFlip(resp.clock.reset)
win.callOnFlip(port.write,b'1')#trigger for stimulus onset
win.callOnFlip(resp.clearEvents, eventType='keyboard')
while True:
if kb_delay==1:#check keyboard buffer AFTER first draw of stimulus and clock reset
theseKeys = resp.getKeys(keyList=['1','2'], waitRelease=False)
if len(theseKeys):
theseKeys = theseKeys[0]
if theseKeys.name == '1':#left button press
port.write(b'2')#trigger for left response
if theseKeys.name == '2':#right button press
port.write(b'3')#trigger for right response
break
if defaultKeyboard.getKeys(keyList=["escape"], waitRelease=False):
core.quit()
dots.draw()
win.flip()
if kb_delay == 0:
kb_delay = 1
core.quit()