Hello,
In a simple experiment I turn the monitor on (whole screen white) for one frame (refresh rate:60Hz) and then off for one frame (whole screen black) and repeat this over and over. Simultaneously I measure the luminance of the top left corner of the screen with a photodiode and record its analog signal. When I look at the results the changes in the luminance and the photodiode signal are synchronized at the beginning, but they don’t match at the end of the experiment so it seems that there are some timing issues. However, when I check the vbl times the length of the frames seem to be right and no missed frame is reported. I need to have precise timings and I am wondering why this happens.
My setup: My graphics card is an AMD Radeon RX 5700 XT. I run Psychtoolbox-3 on MATLAB2020b and my OS is Ubuntu 20.04.1. I am also using a Bits# to generate a trigger and synchronize stimulus presentation with data acquisition system. So my stimulus presentation happens through the Bits#.
I have tried different monitors, different refresh rates, and also without using the Bits, but the problem persists in all these conditions.
Here is the code I am using for the experiment:
clc
clear all
close all
%% PREPARE AND COLLECT INFO
KbName('UnifyKeyNames')
Screen('Preference', 'SkipSyncTests', 0);
oldPriority = Priority(1);
input('hit enter to begin... ');
%% Set parameters:
bitsPort = '/dev/ttyACM0';
%% Keyboard set up:
[keyboardIndices, productNames, ~] = GetKeyboardIndices;
deviceString = 'Dell Dell USB Entry Keyboard';
deviceNumber = 0;
for i=1:length(productNames) %for each possible device
if strcmp(productNames{i},deviceString) %compare the name to the name you want
deviceNumber = keyboardIndices(i); %grab the correct id, and exit loop
break;
end
end
%}
triggerKey = KbName('=+');
%%
AssertOpenGL;
HideCursor;
%% setting up the bits#:
clrplusMode = 2;
PsychImaging('PrepareConfiguration');
% 32bit:
PsychImaging('AddTask', 'General','FloatPoint32BitIfPossible');
% Use color++ mode with overlay:
PsychImaging('AddTask', 'General', 'EnableBits++Color++Output',clrplusMode);
% Open a connection to Bits#/Display++.
BitsPlusPlus('OpenBits#',bitsPort);
BitsPlusPlus('SwitchToColor++');
%% Screen:
w.whichScreen = max(Screen('Screens'));
% setting the resolution
w.screenRes = [0 0 1024 768];
w.screenFrameRate = 60;
oldRes = SetResolution(w.whichScreen,w.screenRes(3), w.screenRes(4),w.screenFrameRate);
w.frameRate = Screen('FrameRate',w.whichScreen);
%% timing:
t.ifi = 1/w.frameRate;
t.nRep = 2^12;
t.nFrame = 1;
%% stimulus features:
stim.grey = [.5 .5 .5];
stim.black = [0 0 0];
stim.white = [1 1 1];
%% WINDOW SETUP
[window, rect] = PsychImaging('OpenWindow', w.whichScreen, stim.grey,w.screenRes);
w.screenRect = rect;
cntrX = round(w.screenRect(3)/2);
cntrY = round(w.screenRect(4)/2);
%% setting up the Bits# trigger:
repetitions = 1;
mask = bin2dec('1111111111111111');
trigPackOn = 10; % time to be high in the beginning of the frame (in 100 us steps = 0.1 ms steps)
dataPack = [repmat(bin2dec('1000000000000000'),trigPackOn,1);repmat(bin2dec('0000000000000000'),248-trigPackOn,1)]';
command = 0;
xpBits = 1;
ypBits = 2;
%% Initial set up:
btext = 'Hit =/+ Key to Begin...';
bbox = Screen('TextBounds', window, btext);
newRect = CenterRectOnPoint(bbox, cntrX, cntrY);
tx = newRect(1); ty = newRect(2);
Screen('DrawText', window, btext, tx, ty + 40, stim.white,stim.grey);
Screen('Flip', window);
KbTriggerWait(triggerKey, deviceNumber);
%% presenting the stimulus
BitsPlusPlus('DIOCommand', window, 1, mask, dataPack, command,xpBits,ypBits);
vbl = Screen('Flip', window);
vblAll = [];
stimOnTAll = [];
flipTAll = [];
missedAll = [];
beamPosAll = [];
for nii=1:t.nRep/2
%%%%%%%% ON:
Screen('FillRect',window,stim.white);
[vbl stimOnT flipT missed beamPos] = Screen('Flip', window, vbl + (t.nFrame - 0.5)*t.ifi,0);
vblAll = [vblAll vbl];
stimOnTAll = [stimOnTAll,stimOnT];
flipTAll = [flipTAll,flipT];
missedAll = [missedAll,missed];
beamPosAll = [beamPosAll,beamPos];
%%%%%%%%%% OFF:
Screen('FillRect',window,stim.black);
[vbl stimOnT flipT missed beamPos] = Screen('Flip', window, vbl + (t.nFrame - 0.5)*t.ifi,0);
vblAll = [vblAll vbl];
stimOnTAll = [stimOnTAll,stimOnT];
flipTAll = [flipTAll,flipT];
missedAll = [missedAll,missed];
beamPosAll = [beamPosAll,beamPos];
end
%% Reseting Bits#:
BitsPlusPlus('DIOCommandReset', window);
% Load identity (linear) CLUT into Bits++/Bits#/Display++ to restore proper display:
BitsPlusPlus('LoadIdentityClut', window);
Screen('Flip', window);
BitsPlusPlus('Close');
%% Close everything down
ShowCursor;
Screen('CloseAll');
In this code I set the times relative to the timing of the last frame, but I have also tested setting the flipping times with absolute values by calculating the timings before the stimulus presentations. Still, I have the same issue.
Following are the results:
no missed frames, and duration of the frames:
two events match at the beginning:
but the synchronicity is not as good at the end:
My authentication code for priority support:
CZS6KX2Y-202145122119:509c8b2e476ca976cfd253b3f725126098767e9a548cb4f30fa1ea282922433f