Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18,758 changes: 18,758 additions & 0 deletions DefaultTrial_Session1_Shimmer_6749_Calibrated_PC_ECG.dat

Large diffs are not rendered by default.

807 changes: 807 additions & 0 deletions DefaultTrial_Session1_test_Calibrated_SD.dat

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions Resources/newWriteHeadersToFile.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function firstTime = newWriteHeadersToFile(fileName, signalNameArray, signalFormatArray, signalUnitArray)

if iscell(signalNameArray)
signalNames = cellfun(@char, signalNameArray, 'UniformOutput', false);
end

if iscell(signalFormatArray)
signalFormats = cellfun(@char, signalFormatArray, 'UniformOutput', false);
end

if iscell(signalUnitArray)
signalUnits = cellfun(@char, signalUnitArray, 'UniformOutput', false);
end

signalNamesString = strjoin(signalNames, '\t');
signalFormatsString = strjoin(signalFormats, '\t');
signalUnitsString = strjoin(signalUnits, '\t');

fid = fopen(fileName, 'wt');
if fid == -1
error('Cannot open file: %s', fileName);
end
fprintf(fid, '%s\n%s\n%s\n', signalNamesString, signalFormatsString, signalUnitsString);
fclose(fid);

firstTime = false;
end
52 changes: 52 additions & 0 deletions ShimmerDeviceHandler.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
classdef ShimmerDeviceHandler
properties
obj
shimmer
comPort
sensorClass
end

methods
function this = ShimmerDeviceHandler(comPort)
javaaddpath('ShimmerBiophysicalProcessingLibrary_Rev_0_10.jar');
javaaddpath('libs/ShimmerJavaClass.jar');
javaaddpath('libs/jssc-2.9.6.jar');
javaaddpath('libs/vecmath-1.3.1.jar');
javaaddpath('libs/commons-lang3-3.8.1.jar');

this.sensorClass = javaObjectEDT('com.shimmerresearch.driver.Configuration$Shimmer3$SENSOR_ID');
this.comPort = comPort;
this.obj = com.shimmerresearch.tools.matlab.ShimmerJavaClass();
end

function [success, this] = connect(this)
this.obj.mBluetoothManager.connectShimmerThroughCommPort(this.comPort);

timeout = 15;
startTime = tic;
this.shimmer = [];

while isempty(this.shimmer) && toc(startTime) < timeout
pause(1);
this.shimmer = this.obj.mBluetoothManager.getShimmerDeviceBtConnected(this.comPort);

if ~isempty(this.shimmer)
disp(['Device connected... Elapsed time: ', num2str(toc(startTime)), ' seconds']);
success = true;
pause(10);
return;
end
end
success = false;
end

function success = start(this)
this.shimmer = this.obj.mBluetoothManager.getShimmerDeviceBtConnected(this.comPort);
if isempty(this.shimmer)
error('Shimmer device is not connected.');
end
this.shimmer.startStreaming();
success = true;
end
end
end
4 changes: 2 additions & 2 deletions javaclasspath.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<before>

C:\Users\AbdullahHarithJamadi\Documents\MATLAB\libs\commons-math-2.2.jar
C:\Users\AbdullahHarithJamadi\Documents\MATLAB\libs\commons-math3-3.6.jar
C:\Users\AbdullahHarithJamadi\Documents\GitHub\Shimmer-MATLAB-ID\libs\commons-math-2.2.jar
C:\Users\AbdullahHarithJamadi\Documents\GitHub\Shimmer-MATLAB-ID\libs\commons-math3-3.6.jar
Binary file modified libs/ShimmerJavaClass.jar
Binary file not shown.
254 changes: 254 additions & 0 deletions newplotandwriteecgexample.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
function shimmer = newplotandwriteecgexample(comPort, captureDuration, fileName)
%NEWPLOTANDWRITEECGEXAMPLE - Plotting ecg signal and write to file
% INPUT: comPort - String value defining the COM port number for Shimmer
%
% INPUT: captureDuration - Numerical value defining the capture duration
%
% INPUT: fileName - String value defining the name of the data file
%
% OUTPUT: shimmer - Object of the ShimmerDeviceHandler
%
% EXAMPLE: newplotandwriteecgexample('COM5', 30, 'testdata.dat')
%
% See also newplotandwriteexample ShimmerDeviceHandler
%
% Example for Shimmer3

%% definitions
shimmer = ShimmerDeviceHandler(comPort); % Define shimmer as a ShimmerHandle Class instance with comPort1

fs = 512; % sample rate in [Hz]
firsttime = true;

% Note: these constants are only relevant to this examplescript and are not used
% by the ShimmerHandle Class
NO_SAMPLES_IN_PLOT = 5000; % Number of samples in the plot
DELAY_PERIOD = 0.2; % Delay (in seconds) between data read operations
numSamples = 0;

addpath('./Resources/')
%% settings

% filtering settings
fm = 50; % mains frequency [Hz]
fchp = 0.5; % corner frequency highpassfilter [Hz]; Shimmer recommends 0.5Hz for monitoring applications, 0.05Hz for diagnostic settings
nPoles = 4; % number of poles (HPF, LPF)
pbRipple = 0.5; % pass band ripple (%)

