psychopy.org | Reference | Downloads | Github

Weird output when recording key durations online

URL of experiment: https://gitlab.pavlovia.org/CWoodrow/student_computer_experiment_v1

This is an unfinished experiment that I am just using to test the key duration code.
(Also, apologies for a messy GitLab - the file in question is ‘StudentExperiment_wordsX2_v6’).

Description of the problem: In my experiment, participants see a word on the screen, followed by a prompt (‘Type!’), after which they need to type this word. This happens twice for each word (i.e. participants type each word twice). The first time participants type I am recording the key presses and RTs using a keyboard component, which all works as intended.

The second time the word is typed, I have some code which intends to record the key press time relative to the key before, i.e., when a key is pressed the clock resets so that the next key press time is relative to the press before it, giving me inter-key-interval times rather than absolute RTs. Importantly, the code also records a key lift time, which is relative to the press (because the clock reset after every key press), which then works as a key duration (time the key was held down).

I got this working as planned in PsychoPy but in Pavlovia the output is not as expected. I only want a key duration and press time for each key pressed (~6 keys as participants type 6-letter words), but I am getting heaps of different values instead. It looks like this could be because the code is updating every frame, but all of the values in the .xlsx file also seem to be different (rather than a few the same as would be expected if it was updating a key press time every frame for the same key press).

Here is what the output looks like from Pavlovia:

Here is the JS code I have in my component:

Begin routine

taskClock = new util.Clock();

mykb = new core.Keyboard({psychoJS: psychoJS, clock: new util.Clock(), waitForStart: true});
mykb.start();
keysWatched = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p",
"q","r","s","t","u","v","w","x","y","z","backspace","enter","space",",",
".","/", "backslash", "'",";","[","]","1","2","3","4","5","6","7","8","9","0",
"shift", "capslock", "tab","control", "alt", "`", "-", "=", "meta", "contextmenu",
"delete", "#", "arrowleft", "arrowright", "arrowup", "arrowdown", "insert",
"printscreen", "home", "end", "pagedown", "pageup", "pause"];
status = ["up", "up", "up", "up", "up", 
"up","up","up","up","up","up","up","up","up","up","up","up","up","up","up","up",
"up","up","up","up","up","up","up","up","up","up","up","up","up","up","up","up",
"up","up","up","up","up","up","up","up","up","up","up","up","up","up","up","up",
"up","up","up","up","up","up","up","up","up","up","up","up","up","up","up","up",
"up"];
keyCount = 0;
currentKey = 0;
statusList = [];
pressTime = 0;
keyPressTime = [];
liftTime = 0;
keyDur=[];
key_list=[];

Each frame

// Loop through keyboard events to update keyStates
let keyEvents = mykb.getEvents();
// Get keys?
let keys1 = mykb.getKeys({keyList: keysWatched, waitRelease: false, clear: false});
key_list = key_list.concat(keys1);
// Previous status of key we are currently watching
let previousStatus = status[currentKey];
// Key, timestamp, and keyDown, of current key event
let keyIndex, key, keyStatus;
for (let i = 0; i < keyEvents.length; i++) {
    // Current key event
    key = keyEvents[i].pigletKey;
    keyStatus = keyEvents[i].status === Symbol.for('KEY_DOWN')? 'down': 'up';
    // Index of this key in keysWatched. NB findIndex not supported by IE
    keyIndex = keysWatched.indexOf(key);
    // Key is one that we watch; update its status
    if (keyIndex !== -1) {
        status[keyIndex] = keyStatus
        statusList.append(keyStatus)
        console.log('keyStatus')
        console.log(statusList)
    }
}
if ((statusList.length > 1)) {
    if ((statusList.slice((- 1))[0] !== statusList.slice((- 2))[0])) {
        if ((statusList.slice((- 1))[0] === "down")) {
            pressTime = taskClock.getTime() * 1000
            keyPressTime.append(pressTime)
            taskClock.reset()
        } else {
            if ((statusList.slice((- 1))[0] === "up")) {
                liftTime = taskClock.getTime() * 1000
                keyDur.append(liftTime)
                taskClock.reset()
            }
        }
    }
} else {
    if ((statusList.length == 1)) {
        pressTime = taskClock.getTime() * 1000
        keyPressTime.append(pressTime)
        taskClock.reset()
    }
}

End routine

thisExp.addData("keyPressTime", keyPressTime);
thisExp.addData("keyDuration", keyDur);
thisExp.addData("statusList", statusList);

I do also have the recommended JS only code component in the first routine of my experiment with the following inside:

Begin experiment

thisExp=psychoJS.experiment;
win=psychoJS.window;
event=psychoJS.eventManager;
shuffle = util.shuffle;
Array.prototype.append = [].push;

Any ideas as to why this might be happening would be much appreciated! I’m new to JavaScript and struggling to figure out what could be amiss in the code.

While I don’t have an answer to why your code isn’t working, I do know that other topics about registering the duration of keypresses have come by on the forum, maybe this post could help? Logging duration of keypress to end routine - #6 by DavidBrocker