Real-time EMG signal acquisition-Plots
24 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Iro Liontou
el 12 de Oct. de 2024
Comentada: Iro Liontou
el 14 de Oct. de 2024
I am in the process of figuring out how to acquire my EMG signal in real - time and plot it, due to a lot delays that may occur from the for iteration the readVoltage function of Matlab, etc. What I was thinking is to just acquire a muscle contraction every 10 seconds for 1 minute. Below is the code that I used
%% Raw sEMG Signal Measuring with Precise Timing and X-Axis in Milliseconds
clc;
clear;
close all;
% Parameters
sampling_frequency = 1000; % Sampling frequency in Hz (1 kHz)
duration = 60; % Duration of signal acquisition in seconds
num_samples = sampling_frequency * duration; % Total number of samples
% Swallow timer setup
swallow_interval = 10; % Swallow every 10 seconds
next_swallow_time = swallow_interval; % Initial swallow time
% Initialize variables
x = zeros(num_samples, 1); % Array to store raw voltage data
time_ms = zeros(num_samples, 1); % Time array for accurate x-axis in milliseconds
% Connect to Arduino with higher baud rate (115200)
a = arduino('COM8', 'Uno', 'BaudRate', 115200); % Replace 'COMx' with your port
% Start acquisition and timing
start_time = tic; % Start the overall timer
% Start loop to acquire signal
for i = 1:num_samples
% Read voltage from analog pin A0
raw_voltage = readVoltage(a, 'A0');
% Store the raw voltage in the array
x(i) = raw_voltage;
% Calculate elapsed time for each sample in milliseconds
elapsed_time = toc(start_time) * 1000; % Convert to milliseconds
time_ms(i) = elapsed_time;
% Swallow notification logic
if elapsed_time >= next_swallow_time * 1000 % Convert to milliseconds
disp(['Time to swallow at t = ', num2str(next_swallow_time), ' seconds']);
next_swallow_time = next_swallow_time + swallow_interval; % Set next swallow time
% Optional: Play a sound or beep for notification
beep; % Beep sound (you can adjust with 'sound' for different notifications)
end
% Stop acquisition after the specified duration
if elapsed_time >= duration * 1000 % Convert duration to milliseconds
disp('Acquisition complete. Plotting the signal...');
break; % Exit the loop once the duration has passed
end
% Measure how long this iteration took
iteration_time = toc(start_time) * 1000 - elapsed_time; % In milliseconds
disp(iteration_time)
% Compensate for any delay in the loop to keep the sampling frequency consistent
if iteration_time < (1 / sampling_frequency) * 1000
pause((1 / sampling_frequency) - iteration_time / 1000); % Adjust to match the sampling rate
end
end
% Cleanup: Clear Arduino object when done
clear a;
% Plot the raw sEMG signal after acquisition (in milliseconds)
figure('Name', 'Raw sEMG Signal After Acquisition');
plot(time_ms(1:i), x(1:i)); % Only plot up to the last acquired sample
grid on;
title('Raw sEMG Signal After Acquisition');
xlabel('Time (ms)');
ylabel('Voltage (V)');
xlim([0, duration * 1000]); % Adjust x-axis to show time in milliseconds
ylim([0, 5]); % Adjust based on your expected voltage range
save('your_data_file.mat', 'x', 'time_ms'); % Save your variables to a .mat file and it actually plots the signal acquired every 10 seconds(it is messaging and beeping). The x-axis here is in ms.
When I am loading this signal with this code
%% sEMG Signal Analysis - Healthy Ingestion
clc;
clear;
close all;
%%%%%%%%%%%%%%%% Load sEMG Signal %%%%%%%%%%%%%%%%
% Load the saved raw sEMG signal x and the corresponding time array in ms
load('your_data_file.mat'); % Ensure x and time_ms are loaded properly
% Convert time from milliseconds to seconds
time_s = time_ms / 1000; % Convert milliseconds to seconds
% Parameters
sampling_frequency = 1000; % Adjust this to match your actual sampling frequency
tm = 1 / sampling_frequency; % Sampling period in seconds
N = length(x); % Number of samples
% Calculate total time duration
total_time = N * tm; % Total time in seconds
disp(['Total duration: ', num2str(total_time), ' seconds']);
% Display basic characteristics
disp(['Number of samples: ', num2str(N)]);
disp(['Sampling period: ', num2str(tm), ' seconds']);
% Extract EMG signal (assuming x is your EMG data)
EMGR = x'; % Transpose if necessary
% Plot the Raw EMG Signal (with time in seconds)
figure;
plot(time_s, EMGR, 'k'); % Plotting the EMG signal
title('Raw EMG Signal Over 60 Seconds');
xlabel('Time (s)');
ylabel('Magnitude (V)');
grid on;
ylim([-1.2 1.2]); % Adjust y-axis limits as per your requirements
xlim([0, 60]); % Adjust x-axis to 60 seconds
it plots the signal as it seems in the picture. it connects the last point with the first. why is this happening and how can I fix it?
0 comentarios
Respuesta aceptada
nick
el 13 de Oct. de 2024
Hi Iro,
The issue, where the plot connects the last point with the first point, is likely due to inclusion of zero values in the arrays 'x' and 'time_ms' which remained unassigned. This occurs because the preallocated arrays might have more elements than the actual acquired data, especially if the loop terminates early,as shown:
y = zeros(4,1)
x = zeros(4,1)
for i = 1:3
x(i) = i-1;
y(i) = x(i)^2;
end
x
y
plot(x,y)
To resolve this, you can plot only the portion of the arrays that contain valid data by using the loop index 'i' as shown:
% Extract EMG signal (assuming x is your EMG data)
EMGR = x(1:i)'; % Only use the data collected up to the last sample index
time_s_valid = time_s(1:i); % Corresponding time values
figure;
plot(time_s_valid, EMGR, 'k'); % Plotting the EMG signal
title('Raw EMG Signal Over 60 Seconds');
xlabel('Time (s)');
ylabel('Magnitude (V)');
grid on;
ylim([-1.2, 1.2]); % Adjust y-axis limits as per your requirements
xlim([0, 60]); % Adjust x-axis to 60 seconds
Hope this helps!
Más respuestas (0)
Ver también
Categorías
Más información sobre Data Acquisition Toolbox Supported Hardware en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!