Getting current time on x-axis using Design app - GUI

Hello! I'm trying to use GUI app to plot real-time data and I can only get the x-axis to show the elapsed time in seconds, but I would like to get the current clock time, like 13:48:17. I've tried a few things but nothing seems to work, I would really appreciate your help. Also I would like the plot to update every 1sec rather than constantly, but don't know if that is defined on the hGui function or on the dataCapture function.
I'm using the code in this page https://www.mathworks.com/help/daq/software-analog-triggered-data-capture.html, and I think I've got to edit the hGui function somewhere in this part:
hGui.Axes1 = gca;
hGui.LivePlot = plot(0, zeros(1, numel(s.Channels)));
xlabel('Time (s)');
ylabel('Voltage (V)');
title('Continuous data');
legend({s.Channels.ID}, 'Location', 'northwestoutside')
hGui.Axes1.Units = 'Pixels';
hGui.Axes1.Position = [207 391 488 196];
% Turn off axes toolbar and data tips for live plot axes
hGui.Axes1.Toolbar.Visible = 'off';
disableDefaultInteractivity(hGui.Axes1);
This is how I'm acquiring data:
[eventData, eventTimestamps] = read(src, src.ScansAvailableFcnCount,'OutputFormat', 'Matrix');
If I could change evenTimestamps to the current time in the format 'HH:MM:SS', I think that would do it, because in the matrix instead of the miliseconds I would be getting the current time.
Or maybe I've got to edit the dataCapture function in this part:
% Update x-axis limits
xlim(hGui.Axes1, [dataBuffer(firstPoint,1), dataBuffer(end,1)]);
% Live plot has one line for each acquisition channel
for ii = 1:numel(hGui.LivePlot)
set(hGui.LivePlot(ii), 'XData', dataBuffer(firstPoint:end, 1), ...
'YData', dataBuffer(firstPoint:end, 1+ii))
end
It may not have anything to do with editing either of this code parts so I would really like someones help :)

2 comentarios

Teresa - so you want to show the current time along the x-axis? Where is the time data that corresponds to the buffered data?
I don't know what that means

Iniciar sesión para comentar.

 Respuesta aceptada

The same way you would do it in MATLAB. If your duration corresponds to daytime, then you can just set the format of your xdata using xtickformat.
x=seconds(4800:50:5900);
y = rand(size(x));
plot(x,y)
xtickformat('hh:mm:ss')

24 comentarios

