EEGLAB can be used for the analysis and visualization of EEG datasets recorded using OpenBCI hardware and software. EEGLAB can work with a variety of different file types, including those that are exported from the OpenBCI GUI, as we saw in the previous post.
Get your data ready
EEG Data File
EEG data can be stored ASCII files (often saved with the “.txt” extension). The OpenBCI Processing GUI saves data in text or comma separated value (csv) files, which are output into the “SavedData” directory within the OpenBCI_Processing directory.
Import the CSV file as a MATLAB matrix using the following command:
> data = csvread('.../directory/yourfile.txt', row offset, column offset)
For example:
> data = csvread('.../OpenBCI-RAW-__.txt', 5, 1);
Row offset is the number of rows in your txt file before the start of your EEG data (in the current version of the OpenBCI GUI, there are 5 commented lines before the start of the data, so the offset should be 5 to make the matrix start on line 6). Column offset skips the sample number column.
You can also write a function to open files and avoid writing and changing the name of the file everytime. To do so, you must write the code showed below and save it as a “.m” file.
function [data] = open_files() % Prompt user for filename [fname, fdir] = uigetfile( ... {'*.csv', 'CSV Files (*.csv)'; ... '*.xlsx', 'Excel Files (*.xlsx)'; ... '*.txt*', 'Text Files (*.txt*)'}, ... 'Pick a file'); % Create fully-formed filename as a string filename = fullfile(fdir, fname); % Check that file exists assert(exist(filename, 'file') == 2, '%s does not exist.', filename); % Read in the data, skipping the 5 first rows data = csvread(filename,5,0); end
You can call the function from the Command Window with the following line (Remember to save both scripts at the same folder):
[data] = open_files();
If you are using the OpenBCI V3 board with accelerometer data and aux data, you might want to separate the last three channels of your data before you send it into EEGLAB in order to only work with the EEG data and the accelerometer data separetly. To separte the different data with the respective variables, enter the command:
% Create general variables Time = data(:,1); EEGData = data(:,2:9); AuxData = data(:,10:12);

Channel Location File
Channel locations are useful for plotting EEG scalp maps in 2-D or 3-D format. OpenBCI uses the standard 10-20 format for the 8 and 16 channel models, which can be found within these .ced files: 8 channel and 16 channel. You can then import channel data by click “Browse” next to “Channel location file or info” and locating the OpenBCI .ced file you downloaded.

