Arduino Matlab绘图

时间:2017-01-26 04:06:13

标签: matlab arduino

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

这是我的Arduino代码,我已经在link的帮助下对其进行了调整,以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中,我只得到它的一部分。这是我的意思的截图:

Recieved sine

我在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 channels' response

1 个答案:

答案 0 :(得分:0)

看起来您的问题是某些数据被删除并导致数据的发送和接收失去同步。

理想情况下,您希望发送类似:

的流
...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语句处理它