Arduino digital read into loop

11 views (last 30 days)
Olivier Roy
Olivier Roy on 26 Oct 2022
Answered: Ayush Gupta on 16 Oct 2023
I want to run an experiment in which a TTL signal is sent to Matlab via an Arduino to trigger an audio playback. I want to use the digitalRead function of PsychToolbox as the process is latency critical and this offers the best latency. This is based on the Arduino Legacy from Matlab. See discussion here.
My script presents sound at a 1250 ms interval with 250 ms jitter and records inputs as response time in a for loop. Here is an excerpt:
for block = 1:param.nblocks
for trial = 1:ntrials
if trial == 1
TrialStart(block, trial) = GetSecs;
else
TrialStart(block, trial) = TrialStart(block, trial-1) + blocklog(block).ran(trial-1).soa;
end
[data] = present(blocklog, block, trial, TrialStart, TheSnd, pahandle, param, ntrials, key);
data.correct = correct(data);
subjdata = [subjdata; struct2array(data)];
end
block_feedback (scr, param, subjdata, block, img);
end
where TrialStart stores the trial start time and the structure blocklog is the predetermined sequence and its associated parameters (ie. ran (trial) and soa (interval between two trials)).
The goal would be to implement continuous polling of a digital pin during the 500 ms interval in which a sound can be presented. If there is a TTL (pin going from 0 to 1, rise) within, say, the first 495 ms, then immidiately trigger sound A or B according to a predetermined sequence. If no TTL, then revert to presenting either sound C or D according to a predetermined sequence.
I am relatively new to Matlab and can't figure out how to do it. I assume this would require a while loop and research of this forum suggested the use of Callbacks but I am not sure how to do it.
Thank you.

Accepted Answer

Ayush Gupta
Ayush Gupta on 16 Oct 2023
for block = 1:param.nblocks
for trial = 1:ntrials
if trial == 1
TrialStart(block, trial) = GetSecs;
else
TrialStart(block, trial) = TrialStart(block, trial-1) + blocklog(block).ran(trial-1).soa;
end
% Clear any pending events from previous trials
while KbCheck; end
% Start the polling loop
ttlDetected = false;
startTime = GetSecs;
while (GetSecs - startTime) < 0.5
% Poll the digital pin using digitalRead
ttlValue = digitalRead(arduino, pinNumber);
% Check if TTL is detected within the first 495 ms
if (GetSecs - startTime) < 0.495 && ttlValue == 1
ttlDetected = true;
break;
end
end
% Determine which sound to present based on TTL detection
if ttlDetected
% Play sound A or B according to predetermined sequence
soundIndex = getSoundIndexForTrial(block, trial); % Replace with your own logic
playSound(TheSnd(soundIndex), pahandle);
else
% Play sound C or D according to predetermined sequence
soundIndex = getSoundIndexForTrial(block, trial); % Replace with your own logic
playSound(TheSnd(soundIndex), pahandle);
end
[data] = present(blocklog, block, trial, TrialStart, TheSnd, pahandle, param, ntrials, key);
data.correct = correct(data);
subjdata = [subjdata; struct2array(data)];
end
block_feedback (scr, param, subjdata, block, img);
end
In this modified script, the while loop continuously polls the digital pin using the digitalRead function until either a TTL is detected within the first 495 ms or the 500 ms interval ends. Based on the TTL detection, the appropriate sound is played using the playSound function.
Make sure to replace 'pinNumber' with the actual pin number you are using on the Arduino, and implement your own logic to determine the sound index for each trial based on your predetermined sequence.
Thank you.

More Answers (0)

Categories

Find more on MATLAB Support Package for Arduino Hardware in Help Center and File Exchange

Tags

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!