If you need to edit the channel locations, I would suggest you editing either “eeglab_chan32.locs” located in “\EEGLAB\sample_data” or “Standard-10-20-Cap25.ced” located in “\EEGLAB\sample_locs”. You should use any text editors such as WordPad, NotePad++, Atom… Whichever works better for you and edit the files. Remember to save it as a “.ced” file, and not a txt file.
Number labels theta radius X Y Z sph_theta sph_phi sph_radius 1 Fp1 -18 0.511 0.95 0.309 -0.0349 18 -2 1 2 Fp2 18 0.511 0.95 -0.309 -0.0349 -18 -2 1 3 F9 -55 0.639 0.52 0.742 -0.423 55 -25 1 4 F7 -54 0.511 0.587 0.809 -0.0349 54 -2 1 5 F3 -39 0.333 0.673 0.545 0.5 39 30 1 6 Fz 0 0.256 0.719 -0 0.695 -0 44 1 7 F4 39 0.333 0.673 -0.545 0.5 -39 30 1 8 F8 54 0.511 0.587 -0.809 -0.0349 -54 -2 1 9 F10 55 0.639 0.52 -0.742 -0.423 -55 -25 1 10 T9 -90 0.639 5.55e-17 0.906 -0.423 90 -25 1 11 T7 -90 0.511 6.12e-17 0.999 -0.0349 90 -2 1 12 C3 -90 0.256 4.4e-17 0.719 0.695 90 44 1 13 Cz 90 0 3.75e-33 -6.12e-17 1 -90 90 1 14 C4 90 0.256 4.4e-17 -0.719 0.695 -90 44 1 15 T8 90 0.511 6.12e-17 -0.999 -0.0349 -90 -2 1 16 T10 90 0.639 5.55e-17 -0.906 -0.423 -90 -25 1 17 P9 -126 0.639 -0.533 0.733 -0.423 126 -25 1 18 P7 -126 0.511 -0.587 0.809 -0.0349 126 -2 1 19 P3 -141 0.333 -0.673 0.545 0.5 141 30 1 20 Pz 180 0.256 -0.719 -8.81e-17 0.695 -180 44 1 21 P4 141 0.333 -0.673 -0.545 0.5 -141 30 1 22 P8 126 0.511 -0.587 -0.809 -0.0349 -126 -2 1 23 P10 126 0.639 -0.533 -0.733 -0.423 -126 -25 1 24 O1 -162 0.511 -0.95 0.309 -0.0349 162 -2 1 25 O2 162 0.511 -0.95 -0.309 -0.0349 -162 -2 1
Events File
If you are working with Motor Imagery, Event Related Cortical Potentials (ERPs) or you just interested in the data followed by a specific moment, you need to upload Events Information in a “.txt” file.
Since I am working with Motor Imagery and Motor Execution and I am using OpenBCI axelerometer data to save my events, I wrote an script that finds all the events that I am interested in.
%% FINDING EVENTS % Trials Events RF_Re = find(Trials == 1); % Move Right Finger LF_Re = find(Trials == 2); % Move Left Finger RF_Im = find(Trials == 3); % Imagine Moving Right Finger LF_Im = find(Trials == 4); % Imagine Moving Left Finger Events_row = [RF_Re; LF_Re; RF_Im; LF_Im]; % List of events (based on counts) E = sort(Events_row); % List of events (based on counts) sorted % Two External Buttons RightButton = find(Right == 25120); % RightButton is pressed Events_RB = RightButton*4-4; % Translate the row to time for RB_Char = {'RightButton'}; % Create 'Right Button' column RB = repmat (RB_Char, length(Events_RB),1); end R = table(Events_RB,RB); % Create a table with Right Button events LeftButton = find(Left == 25120); % LeftButton is pressed Events_LB = LeftButton*4-4; % Translate the row to time for LB_Char = {'LeftButton'}; % Create 'Left Button' column LB = repmat (LB_Char, length(Events_LB),1); end L = table(Events_LB,LB); % Create a table with Left Button events % OBSERVATION: Some events are not saved. There is a difference of 2506ms % between two different type of events (RF_Re and LF_Re, for example). % This means that between two values of the same event there is difference % of 10000ms. Currently, you must add this new values manually. MoveRF = RF_Re(1,:); % Find 1st Move RF Event MoveLF = LF_Re(1,:); % Find 1st Move LF Event ImagineRF = RF_Im(1,:); % Find 1st Imagine RF Event ImagineLF = LF_Im(1,:); % Find 1st Imagine RF Event Move_RF = (MoveRF:10000:(MoveRF+100000-1000))'; % Create Move RF Event Variable Move_LF = (MoveLF:10000:(MoveLF+100000-1000))'; % Create Move LF Event Variable Imagine_RF = (ImagineRF:10000:(ImagineRF+100000-1000))'; % Create Imagine RF Event Variable Imagine_LF = (ImagineLF:10000:(ImagineLF+100000-1000))'; % Create Imagine LF Event Variable % Conversion of variables (From counts to time) Events_RFRe = Move_RF*4-4; % Translate MoveRF counts into time Events_LFRe = Move_LF*4-4; % Translate MoveLF counts into time Events_RFIm = Imagine_RF*4-4; % Translate ImagineRF counts into time Events_LFIm = Imagine_LF*4-4; % Translate ImagineLF counts into time Events = [Events_RFRe; Events_LFRe; Events_RFIm; Events_LFIm]; % List of events (based on time) Events_Time = sort(Events); % Sort of the 2nd List of Events
Also, to make my life easier, I wrote a legit script to save the events accordingly to EEGLAB requirements. , where all the events are label and sort in time.
% EEGLAB Event file (.xls) % Latency (1st Column) Latency = sort(Events); % Sort of 1st Events List (EEGLAB variable) % Type (2nd Column) for Cues = {'MoveRF';'MoveLF'; 'ImagineRF';'ImagineLF'}; % Repeat matix 10 times (10 trials) in column 1 Type = repmat(Cues, 10, 1); end % Duration (3rd Column) for Sec = 4; Duration = repmat(Sec,40,1); end % General Variable EEGLAB_Events = table(Latency, Type, Duration); % Save EEGLAB_Events.xlsx in Excel File (Ready to upload in EEGLAB) filename = 'EEGLAB_Events.xlsx'; writetable(EEGLAB_Events,filename,'Sheet',1,'Range','A1');
Thus, the result is a “.csv” file distributed in three different columns:
- Latency column has the specific times event happend sorted by time.
- Type column distinguish among the different types of events.
- Duration column shows the length of the event.

Start with EEGLAB
If EEGLAB isn’t already running, enter “eeglab” into the Matlab command line to start the program. Check that you are in the correct path before you run it.

The main EEGLAB window will pop-up in your screen:

Import your matrix into EEGLAB using the EEGLAB GUI: File -> Import Data -> Using EEGLAB functions and plugins -> From ASCII/float file or Matlab array.
In the pop-up window that appears, enter information about the data set. Select “Matlab variable”, and enter the name of the variable where your matrix is stored. Enter the Data Sampling rate (it should be commented in at the top of the txt file – usually 250 Hz by default in the OpenBCI GUI). The other fields can be left at default, and EEGLAB will automatically fill in the information from the data set.

Congratulations! The EGE data and Channel Locations are now imported into EEGLAB, and you can perform a variety of data analysis on the data and visualize it.
Plot your data into EEGLAB using the EEGLAB GUI: Plot -> Channel data (scroll). By default, EEGLAB has a 5 seconds window length (x axis). If you want to change it, you must select Settings -> time range to display in the figure window and type the new window length (s).

Besides, you can also change the scale of the plot by playing a little bit with the “+” and “-“in the bottom of the plot. I would suggest a scale of 50 or 100. Thus, you will have better perspective and visualization of EEG data. This should be the result:

If you wanna go one step further, you can import events into your data by using the EEGLAB GUI: File -> Import event info -> From Matlab array or ASCII file. Make sure to write in Input field “latency type duration”, and the following parameters showed in Figure 8.

At this point, you can plot EEG data with the events marked in different colours by following the same steps as earlier when we plot only EEG data.

There is also the opportunity to reject continous EEG data so as to “clean” your data by selecting with the cursor the length of the data that you want to remove from the signal. Although I will explain in another post how to do it significantly, feel free to play with it!

References
- EEGLAB Tutorial: http://sccn.ucsd.edu/wiki/EEGLAB_TUTORIAL_OUTLINE
- EEGLAB Wiki: http://sccn.ucsd.edu/wiki/EEGLAB
Hi, I noticed that .ced file for channel locations can be edited, but I can’t seems to find .ced file in OpenBCI application folder.
Could you please help?
I’m also looking for the .ced channel location file (8 channel) – where can I find it? (link on this page seems to be broken)