-- This Lua script sends Stimulations to the speller visualization box for a p300-visual-speller -- -- Author : Tobias Baumann -- Date : 2021-12-06 -- Revised: 2021-21-07 --This function lets the box sleep until a fixed moment function wait_until(box, time) while box:get_current_time() < time do box:sleep() end end --This function lets the box wait for a fixed duration function wait_for(box, duration) wait_until(box, box:get_current_time() + duration) end --this function checks, wether value already is an element of the given stim_matrix function is_element(matrix, value) for i = 1, #matrix do if #matrix == 0 then return(false) elseif value == matrix[i] then return(true) end end return(false) end --this function creates a sequence of stimulations by shuffeling the values of the given stim_matrix function create_sequence(matrix) math.randomseed(os.time()) local stim_matrix = {} local stim_code = 0 local i = 1 while i <= #matrix do stim_code = matrix[math.random(1,#matrix)] if is_element(stim_matrix, stim_code) == false then stim_matrix[i] = stim_code i = i + 1 end end return(stim_matrix) end -- this function is called when the box is initialized function initialize(box) --load stimulation codes dofile(box:get_config("${Path_Data}") .. "/plugins/stimulation/lua-stimulator-stim-codes.lua") --load box settings row_base = _G[box:get_setting(2)] col_base = _G[box:get_setting(3)] matrix_size = box:get_setting(4) n_repetitions = box:get_setting(5) flash_duration = box:get_setting(7) noflash_duration = box:get_setting(8) inter_repetition_delay = box:get_setting(9) inter_trial_delay = box:get_setting(10) send_toggle = _G[box:get_setting(11)] time_to_send = box:get_setting(13) if box:get_setting(12) == 'true' then free_spelling = true n_trials = 1 else free_spelling = false n_trials = box:get_setting(6) end --Lua variables send = false row_stimcodes = {} col_stimcodes = {} for x = 1, matrix_size do row_stimcodes[x] = row_base + x - 1 end for x = 1, matrix_size do col_stimcodes[x] = col_base + x - 1 end end -- this function is called when the box is uninitialized function uninitialize(box) end -- this function is called once by the box function process(box) while box:keep_processing() do if send then for stimulation = 1, box:get_stimulation_count(1) do stimulation_id, stimulation_time, stimulation_duration = box:get_stimulation(1, 1) if stimulation_id == send_toggle then send = false box:send_stimulation(1, OVTK_StimulationId_ExperimentStop ,box:get_current_time() , 0) box:remove_stimulation(1, 1) end end for trial = 1, n_trials do if not send then break end box:send_stimulation(1, OVTK_StimulationId_RestStart, box:get_current_time() , 0) wait_for(box, inter_trial_delay) box:send_stimulation(1, OVTK_StimulationId_RestStop, box:get_current_time() , 0) box:send_stimulation(1, OVTK_StimulationId_TrialStart ,box:get_current_time() , 0) for segment = 1, n_repetitions do row_stimcodes = create_sequence(row_stimcodes) col_stimcodes = create_sequence(col_stimcodes) box:send_stimulation(1, OVTK_StimulationId_SegmentStart ,box:get_current_time() , 0) for i = 1, matrix_size do box:send_stimulation(1, row_stimcodes[i] ,box:get_current_time() , 0) box:send_stimulation(1, OVTK_StimulationId_VisualStimulationStart ,box:get_current_time() , 0) wait_for(box, flash_duration) box:send_stimulation(1, OVTK_StimulationId_VisualStimulationStop ,box:get_current_time() , 0) wait_for(box, noflash_duration) box:send_stimulation(1, col_stimcodes[i] ,box:get_current_time() , 0) box:send_stimulation(1, OVTK_StimulationId_VisualStimulationStart ,box:get_current_time() , 0) wait_for(box, flash_duration) box:send_stimulation(1, OVTK_StimulationId_VisualStimulationStop ,box:get_current_time() , 0) wait_for(box, noflash_duration) end box:send_stimulation(1, OVTK_StimulationId_SegmentStop ,box:get_current_time() , 0) wait_for(box, inter_repetition_delay) end box:send_stimulation(1, OVTK_StimulationId_TrialStop ,box:get_current_time() , 0) end if not free_spelling then box:send_stimulation(1, OVTK_StimulationId_ExperimentStop ,box:get_current_time() , 0) send = false end else for stimulation = 1, box:get_stimulation_count(1) do stimulation_id, stimulation_time, stimulation_duration = box:get_stimulation(1, 1) if stimulation_id == send_toggle then send = true wait_for(box, time_to_send) box:send_stimulation(1, OVTK_StimulationId_ExperimentStart ,box:get_current_time() , 0) box:remove_stimulation(1, 1) end end end -- releases cpu box:sleep() end end