HPF = true; % enable (true) or disable (false) highpass filter
LPF = true; % enable (true) or disable (false) lowpass filter
BSF = true; % enable (true) or disable (false) bandstop filter

% highpass filters for ExG channels
if (HPF)
hpfexg1ch1 = FilterClass(FilterClass.HPF,fs,fchp,nPoles,pbRipple);
hpfexg1ch2 = FilterClass(FilterClass.HPF,fs,fchp,nPoles,pbRipple);
hpfexg2ch1 = FilterClass(FilterClass.HPF,fs,fchp,nPoles,pbRipple);
hpfexg2ch2 = FilterClass(FilterClass.HPF,fs,fchp,nPoles,pbRipple);
end
% lowpass filters for ExG channels
if (LPF)
lpfexg1ch1 = FilterClass(FilterClass.LPF,fs,fs/2-1,nPoles,pbRipple);
lpfexg1ch2 = FilterClass(FilterClass.LPF,fs,fs/2-1,nPoles,pbRipple);
lpfexg2ch1 = FilterClass(FilterClass.LPF,fs,fs/2-1,nPoles,pbRipple);
lpfexg2ch2 = FilterClass(FilterClass.LPF,fs,fs/2-1,nPoles,pbRipple);
end
% bandstop filters for ExG channels;
% cornerfrequencies at +1Hz and -1Hz from mains frequency
if (BSF)
bsfexg1ch1 = FilterClass(FilterClass.LPF,fs,[fm-1,fm+1],nPoles,pbRipple);
bsfexg1ch2 = FilterClass(FilterClass.LPF,fs,[fm-1,fm+1],nPoles,pbRipple);
bsfexg2ch1 = FilterClass(FilterClass.LPF,fs,[fm-1,fm+1],nPoles,pbRipple);
bsfexg2ch2 = FilterClass(FilterClass.LPF,fs,[fm-1,fm+1],nPoles,pbRipple);
end

%%

[success, obj] = shimmer.connect();

if success

shimmerClone = obj.shimmer.deepClone();
shimmerClone.setSamplingRateShimmer(fs);

shimmerClone.disableAllSensors(); % Disables all currently enabled sensors
shimmerClone.setEnabledAndDerivedSensorsAndUpdateMaps(0, 0); % Resets configuration on enabled and derived sensors

sensorIds = javaArray('java.lang.Integer', 1);
sensorIds(1) = java.lang.Integer(obj.sensorClass.HOST_ECG);

shimmerClone.setSensorIdsEnabled(sensorIds);

commType = javaMethod('valueOf', 'com.shimmerresearch.driver.Configuration$COMMUNICATION_TYPE', 'BLUETOOTH');
com.shimmerresearch.driverUtilities.AssembleShimmerConfig.generateSingleShimmerConfig(shimmerClone, commType);
obj.shimmer.configureFromClone(shimmerClone);

pause(20);

if shimmer.start()

plotData = [];
timeStamp = [];
filteredplotData = [];

h.figure1=figure('Name','Shimmer ECG signals'); % Create a handle to figure for plotting data from shimmer
set(h.figure1, 'Position', [100, 500, 800, 400]);
h.figure2=figure('Name','Shimmer ECG signals'); % Create a handle to figure for plotting data from shimmer
set(h.figure2, 'Position', [950, 500, 800, 400]);

elapsedTime = 0; % Reset to 0
tic; % Start timer

while (elapsedTime < captureDuration)

pause(DELAY_PERIOD); % Pause for this period of time on each iteration to allow data to arrive in the buffer
data = obj.obj.receiveData(); % Read the latest data from shimmer data buffer, signalFormatArray defines the format of the data and signalUnitArray the unit
newData = data(1);
signalNameArray = data(2);
signalFormatArray = data(3);
signalUnitArray = data(4);

signalNameCellArray = cell(numel(signalNameArray), 1);
for i = 1:numel(signalNameArray)
signalNameCellArray{i} = char(signalNameArray(i)); % Convert each Java string to a MATLAB char array
end

signalFormatCellArray = cell(numel(signalFormatArray), 1);
for i = 1:numel(signalFormatArray)
signalFormatCellArray{i} = char(signalFormatArray(i)); % Convert each Java string to a MATLAB char array
end

signalUnitCellArray = cell(numel(signalUnitArray), 1);
for i = 1:numel(signalUnitArray)
signalUnitCellArray{i} = char(signalUnitArray(i)); % Convert each Java string to a MATLAB char array
end

if(~isempty(signalNameCellArray))
chIndex(1) = find(ismember(signalNameCellArray, 'ECG_LL-RA_24BIT'));
chIndex(2) = find(ismember(signalNameCellArray, 'ECG_LA-RA_24BIT'));
chIndex(3) = find(ismember(signalNameCellArray, 'ECG_Vx-RL_24BIT'));
chIndex(4) = find(ismember(signalNameCellArray, 'ECG_LL-LA_24BIT'));
end

