Real-time EMG signal acquisition-Plots

24 visualizaciones (últimos 30 días)
Iro Liontou
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?

Respuesta aceptada

nick
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)
y = 4×1
0 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
x = zeros(4,1)
x = 4×1
0 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
for i = 1:3
x(i) = i-1;
y(i) = x(i)^2;
end
x
x = 4×1
0 1 2 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
y
y = 4×1
0 1 4 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
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!
  1 comentario
Iro Liontou
Iro Liontou el 14 de Oct. de 2024
Thanks Nick. I fixed it, but now I'm dealing with another issue that affects the above results. I want to acquire a real - time emg signal. The probelm is that the acquisition of the signal doesn't actually correspond to the elapsed time . Lte's say I want to acquire the signal for an elapsed time = 100 seconds. but the signal as it is acquired from the arduino doesn't even reach the 100 seconds as it plots in real time.
If you have any idea what might be the problem it would be really helpful. Thanks a lot!!

Iniciar sesión para comentar.

Más respuestas (0)

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!

Translated by