Clear Filters
Clear Filters

How to avoid UDP-sampling tied to code execution time without buffer

5 views (last 30 days)
I am trying to use udpport to sample data from a netFT device that theoretically can sample at 7000 Hz. I am not experienced in using UDP (and udpport) but found some code that can collect the data. However it collects the data without timestamps, which i added, and the sampling period is irregular to highly ireggular. The sampling freqency is also depended on how much i do in between (upd)-read commands which is a problem as I also want a live plot-feed of the data. For the plotting I have some ideas for some home made burst-chunk sampeling, but the problem is having consistent sampeling times and preferble close to the 7000 hz sampeling rate.
In bare a bones version i get the sampeling to about 3000 hz (with a devition of up to ~40% in a 1000 sampels) but this drops down to about 1000 hz when using the "flush(u)" and introduces "lag-spikes" (sample freq ~ 5 hz for 1-5 samples) around every 200:th sample. But it seems the flush is need if I want a functional live-plot. With a live plot i go down to about 10-25 hz sampling frequency.
Is there some sort of buffer in udp-read that can be used to collect larger chunks of the data?
Is there a better way to get timestamps?
Tips on how do i get a stable sampling-frequency not dependent on the computers execution time (I am ok with sampling freqency of about 500 hz)?
u = udpport('byte', 'IPV4');
netFT = "";
port = 49152;
startCommand="Special Hex Start-String"; % [Non functional exampel]
write(u, startCommand, "string", netFT, port) % send message to start rdt streaming
numIterations = 1000;
for i = 1:numIterations
[result(i,:), TimeStamps(i)] = netFT_getFreshData(u);
% [Yes there are much better ways to plot things in loops, but this is a placeholder]
function [ data, TimeStamp ] = netFT_getFreshData(u)
% 1:4 = rdt_sequence / 5:8 = ft_sequence / 9:12 = status
% 13:16 = Fx / 17:20 = Fy / 21:24 = Fz
% 25:28 = Tx / 29:32 = Ty / 33:36 = Tz
flush(u, "input") %[is needed for accurate live ploting but slow down sampling and gives large lag-spikes]
data = read(u, 36); %[Is there a buffer / how do i get all the data?]
TimeStamp=datetime("now"); %[Is this a "good" way to get time stamps?]
  1 Comment
Magnus on 26 Jan 2024
The upd object inded has a buffer, just needed to change the number of data points read. About 36*500 seems to do the trick for now.
Clearing the buffer with flush seems to be a bad idea as the timing get wrong and data point seems to be lost.
But if I now get a set amount of data from the buffer should I not get dublicate data if I fetch the data again before 500 new sampels have been generated? It did not seem to be the case nor did it seem to be missing any sampels.

Sign in to comment.

Answers (1)

akshatsood on 5 Feb 2024
Edited: akshatsood on 6 Feb 2024
From what I understand, you are attempting to sample data from a netFT device using "udpport" at a theoretical sampling rate of 7000 Hz. The requirements can be summarised as follows
  1. Using "flush" for live plotting slows down sampling and ouputs large lag-spikes
  2. Achieving a stable sampling frequency that is not dependent on the computer's execution time.
  3. A better method to add timestamps to the sampled data.
Here are some recommendations that might be helpful for the issue in response to the requirements mentioned above
  1. Avoid Flushing the Buffer on Every Call: flushing the input buffer on every data read can be very inefficient and cause lag spikes. Instead, consider reading the data more frequently or adjusting the buffer size if possible. This can help ensure that you do not miss out on data while avoiding the need to flush the buffer as often.
  2. Optimize Plotting: creating a new figure in the loop with "figure(1)" is unnecessary and can slow down the execution. Instead, create the figure outside the loop and update the plot data within the loop.
  3. Stable Sampling Frequency and Timestamps: In response to achieving a stable sampling frequency and a better method for adding timestamps, a more detailed investigation would be required, I will look into it and update you as and when I find something.
Nevertheless, I have tried to incorporate the first two requirements mentioned above in your code snippet. Please try the updated code and let me know if this assits in addressing the issue.
u = udpport('byte', 'IPV4');
netFT = "";
port = 49152;
startCommand = "Special Hex Start-String"; % replace with actual command
write(u, startCommand, "string", netFT, port); % send start message
numIterations = 1000;
result = zeros(numIterations, 6);
TimeStamps = NaT(numIterations, 1);
% set up figure and plot
hPlot = plot(NaT, zeros(numIterations, 1));
flushInterval = 10; % flush every 10 iterations, adjust as needed
iterationCounter = 0;
for i = 1:numIterations
[result(i,:), TimeStamps(i)] = netFT_getFreshData(u, iterationCounter, flushInterval);
% update the plot
set(hPlot, 'XData', TimeStamps, 'YData', result(:, 1));
drawnow limitrate;
iterationCounter = iterationCounter + 1;
function [data, TimeStamp] = netFT_getFreshData(u, iterationCounter, flushInterval)
% read data and record timestamp
data = read(u, 36*500);
TimeStamp = datetime("now");
% flush conditionally based on the iteration counter
if mod(iterationCounter, flushInterval) == 0
flush(u, "input");
I hope this helps.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!