Speed up serial Communication with parallel computing

조회 수: 4 (최근 30일)
Fire Phoenix
Fire Phoenix 2021년 3월 3일
댓글: Fire Phoenix 2021년 3월 15일
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