Real-time EMG signal acquisition-Plots
23 次查看(过去 30 天)
显示 更早的评论
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 个评论
采纳的回答
nick
2024-10-13
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!
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Data Acquisition Toolbox Supported Hardware 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!