Line 509: |
Line 509: |
| | | |
| <nowiki> | | <nowiki> |
− | % ===================================================================================================
| + | function handle = buttonbox(cmd,varargin) |
− | function handle = serial_buttonbox_common(cmd,varargin)
| + | % to initialize connection: |
− | %
| + | % define settings as structure with fields: |
− | % NOTE: this is a functional example, please adapt code according to your needs.
| + | % bb.Device = 'COM3'; |
− | %
| + | % bb.BaudRate = 115200; |
− | % to initialize connection:
| + | % bb.DataBits = 8; |
− | % handle = serial_buttonbox_common('open',se)
| + | % bb.StopBits = 1; |
− | % settings (se):
| + | % bb.Parity = 'none'; |
− | % define settings as a structure, i.e.:
| + | % handle = buttonbox('open',bb) |
− | % se.Device = 'COM2';
| + | % |
− | % se.BaudRate = 115200;
| + | % to run: |
− | % se.DataBits = 8;
| + | % buttonbox('run',handle); |
− | % se.StopBits = 1;
| + | % |
− | % se.Parity = 0;
| + | % to close the connection: |
− | % se.PTBPath = 'c:\toolboxes\PsychToolbox'
| + | % buttonbox('close',handle); |
− | %
| + | |
− | % to run:
| + | persistent old_hdl % keep handle to COM object persistent |
− | % serial_buttonbox_common('run')
| + | |
− | %
| + | % set defaults |
− | % to close the connection:
| + | bb.Device = 'COM3'; |
− | % serial_buttonbox_common('close',handle);
| + | bb.BaudRate = 115200; |
− |
| + | bb.DataBits = 8; |
− | persistent old_hdl | + | bb.StopBits = 1; |
− |
| + | bb.Parity = 'none'; |
− | % set defaults
| + | |
− | se.Device = 'COM2';
| + | if nargin < 1 |
− | se.BaudRate = 115200;
| + | cmd = 'open'; |
− | se.DataBits = 8;
| + | end |
− | se.StopBits = 1;
| + | if nargin > 1 |
− | se.Parity = 0;
| + | % user overwrites default settings |
− | se.PTBPath = 'c:\toolboxes\PsychToolbox';
| + | flds = fields(varargin{1}); |
− |
| + | for n = 1 : numel(flds) |
− | if nargin < 1
| + | bb.(flds{n}) = varargin{1}.(flds{n}); |
− | cmd = 'open';
| + | end |
− | end
| + | end |
− | if nargin > 1
| + | |
− | % user overwrites default settings
| + | |
− | flds = fields(varargin{1});
| + | switch cmd |
− | for n = 1 : numel(flds)
| + | case 'open' |
− | se.(flds{n}) = varargin{1}.(flds{n});
| + | % get handle to serial device |
− | end
| + | handle = open_buttonbox(bb); |
− | end
| + | return |
− |
| + | case 'close' |
− |
| + | if nargin > 0 |
− | switch cmd
| + | handle = varargin{1}; |
− | case 'open'
| + | else |
− | addpath(genpath(se.PTBPath));
| + | handle = old_hdl; |
− | % get handle to serial device
| + | end |
− | handle = open_buttonbox(se.Device);
| + | fclose(handle); |
− | return
| + | return |
− | case 'close'
| + | case 'run' |
− | handle = varargin{1};
| + | % read incoming data |
− | IOPort('close',handle);
| + | if isempty(old_hdl) |
− | return
| + | help serial_buttonbox_common |
− | case 'run'
| + | error('Buttonbox not yet initialized'); |
− | % read incoming data
| + | end |
− | if isempty(old_hdl)
| + | handle = old_hdl; |
− | help serial_buttonbox_common
| + | otherwise |
− | error('Buttonbox not yet initialized');
| + | fprintf('Unknown option %s\n',cmd); |
− | end
| + | return |
− | handle = old_hdl;
| + | end |
− | otherwise
| + | |
− | fprintf('Unknown option %s\n',cmd);
| + | % only gets here when cmd = 'run' |
− | return
| + | % Initialize output figure |
− | end
| + | win = list_output(' ',[]); |
− |
| + | while 1 |
− | % only gets here when cmd = 'run'
| + | % Exit if user closed output figure |
− | while 1
| + | if ~ishandle(win) |
− | % start polling for characters (indicating start of scan)
| + | return |
− | navailable = IOPort('BytesAvailable', handle);
| + | end |
− | if navailable
| + | % start polling for characters (indicating start of scan) |
− | data = [];
| + | navailable = handle.BytesAvailable; |
− | while navailable
| + | if navailable |
− | % read incoming data
| + | data = []; |
− | [newdata, ~, err] = IOPort('Read', handle, 0, navailable);
| + | while navailable |
− | if ~isempty(err), disp(err); end
| + | % read incoming data |
− | data = [data newdata];
| + | [newdata, cnt] = fread(handle, navailable); |
− | %pause(0.001); % if possible just add a small pause to not claim entire core
| + | % concatenate possible new data |
− | navailable = IOPort('BytesAvailable', handle);
| + | if cnt |
− | end
| + | data = [data newdata(:)]; |
− | if numel(data)>1
| + | end |
− | fprintf('\nReceived characters: %d\n',numel(data));
| + | % check if any more data left |
− | end
| + | navailable = handle.BytesAvailable; |
− | for n = 1 : numel(data)
| + | end |
− | % disp(char(data(n)));
| + | % output info about which button was pressed |
− | fprintf('incoming: %d\t%s\n',data(n),char(data(n)));
| + | for n = 1 : numel(data) |
− | end
| + | line = sprintf('incoming: %03d %s',data(n),char(data(n))); |
− | end
| + | list_output(line,win); |
− |
| + | end |
− |
| + | end |
− | end %while 1
| + | pause(0.01); |
− |
| + | end %while 1 |
− | function hdl = open_buttonbox(device)
| + | |
− | % open handle to serial device (mini buttonbox)
| + | function hdl = open_buttonbox(device) |
− | try
| + | % open handle to serial device (mini buttonbox) |
− | hdl = IOPort('OpenSerialPort',device,['BaudRate=' num2str(se.BaudRate)]);
| + | try |
− | catch
| + | hdl = serial(device.Device, 'Baudrate', device.BaudRate, 'DataBits', device.DataBits, 'StopBits', device.StopBits, 'Parity', device.Parity); |
− | if ~isempty(old_hdl)
| + | fopen(hdl); |
− | IOPort('close',old_hdl);
| + | catch |
− | end
| + | if ~isempty(old_hdl) |
− | hdl = IOPort('OpenSerialPort',device,['BaudRate=' num2str(se.BaudRate)]);
| + | fclose(old_hdl); |
− | end
| + | delete(old_hdl); |
− | old_hdl = hdl;
| + | end |
− |
| + | hdl = serial(device.Device, 'Baudrate', device.BaudRate, 'DataBits', device.DataBits, 'StopBits', device.StopBits, 'Parity', device.Parity); |
− | fprintf('Wait for device buttonbox....\n');
| + | fopen(hdl); |
− | tic
| + | end |
− | while ~IOPort('BytesAvailable', hdl) && toc<10
| + | old_hdl = hdl; |
− | % wait for welcome message device
| + | |
− | end
| + | fprintf('Wait for device buttonbox....\n'); |
− | pause(0.5);
| + | tic |
− |
| + | while hdl.BytesAvailable && toc<10 |
− | % clear buffer
| + | navailable = bbox.BytesAvailable; |
− | %IOPort('flush', hdl);
| + | % wait for welcome message device |
− | IOPort('purge', hdl); | + | fread(hdl, navailable); |
− | end
| + | end |
− |
| + | pause(0.5); |
− | end</nowiki>
| + | end |
| + | |
| + | function win = list_output(line,win) |
| + | persistent ptr |
| + | persistent lines |
| + | persistent edt |
| + | Maxlines = 40; |
| + | |
| + | if isempty(win) |
| + | % initialize listbox output figure |
| + | lines = cell(1,Maxlines); |
| + | [lines(1:end)]=deal({''}); |
| + | ptr=Maxlines; |
| + | lines(ptr) = {'Buttonbox output:'}; |
| + | idxs = mod(ptr:ptr+Maxlines-1,Maxlines)+1; |
| + | |
| + | win = figure(); |
| + | % initialize figure to hold output text |
| + | edt = uicontrol('Parent',win,'Style','ListBox','HorizontalAlignment','left', ... |
| + | 'Max',Maxlines,'BackgroundColor',[1 1 1],'Visible','on','String',lines(idxs), ... |
| + | 'FontSize',12,'Value',Maxlines); |
| + | pos = get(win,'Position'); |
| + | set(edt,'Position',[1 1 pos(3) pos(4)]); |
| + | end |
| + | ptr = mod(ptr,Maxlines)+1; % start |
| + | lines{ptr} = line; |
| + | idxs = mod(ptr:ptr+Maxlines-1,Maxlines)+1; |
| + | set(edt,'String',lines(idxs),'Value',Maxlines); |
| + | drawnow; |
| + | end |
| + | |
| + | end |
| + | </nowiki> |