Arduino Matlab plotting



我正试图将数据从我的Arduino Leonardo发送到Matlab,然后绘制它。我尝试将正弦波传递到模拟输入,我能够在串行绘图仪上看到它。问题是,每当我将数据发送到Matlab并绘制它时,该图就不再是正弦波。

这是我的Arduino代码,我在这个链接的帮助下将其调整为1kHz采样,这对串行绘图仪的结果没有太大影响

#define INTERVAL_LENGTH_US 1000UL
unsigned long previousMicros;
#define FASTADC 1
int recValue;
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
double t = 0;

void setup() {
int start ;
int i ;
#if FASTADC
// set prescale to 16
sbi(ADCSRA, ADPS2) ;
cbi(ADCSRA, ADPS1) ;
cbi(ADCSRA, ADPS0) ;
#endif
Serial.begin(115200) ;
while (1)
{
if (Serial.available() > 0)
{
recValue = Serial.read();
if  (recValue == 1)            // If use will send value 1 from MATLAB
{ //delay(10);
Serial.println("g");
break;
}
}
}

void loop()
{
unsigned long currentMicros = micros();
if ((currentMicros - previousMicros) >= INTERVAL_LENGTH_US)
{
previousMicros += INTERVAL_LENGTH_US;
int val_a0 = analogRead(A0);
int val_a1 = analogRead(A1);
int val_a2 = analogRead(A2);
int val_a3 = analogRead(A3);

Serial.println(val_a0);

Serial.println(val_a1);
Serial.println(val_a2);

Serial.println(val_a3);
}
}

编辑:我把电路板换成了UNO电路板(不使用虚拟通信端口),并设法转移了它。但当我实时绘制它时,我成功地绘制了一小段时间(700个样本)。我知道Arduino是连续发送正弦波,只是在matlab中,我只得到了它的一部分

收到的正弦

我在Matlab中用来接收和绘制它的代码如下:

clear all;
s = serial('COM4', 'BaudRate', 250000); % setup comport
fopen(s);
t=[0]; v1=[0]; v2=[0];v2=[0];v3=[0]; v4=[0];                            % same as in Arduino IDE
n=1;h1=0; h2=0; h3=0; h4=0; base=0.0; x=[];  reply = '1';
% signalling to Arduino to start reading inputs
servalue= input('Enter the value 1 to start reading :');
pause(1);tic;
fprintf(s,servalue);
%Arduino will send an acknowledgment
reply = fgetl(s);
if(reply~='g')
disp('fail')
end
%%%%%%%%%%%%%%%%%%setting the plots%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
figure; subplot(411) ;
h1 = plot( v1, 'r-');
%animatedline(nan,nan); % Save handle to the line
title('Channel 1');
ylabel('Amplitude(V)');
subplot(412); h2= plot( v2, 'r-');
%animatedline(nan,nan); % Save handle to the line
title('Channel 2');
ylabel('Amplitude(V)');

subplot(413); h3= plot( v3, 'r-');
%animatedline(nan,nan); % Save handle to the line
title('Channel 3');
ylabel('Amplitude(V)');
subplot(414); h4= plot( v4, 'r-');
%animatedline(nan,nan); % Save handle to the line
title('Channel 4');
xlabel('Time (seconds)');
ylabel('Amplitude(V)');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
while(toc<50)
v1 = [v1, str2double(fgetl(s))*(5.0 / 1023.0)];
v2 = [v2, str2double(fgetl(s))*(5.0 / 1023.0)];
v3 = [v3, str2double(fgetl(s))*(5.0 / 1023.0)];
v4 = [v4,str2double(fgetl(s))*(5.0 / 1023.0)];
%% %%%%%%%updating plots%%%%%%%%%%%%%%%%%%
set(h1,  'ydata', v1); % Update plot
set(h2,  'ydata', v2); % Update plot
set(h3,  'ydata', v3); % Update plot
set(h4,  'ydata', v4); % Update plot
drawnow;
n=n+1;
end
fclose(s);

以下是4个通道的响应:4通道的响应

看起来您的问题是一些数据被丢弃,并且使数据的发送和接收不同步。

理想情况下,您希望发送一个流,如:

...Ch1-Ch2-Ch3-Ch4-Ch1-Ch2-Ch3-Ch4-Ch1-Ch2-Ch3-Ch4-Ch1-Ch2-Ch3-Ch4...

并在Matlab中接收,如:

V1    V2    V3    V4
Ch1 - Ch2 - Ch3 - Ch4
Ch1 - Ch2 - Ch3 - Ch4
Ch1 - Ch2 - Ch3 - Ch4
Ch1 - Ch2 - Ch3 - Ch4

但是,无论出于何种原因,如果有一些数据丢失,那么您的通道将混合:

您的流看起来像:

...Ch1-Ch2-Ch3-Ch4-Ch1-Ch2- -Ch4-Ch1-Ch2-Ch3- -Ch1-Ch2-Ch3-Ch4-Ch1-Ch2...

因此,你在Matlab中的程序将把这些数据作为

V1    V2    V3    V4
Ch1 - Ch2 - Ch3 - Ch4
Ch1 - Ch2 - Ch4 - Ch1
Ch2 - Ch3 - Ch1 - Ch2
Ch3 - Ch4 - Ch1 - Ch2

正如您所看到的,它可以工作一段时间,但当数据被丢弃时,所有的协调都会丢失。

有几种方法可以解决这个问题。搜索"同步串行通信",你会发现几种方法。

在这种情况下,我建议在一行中发送所有用逗号分隔的通道,然后在matlab中进行分隔。在Arduino方面:

Serial.print(val_a0);
Serial.print(',');
Serial.print(val_a1);
Serial.print(',');
Serial.print(val_a2);
Serial.print(',');
Serial.println(val_a3);

然后在Matlab端

data=strsplit(fgetl(s),',');
if lenght(data)==4
v1 = [v1, str2double(data(1))*(5.0 / 1023.0)];
v2 = [v2, str2double(data(2))*(5.0 / 1023.0)];
v3 = [v3, str2double(data(3))*(5.0 / 1023.0)];
v4 = [v4, str2double(data(4))*(5.0 / 1023.0)];
end

请注意,这只会修复同步,但如果接收到部分数据,则可能会引入其他错误。你可以用一些try-catch语句来处理这个问题

最新更新