if (firsttime==true && isempty(newData)~=1)
firsttime = newWriteHeadersToFile(fileName,signalNameCellArray(chIndex),signalFormatCellArray(chIndex),signalUnitCellArray(chIndex));
end

if ~isempty(newData) % TRUE if new data has arrived

ECGData = newData(:,chIndex);
ECGDataFiltered = ECGData;
% filter the data
if HPF % filter newData with highpassfilter to remove DC-offset
ECGDataFiltered(:,1) = hpfexg1ch1.filterData(ECGDataFiltered(:,1));
ECGDataFiltered(:,2) = hpfexg1ch2.filterData(ECGDataFiltered(:,2));
ECGDataFiltered(:,3) = hpfexg2ch1.filterData(ECGDataFiltered(:,3));
ECGDataFiltered(:,4) = hpfexg2ch2.filterData(ECGDataFiltered(:,4));
end

if BSF % filter highpassfiltered data with bandstopfilter to suppress mains interference
ECGDataFiltered(:,1) = bsfexg1ch1.filterData(ECGDataFiltered(:,1));
ECGDataFiltered(:,2) = bsfexg1ch2.filterData(ECGDataFiltered(:,2));
ECGDataFiltered(:,3) = bsfexg2ch1.filterData(ECGDataFiltered(:,3));
ECGDataFiltered(:,4) = bsfexg2ch2.filterData(ECGDataFiltered(:,4));
end

if LPF % filter bandstopfiltered data with lowpassfilter to avoid aliasing
ECGDataFiltered(:,1) = lpfexg1ch1.filterData(ECGDataFiltered(:,1));
ECGDataFiltered(:,2) = lpfexg1ch2.filterData(ECGDataFiltered(:,2));
ECGDataFiltered(:,3) = lpfexg2ch1.filterData(ECGDataFiltered(:,3));
ECGDataFiltered(:,4) = lpfexg2ch2.filterData(ECGDataFiltered(:,4));
end

dlmwrite(fileName, double(ECGDataFiltered), '-append', 'delimiter', '\t','precision',16); % Append the new data to the file in a tab delimited format

plotData = [plotData; ECGData]; % Update the plotData buffer with the new ECG data
filteredplotData = [filteredplotData; ECGDataFiltered]; % Update the filteredplotData buffer with the new filtered ECG data
numPlotSamples = size(plotData,1);
numSamples = numSamples + size(newData,1);
timeStampNew = newData(:,1); % get timestamps
timeStamp = [timeStamp; timeStampNew];
if numSamples > NO_SAMPLES_IN_PLOT
plotData = plotData(numPlotSamples-NO_SAMPLES_IN_PLOT+1:end,:);
filteredplotData = filteredplotData(numPlotSamples-NO_SAMPLES_IN_PLOT+1:end,:);
end
sampleNumber = max(numSamples-NO_SAMPLES_IN_PLOT+1,1):numSamples;

set(0,'CurrentFigure',h.figure1);
subplot(2,2,1); % Create subplot
signalIndex = chIndex(1);
plot(sampleNumber,plotData(:,1)); % Plot the ecg for channel 1 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);

subplot(2,2,2); % Create subplot
signalIndex = chIndex(2);
plot(sampleNumber,plotData(:,2)); % Plot the ecg for channel 2 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);

subplot(2,2,3); % Create subplot
signalIndex = chIndex(1);
plot(sampleNumber,filteredplotData(:,1)); % Plot the filtered ecg for channel 1 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);

subplot(2,2,4); % Create subplot
signalIndex = chIndex(2);
plot(sampleNumber,filteredplotData(:,2)); % Plot the filtered ecg for channel 2 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);


set(0,'CurrentFigure',h.figure2);
subplot(2,2,1); % Create subplot
signalIndex = chIndex(3);
plot(sampleNumber,plotData(:,3)); % Plot the ecg for channel 1 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);

subplot(2,2,2); % Create subplot
signalIndex = chIndex(4);
plot(sampleNumber,plotData(:,4)); % Plot the ecg for channel 2 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);

subplot(2,2,3); % Create subplot
signalIndex = chIndex(3);
plot(sampleNumber,filteredplotData(:,3)); % Plot the filtered ecg for channel 1 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);

subplot(2,2,4); % Create subplot
signalIndex = chIndex(4);
plot(sampleNumber,filteredplotData(:,4)); % Plot the filtered ecg for channel 2 of SENSOR_EXG1
legendName1 = [char(signalFormatArray(signalIndex)) ' ' char(signalNameArray(signalIndex)) ' (' char(signalUnitArray(signalIndex)) ')'];
legend(legendName1); % Add legend to plot
xlim([sampleNumber(1) sampleNumber(end)]);

end

elapsedTime = elapsedTime + toc; % Update elapsedTime with the time that elapsed since starting the timer
tic; % Start timer

end

elapsedTime = elapsedTime + toc; % Update elapsedTime with the time that elapsed since starting the timer
fprintf('The percentage of received packets: %d \n',obj.shimmer.getPacketReceptionRateCurrent()); % Detect loss packets
obj.shimmer.stopStreaming(); % Stop data streaming

end

end

obj.shimmer.disconnect();

end

Loading