/
ft_realtime_modeegproxy.m
112 lines (98 loc) · 4.64 KB
/
ft_realtime_modeegproxy.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
function ft_realtime_modeegproxy(cfg)
% FT_REALTIME_MODEEGPROXY reads continuous data from a modeeg EEG acquisition system
% through the serial port or through BlueTooth and writes it to a FieldTrip buffer.
%
% The FieldTrip buffer is a network transparent server that allows the acquisition
% client to stream data to it. An analysis client can connect to read the data upon
% request. Multiple clients can connect simultaneously, each analyzing a specific
% aspect of the data concurrently.
%
% Use as
% ft_realtime_modeegproxy(cfg)
%
% The configuration should contain
% cfg.filename = string, name of the serial port (default = '/dev/tty.FireFly-B106-SPP')
% cfg.feedback = 'yes' or 'no' (default = 'no')
% cfg.blocksize = number, in seconds (default = 0.125)
%
% The target to write the data to is configured as
% cfg.target.datafile = string, target destination for the data (default = 'buffer://localhost:1972')
% cfg.target.dataformat = string, default is determined automatic
%
% To stop this realtime function, you have to press Ctrl-C
%
% See also FT_REALTIME_SIGNALPROXY, FT_REALTIME_SIGNALVIEWER
% Copyright (C) 2012, Robert Oostenveld
%
% This file is part of FieldTrip, see http://www.fieldtriptoolbox.org
% for the documentation and details.
%
% FieldTrip is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% FieldTrip is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with FieldTrip. If not, see <http://www.gnu.org/licenses/>.
%
% $Id$
cfg = ft_checkconfig(cfg);
% set the defaults
if ~isfield(cfg, 'filename'), cfg.filename = '/dev/tty.FireFly-B106-SPP'; end
if ~isfield(cfg, 'channel'), cfg.channel = 'all'; end
if ~isfield(cfg, 'feedback'), cfg.feedback = 'no'; end
if ~isfield(cfg, 'blocksize'), cfg.blocksize = 0.125; end
if ~isfield(cfg, 'target'), cfg.target = []; end
if ~isfield(cfg.target, 'datafile'), cfg.target.datafile = 'buffer://localhost:1972'; end
if ~isfield(cfg.target, 'dataformat'), cfg.target.dataformat = []; end % default is to use autodetection of the output format
% make a connection to the serial port
fid = fopen(cfg.filename, 'r');
if fid<0
ft_error('cannot open %s', cfg.filename);
else
fprintf('opened %s\n', cfg.filename);
c = onCleanup(@()fclose(fid));
end
rem = []; % this will contain the remaining bytes following each conversion
bytes = 0; % number of bytes read in total
count = 0; % number of blocks read
blocksize = round(17*256*cfg.blocksize); % 17 bytes per sample, 256 Hz sampling rate
feedback = strcmp(cfg.feedback, 'yes'); % convert to boolean value
% create a fixed header
hdr.Fs = 256;
hdr.nChans = 6;
ndr.nSamples = inf;
hdr.nSamplesPre = 0;
hdr.label = cellfun(@num2str, {1, 2, 3, 4, 5, 6}, 'uniformoutput', false);
chanindx = 1:2;
while (true)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% read some data from the serial stream
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
raw = fread(fid, [1 blocksize], 'uint8=>uint8');
bytes = bytes + numel(raw);
if feedback
fprintf('%d bytes read\n', bytes);
end
raw = cat(2, raw, rem);
[dat, rem] = decode_modeeg(raw);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% from here onward it is specific to writing the data to another stream
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ~isempty(dat)
count = count + 1;
fprintf('writing %d channels, %d samples\n', size(dat,1), size(dat,2));
if count==1
% flush the file, write the header and subsequently write the data segment
ft_write_data(cfg.target.datafile, dat(chanindx,:), 'header', hdr, 'dataformat', cfg.target.dataformat, 'chanindx', chanindx, 'append', false);
else
% write the data segment
ft_write_data(cfg.target.datafile, dat(chanindx,:), 'header', hdr, 'dataformat', cfg.target.dataformat, 'chanindx', chanindx, 'append', true);
end
end
end % while true