Hi Mario,
Possibly my problem is related to this. Basically, I created a stimulus with 4 parts: an intertrial interval, a sample period, a delay interval and a test period. The code runs for around 200 correct trials and at some point it freezes without giving me any feedback. It might be a bug or a mistake from my part. A description of the stimulus goes below.
[Optional: Description of the stimulus] The intertrial interval is a preparation phase where nothing appears in the screen. During the sample period, a light gray square appears in the middle of the screen and the monkey has to touch this square to advance to the delay period. The delay is just a waiting period when nothing is displayed. Finally, in the test phase the monkey needs to touch a gray square which will appear in a random position. As soon as the monkey touches it, the arduino is invoked to turn on a water pump to deliver juice to the monkey. After that, a new trial starts.
Basically, in my code I created a nested function modified from the MultiTouchMinimalDemo.m to register the touch of only one finger, the finger that touches the screen first (see nested function below). I constantly call this nested function throughout my main function, at every flip of the screen. As I’ve written before, evth works fine until around 200 trials. At some point around it, one of the cores of the CPU gets stuck at 100% and matlab freezes (see figure below). Note that typically the monkey is continuously dragging his finger in the screen, and not removing and retouching the screen. So, there is constant input in the queue.
%% Function to process touch events
function process_touch_event()
% TouchEventAvail reports the number of events in a touch queue.
% One single touch can contain many events.
while TouchEventAvail(dev)
evt_count = evt_count + 1;
% Return oldest pending event
evt = TouchEventGet(dev, w);
% Touch blob id - Unique in the session at least as
% long as the finger stays on the screen:
id = evt.Keycode;
% fprintf("%d %d\n", evt.Keycode, evt.Type)
% Only consider the id of the firstard = serialport('/dev/ttyACM0', 9600); touch event
if evt_count == 1
first_event_id = id;
end
if id == first_event_id
switch evt.Type
case 0
% Not a touch point, but a button press or release on a
% physical (or emulated) button associated with the
% touch device:ard = serialport('/dev/ttyACM0', 9600);
buttonstate = evt.Pressed;
case 1
% Not really a touch point, but movement of the
% simulated mouse cursor, driven by the primary
% touch-point:
Screen('DrawDots', w, [evt.MappedX; evt.MappedY], ...
baseSize, [1,1,1], [], 1, 1);
case {2, 3}
% 2: New touch point -> New blob!
% 3: Moving touch point -> Moving blob!
blob.mul = 1.0; % size of the blob
blob.x = evt.MappedX;
blob.y = evt.MappedY;
blob.t = evt.Time;
case 4
% Touch released -> Dying blob!
blob.mul = 0.999;
blob.x = evt.MappedX;
blob.y = evt.MappedY;
case 5
% Lost touch data for some reason:
% Flush screen red for one video refresh cycle.
fprintf(['Ooops - Sequence data loss! 3rd party ' ...
'interference or overload?\n']);
Screen('FillRect', w, [1 0 0]);
Screen('Flip', w);
Screen('FillRect', w, 0);
end
end
end
% Now that all touches for this iteration are processed, repaint
% the live blob in its new position or fade out a dying blob
if ~isempty(blob) && blob.mul > 0.1
% Draw the blob: .mul defines size of the blob:
Screen('DrawDots', w, [blob.x, blob.y], ...
blob.mul * baseSize, orange / 255, [], 1, 1);
% An orphaned blob with no finger touching anymore,
% so slowly fade it out:
if blob.mul < 1
blob.mul = blob.mul * 0.3;
end
else
% Below threshold: Kill the blob
blob = [];
end
% To determine if blobcol is empty
if evt_count && isempty(blob)
evt_count = 0;
end
if buttonstate
Screen('FrameRect', w, [1, 1, 0], [], 5);
end
end
Core 3 of the CPU stuck at 100%:
After debugging it, I’ve found a workaround for the problem. I must delete and recreate the queue at every few trials, let’s say, at every 30 trials (snippet below).
if ~mod(total_trials, 30)
TouchQueueStop(dev);
TouchQueueRelease(dev);
Pause(0.1);
TouchQueueCreate(w, dev);
TouchQueueStart(dev);
end
The pause is necessary otherwise the whole pc crashes in a non-predictable way. My hypothesis is that sth is being stored in the cue and not being deleted, as I would have expected. If you are interested in exploring this further, I can send you the whole code.
My hardwares are a Microsoft Surface Pro 6 i5 8Gb RAM 128GB connected to an arduino leonardo. I am using psychtoolbox v3.0.16, Matlab r2019b, Ubuntu 18.04 LTS Desktop and Jakeday Linux Kernel for Surfaces.
Best,
Fred.