Speed up serial Communication with parallel computing

4 次查看(过去 30 天)
Hello everybody,
I have a Mikrocontroller, which (with the help of a gain and phase detector) measure the gain and phase signals of a RLC-Circuit. I want to process and display the signals on the pc with matlab. The problem is that the serial communication is very slow. I want to make it faster by using parallel computing. I want to divide my code in two sections: One section (or one Worker) is reading out the Data and process it and the other is plotting it (Live plotting with drawnow). This all repeats continious in a while-loop. Meanwhile the second worker is plotting, the Data must be read out again. In these case i can make it faster. below is my Code.
The Problem i have is that the second worker only print the first fprintf (The "Resonanzfrequenz"). Their is no plotting. Furthermore i do not feel that the speed is increased. Can somebody help me?
spmd
switch labindex
case 1
%Verbindung zum Mikrocontroller aufbauen
if ~isempty(instrfind)
fclose(instrfind);
delete(instrfind);
end
%Port vom User angeben lassen, andem der Arduino angeschlossen ist
s=serial('COM4','BaudRate',9600); %Einrichten der seriellen Schnittstelle
fopen(s);
fprintf(s,'%s\n',num2str(freq_start));
fprintf(s,'%s\n',num2str(freq_stop));
fprintf(s,'%s\n',num2str(freq_schritt));
fprintf(s,'%s\n',num2str(messung_start));
messdaten = zeros(1,(messwerte_max)+1);
for i=1:(messwerte_max+1)
messdaten(i) = str2double(fscanf(s)); %Speichern der Messdaten /Gibt ascii code aus aber betrachtet jeden char einzeln
end
fclose(s);
labSend(messdaten,2);
case 2
messdaten = labReceive(1);
amplitude=zeros(1,scala);
phase=zeros(1,scala);
temperatur = messdaten(messwerte_max+1);
inkrement = 1;
i = 1;
while inkrement <= messwerte_max
phase(1,i) = messdaten(1,inkrement);
inkrement = inkrement + 1;
amplitude(1,i) = messdaten(1,inkrement);
inkrement = inkrement + 1;
i = i + 1;
end
f=freq_start:freq_schritt:freq_stop; % Frequenzvektor
f=double(f);
amplitude(1:10)=amplitude(10);
phase(1:10)=phase(10);
% Umrechnen der Messdaten zu Volt-Werten
amplitude = amplitude.*(3.3/2^13);
phase = phase.*(3.3/2^13);
% Umrechnung der Messdaten in dB für die Amplitude und Grad für Phase
amplitude=(amplitude-0.9)./0.03;
phase=-(((0.9-phase)./0.01)+90);
% -------------------------------------------- Rauschunterdrückung mit Wavelets ----------------------------------------------------
amplitude_bereinigt=Rauschunterdrueckung(amplitude);
phase_bereinigt=Rauschunterdrueckung(phase);
% -----------Berechnung der Frequenz - und Dissipationsänderung-------------
% Ermittlung der Resonanzfrequenz
peak_height = 0.8*max(amplitude_bereinigt);
peak_distance = 10^6;
[amp_max, fr]=findpeaks(amplitude_bereinigt,f,'MinPeakHeight',peak_height, 'MinPeakDistance',peak_distance);
% Ermittlung des Dissipationsfaktors
max_half = amp_max/2;
% Ermittlung der beiden Frequenzen, die die Halbwertsbreite bilden
diff = 1;
f_half1 = 0;
f_half2 = 0;
for i=1:length(amplitude_bereinigt)
kandidat_diff = abs(max_half-amplitude_bereinigt(i));
if diff > kandidat_diff
diff = kandidat_diff;
f_half1 = f(i);
x1=amplitude_bereinigt(i);
end
if amplitude_bereinigt(i) == amp_max
break;
end
end
diff = 1;
for i=i:length(amplitude_bereinigt)
kandidat_diff = abs(max_half-amplitude_bereinigt(i));
if diff > kandidat_diff
diff = kandidat_diff;
f_half2 = f(i);
x2=amplitude_bereinigt(i);
end
end
% Halbwertsbreite
FHWM = abs(f_half2-f_half1);
% Dissipation
D = FHWM/fr;
% ne Umrechnung
fr = fr/10^6;
% Ausgabe
fprintf('Resonanzfrequenz: %d MHz\n', fr);
fprintf('Dissipation: %d\n', D);
fprintf('Temperatur: %d\n',temperatur);
figure(1);
subplot(2,1,1);
plt1 = plot(NaN,NaN,'b'); % Plot empty line
hold on;
grid on;
axis([min(f) max(f) min(amplitude_bereinigt) max(amplitude_bereinigt)]);
title('Rauschbefreites Amplitudensignal')
xlabel('Frequenz/[MHz]');
ylabel('Amplitude/[dB]');
subplot(2,1,2);
plt2 = plot(NaN,NaN,'r'); % Plot empty line
hold on;
grid on;
axis([min(f) max(f) min(phase_bereinigt) max(phase_bereinigt)]);
title('Rauschbefreites Phasensignal')
xlabel('Frequenz/[MHz]');
ylabel('Phase/[°]');
for k = 1:length(amplitude)
set(plt1,'XData',f(1:k),'YData', amplitude_bereinigt(1:k));
set(plt2,'XData',f(1:k),'YData', phase_bereinigt(1:k));
pause(0.01);
drawnow limitrate
end
delete(plt1);
delete(plt2);
end
end

采纳的回答

Walter Roberson
Walter Roberson 2021-3-3
When you plot inside a parallel worker of any kind, the result cannot be sent to the user display.
  5 个评论
Walter Roberson
Walter Roberson 2021-3-10
If you are using USB to the arduino instead of true serial port:
Are you emitting a newline after every number? If so then change that to emit a newline less often, even if it is after every pair of numbers would help. USB has a limit on the number of "transactions per second", and newlines can potentially signal the end of a transaction. For USB purposes you would prefer to fill as close to 1020 characters as possible per packet... if you were to group 100 pairs, (4 digits+delimiter)*2*100 -> 1000 characters per packet then your throughput would improve.... at the cost of greater latency, and inability to track the times of the individual readings.
Fire Phoenix
Fire Phoenix 2021-3-15
Thank you very much! I could reduce the execution time to 3 seconds!

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 MATLAB 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by