Teresa Carneiro
Teresa Carneiro el 5 de Jul. de 2021
Editada: Teresa Carneiro el 5 de Jul. de 2021
I want to show something like this, with the current time on the x axis, and I don't know where to introduce it in the code I have, which is the one from https://www.mathworks.com/help/daq/software-analog-triggered-data-capture.html
I was previously able to do it using:
h = animatedline;
for i = 1:100
% Add points to animated line
if isvalid(h)
addpoints(h, datenum(t), voltage1(i))
end
end
% Update axes
ax.XLim = datenum([t-seconds(15) t]);
datetick('x','keeplimits')
drawnow
But I don't know where to place this on those functions
I've tried this on the dataCapture function, but it doesn't run the code, and the x-axis turn out like in the photo anexed to this comment... don't know why, can someone help me please?
% Update x-axis limits
t = datetime('now','Format','HH:mm:ss');
xlim(hGui.Axes1, datenum([t-15, t]));
datetick('x','keeplimits');
drawnow
I did try to help, but the approach you have posted appears not to have used the solutoin I suggested.
But your solution doesn't show the current time on the x-axis and I did not quite get where I would insert that part of the code. Would love for you to help :)
Then perhaps we don't have enough information yet to propose a solution for your specific case. What is the difference between your elapsed time and time-of-day? Is it always the same amount?
Teresa Carneiro
Teresa Carneiro el 6 de Jul. de 2021
Editada: Teresa Carneiro el 6 de Jul. de 2021
I want to run the code for at least 5 minutes, and I don't want the x-axis to show the elapsed time, I want it to show the current time when I'm running the programme. I was able to do it before, when I was not using GUI. I want a graph like this https://www.mathworks.com/matlabcentral/answers/uploaded_files/674938/WhatsApp%20Image%202021-07-05%20at%2012.01.07.jpeg
instead of something like this https://www.mathworks.com/matlabcentral/answers/uploaded_files/676053/WhatsApp%20Image%202021-07-06%20at%2014.54.34.jpeg which is what I'm getting using the code as it is. I know I have to use something like:
t = datetime('now','format','HH:mm:ss')
But I've tried to insert it in a lot of places in the dataCapture function and nothing seems to work...
Again, how does your elapsed time compare to time-of-day? Changing the display format does not automatically convert elapsed time to time-of-day. It just changes how the elapsed time is displayed. If you want it to reflect actual time-of-day, then you will have to perform some calculations.
In order to perform that calculation, you will probably need to know the time-of-day you started collecting data, and add the elapsed time to it to get time-of-day.
Here's a simple example that I based off your original post. The pause is there only to give the appearance of plotting in real time.
d = datetime("now");
t = seconds(5:5:300);
ph = plot(d,0);
xtickformat('hh:mm:ss')
for i = 1:length(t)
% Add points to animated line
ph.XData = [ph.XData d+t(i)];
ph.YData = [ph.YData rand(1)];
pause(.1)
end
What do you mean "how does your elapsed time compare to time-of-day?" I need it to show me the current time every second. This was my code using just matlab, maybe it can make you understand what I want a little better, and I didn't need to make any calculations on this code, it just showed me the current time I started recording data:
clear
close all
time = 0;
data = 0;
% Set up the plot
figure(1)
plotGraph = plot(time,data,'-r' );
title('DAQ data log','FontSize',15);
xlabel ('Elapsed Time (s)','FontSize',10)
ylabel('Voltage (V)','FontSize',10);
h = animatedline;
ax = gca;
ax.YGrid = 'on';
ax.XGrid = 'on';
% Set up the data acquisition
dq = daq("ni");
ch1 = addinput(dq, "Dev1", "ai0", "Voltage");
dq.Rate = 1000;
% Start the data acquisition
start(dq, "Duration", seconds(20))
n = ceil(dq.Rate/10);
% Open the text file
data = read(dq, n);
writetimetable(data,'data.txt','Delimiter','bar');
type 'data.txt';
while ishandle(plotGraph)
data = read(dq, n)
writetimetable(data,'data.txt','Delimiter','bar','WriteMode','append');
type 'data.txt';
voltage1 = data.Dev1_ai0;
t = datetime('now');
for i = 1:100
% Add points to animated line
if isvalid(h)
addpoints(h, datenum(t), voltage1(i))
end
end
% Update axes
ax.XLim = datenum([t-seconds(15) t]);
datetick('x','keeplimits')
drawnow
end
disp('Plot Closed')
And I don't know where I should insert this code you just gave me. In the function where I acquire the data or in the function that creates the GUI? Sorry for the trouble but I'm very new in matlab
Elapsed time is time from start of acquisition: [0 5 10 15] in seconds, for example.
Time of day is, well, daytime: [ 11:00:00 11:00:05 11:00:10 11:00:15].
If your data is collected in elapsed time, and you want to display it as day time, you will have to convert elapsed time to time of day somehow. If I know I start acquistion at 11:00:00, then the difference between the two is exactly 11 hours. Knowing that, then I just need to add 11 hours to my elapsed time to get time of day.
Perhaps the best thing would be for you to attach your file data.txt to your post. Use the papercilp icon.
I will start my data acquisition at a different time every day, that's why I wanted to use the function datetime('now') because it just gives me the current time. I get what you're saying but If you see my code in my last comment you see that the x-axis is constantly updating with the current time, instead of working with elapsed time, that's what I want, not elapsed time, just current time, constantly updating on the x-axis. Just don't know how to do it on GUI.
I'm not sure your code is doing what you want. For example, I think the for loop in this code will plot all 100 points at the same x location, so it will look like a vertical line rather than a continous stream of data.
while ...
...
t = datetime('now');
for i = 1:100
% Add points to animated line
if isvalid(h)
addpoints(h, datenum(t), voltage1(i))
end
end
...
end
In app designer, I would likely make an approach similar to what you have done. Perhaps with the following changes.
hGui.LivePlot = plot(hGui.Axes1, 0, seconds(zeros(1, numel(s.Channels))));
xlabel('Time (s)');
ylabel('Voltage (V)');
title('Continuous data');
xtickformat('hh:mm:ss')
legend({s.Channels.ID}, 'Location', 'northwestoutside')
hGui.Axes1.Units = 'Pixels';
hGui.Axes1.Position = [207 391 488 196];
% Turn off axes toolbar and data tips for live plot axes
hGui.Axes1.Toolbar.Visible = 'off';
disableDefaultInteractivity(hGui.Axes1);
...
% Update x-axis limits
xlim(hGui.Axes1, [dataBuffer(firstPoint,1), dataBuffer(end,1)]);
% Live plot has one line for each acquisition channel
for ii = 1:numel(s.Channels)
hGui.LivePlot(ii).XData = dataBuffer(firstPoint:end, 1);
hGui.LivePlot(ii).YData = dataBuffer(firstPoint:end, 1+ii));
drawnow
end
Note that this approach will add the entire buffer of data to the plot all at once. If you want to add it point by point, you will need to add another loop.
for r = firstPoint:size(dataBuffer,1)
for ii = 1:numel(s.Channels)
hGui.LivePlot(ii).XData = dataBuffer(r, 1);
hGui.LivePlot(ii).YData = dataBuffer(r, 1+ii));
end
drawnow
end
It doesn't accept the xtickformat (I've attached a photo with the error), I think that you can only use it if you specify before that the x-axis has datetimes. But I've tried without it and it doesn't work... Do you have any other suggestions?
If your time is of type duration, then your format string is wrong. Durations do not accept 'HH'. Use lowercase h instead.
See accepted format syntaxes here.
I've tried that as well and error is the same (see attached photo)
Cris LaPierre
Cris LaPierre el 7 de Jul. de 2021
Editada: Cris LaPierre el 7 de Jul. de 2021
Share your files and data.
I'm acquiring them from a DAQ board on real time, it's always different, it's not a file I have
Save some to a file. From code you posted earlier
data = read(dq, n)
writetimetable(data,'data.txt','Delimiter','bar','WriteMode','append');
I can figure out how to get the app to use it instead of the daq.
Oh yeah that I can do. The data file is attached, as well as the plot I got with the same data.
Please share your code as well. Best is to zip it all together and post the zip.
Please keep in mind this code is exactly what I want (in terms of x-axis), but I need to get it using the GUI app
Then please share your GUI files.
Teresa Carneiro
Teresa Carneiro el 8 de Jul. de 2021
Editada: Teresa Carneiro el 8 de Jul. de 2021
I'm using these functions https://www.mathworks.com/help/daq/software-analog-triggered-data-capture.html. But the zipped folder with the 4 functions is attached :)
Not perfect, but this works for what I was trying to create. You will likely have to modify to get it to do exactly what you want.
Main changes:
1. in createDataCaptureUI, create the plot using a time for your x value instead of 0. I used datetime("now"). You'll want to add this value to hGui so it is available to adjust your time data in dataCapture. This is where you set xtickformat as well. Here is just the subset with all 3 changes.
...
hGui.t0 = datetime("now");
% Create the continuous data plot axes with legend
% (one line per acquisition channel)
hGui.Axes1 = axes;
hGui.LivePlot = plot(hGui.t0, zeros(1, numel(s.Channels)));
xlabel('Time (s)');
ylabel('Voltage (V)');
title('Continuous data');
xtickformat('HH:mm:ss');
...
2. In dataCapture, I've assumed your XData is elapsed time in seconds. To make it day time, I need to convert the first column of dataBuffer to seconds and add hGui.t0 to it. The xlim command is setting what data is displayed. I don't know what you want, so I set it to just show the new data. You can modify this to meet your requirements.
...
% Update x-axis limits
xlim(hGui.Axes1, hGui.t0 + seconds(dataBuffer([firstPoint end], 1)'));
% Live plot has one line for each acquisition channel
for ii = 1:numel(hGui.LivePlot)
hGui.LivePlot(ii).XData = hGui.t0 + seconds(dataBuffer(firstPoint:end, 1));
hGui.LivePlot(ii).YData = dataBuffer(firstPoint:end, 1+ii);
end
...
I left all other code the same. Here is the resulting plot in the gui.
My value for hGui.t0 was 08-Jul-2021 13:23:43 and the diatafile you shared had ~6.8 seconds of data collected at a rate of 1000 scans/second.
Teresa Carneiro
Teresa Carneiro el 9 de Jul. de 2021
Editada: Teresa Carneiro el 9 de Jul. de 2021
Thank you so much!!! It worked :))))

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Productos

Versión

R2021a

Preguntada:

el 2 de Jul. de 2021

Editada:

el 9 de Jul. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by