Arduino Matlab Connection-Low Frequency

Hi,

i’m currently Building a device which prints Data from a microphone (recorded by arduino) to matlab, where i perform a fft.

The attachment Shows the difference between the time Signals, so it should be 1/SampleRate.

Can someone explain what and why is Happening there? And how to solve this?

Some Data: Arduino Uno(16MHz)
Matlab 2015
BaudRate:34800

Can someone explain what and why is Happening there?

With what you've told us?
Seems unlikely, don't you think?

I'm going to guess that the serial I/O is limiting the sample rate after the print buffer fills. More significantly, it makes it non-determinant. A faster serial rate would delay this happening, but it would be better if you explicitly moderate the sample rate on the Arduino side.

As AWOL notes it's kind of hard to address issues with code we haven't seen.

Ok, youre surely right :smiley: I hoped its a maybe a known Problem which can be solved instant with such poor Information.

So: Current Stadium is that LEDs are blinking depending on Signal Amplitude. I already deleted this part,nothing changed.

If the Baudrate is above ~12kBd, the results are the same.

I am using a Matlab Gui for reading the Data.

The important Arduino Code is:
outputV=0;

Serial.begin(34800);
OutputReadVoltage=analogRead(outputV);
Dif2=(int) (average-OutputReadVoltage);
Serial.println(Dif2,DEC);

The MatLab computing:

tic
while toc<30
    ZwSpeicher=fscanf(ardSer,'%d');
    %check datatype of read data; otherwise errors break the code
    c=class(ZwSpeicher);
    if (isa(c,'double'))||length(ZwSpeicher)~=1;
        ZwSpeicher=0;
        errors=errors+1;
    end
    SerialData(curSample)=ZwSpeicher;
    TimeData(curSample)=toc;
%     if curSample>50&&mod(curSample,20)==0
%         plot(handles.RealTimePlot,TimeData(end-50:end),SerialData(end-50:end));
%         drawnow;
%     end
    
    curSample=curSample+1;
end

DiffTimeData=diff(TimeData);

assignin('base','DiffTimeData',DiffTimeData);

tend=second(datetime);

The full Code is in Attachments, .m files are forbidden in this Forum i think (?)

Does someone know where the analogread Data are stored?

Mikrofon5.ino (3.42 KB)

The important part of my answer is: Post your code

Maybe i should have mentioned i’m using the guide, so my Code is too long for posting it.

Full Arduino Code:

int outputV=1;
int GroundOutput=4;
int OutputReadVoltage;
int GrLED1=5;
int GrLED2=6;
int GrLED3=7;
int GrLED4=8;
int GeLED1=9;
int GeLED2=10;
int RoLED1=11;
int StandardVoltage=500;
int ResetP=2;
double sum;
int average;
int Dif=0;
int Dif2;
int Selec=0;
long timer;

void setup() {
  // put your setup code here, to run once:
  pinMode(outputV,INPUT);
  pinMode(GroundOutput,OUTPUT);
  pinMode(ResetP,INPUT);
  Serial.begin(34800);
  pinMode(3,OUTPUT);
  pinMode(4,INPUT);
  
  
}

void loop() {
  // put your main code here, to run repeatedly:
  OutputReadVoltage=analogRead(outputV);
  Dif=(int) abs((average-OutputReadVoltage));
  Dif2=(int) (average-OutputReadVoltage);
  
  //analogWrite(GroundOutput,average/4);
  
  if (Dif<=2){
    Selec=0;
  }
 
  if (Dif>2){
   Selec=1;
    
  }
  if (Dif>4){
    Selec=2;
  
  }
   if (Dif>6){
    Selec=3;
  }
   if (Dif>8){
   Selec=4;
  
  }
   if (Dif>11){
    Selec=5;
  
  }
   if (Dif>14){
    Selec=6;
  }
   if (Dif>19){
    Selec=7;
    }
  if (millis()%30<=2){
  switch (Selec){
    case 0:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,LOW);
      digitalWrite(GrLED3,LOW);
      digitalWrite(GrLED4,LOW);
      digitalWrite(GeLED1,LOW);
      digitalWrite(GeLED2,LOW);
      digitalWrite(RoLED1,LOW);
      
      
    break;
    }
    case 1:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,LOW);
      digitalWrite(GrLED3,LOW);
      digitalWrite(GrLED4,LOW);
      digitalWrite(GeLED1,LOW);
      digitalWrite(GeLED2,LOW);
      digitalWrite(RoLED1,LOW);
            
      break;      
    }
    case 2:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,HIGH);
      digitalWrite(GrLED3,LOW);
      digitalWrite(GrLED4,LOW);
      digitalWrite(GeLED1,LOW);
      digitalWrite(GeLED2,LOW);
      digitalWrite(RoLED1,LOW); 
      
      break;   
    }
    case 3:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,HIGH);
      digitalWrite(GrLED3,HIGH);
      digitalWrite(GrLED4,LOW);
      digitalWrite(GeLED1,LOW);
      digitalWrite(GeLED2,LOW);
      digitalWrite(RoLED1,LOW);
      
      break;    
    }
    case 4:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,HIGH);
      digitalWrite(GrLED3,HIGH);
      digitalWrite(GrLED4,HIGH);
      digitalWrite(GeLED1,LOW);
      digitalWrite(GeLED2,LOW);
      digitalWrite(RoLED1,LOW);
      
      break; 
         
    }
    case 5:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,HIGH);
      digitalWrite(GrLED3,HIGH);
      digitalWrite(GrLED4,HIGH);
      digitalWrite(GeLED1,HIGH);
      digitalWrite(GeLED2,LOW);
      digitalWrite(RoLED1,LOW);
      
      break;    
    }
    case 6:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,HIGH);
      digitalWrite(GrLED3,HIGH);
      digitalWrite(GrLED4,HIGH);
      digitalWrite(GeLED1,HIGH);
      digitalWrite(GeLED2,HIGH);
      digitalWrite(RoLED1,LOW);
      
      break;    
    }
    case 7:{
      digitalWrite(GrLED1,HIGH);
      digitalWrite(GrLED2,HIGH);
      digitalWrite(GrLED3,HIGH);
      digitalWrite(GrLED4,HIGH);
      digitalWrite(GeLED1,HIGH);
      digitalWrite(GeLED2,HIGH);
      digitalWrite(RoLED1,HIGH); 
      
      break;   
    }
  }
  }


  
  digitalWrite(3,HIGH);
  if (digitalRead(4)==1){
    sum=0;
    for (int i=0;i<10;i++){
      sum=sum+analogRead(outputV);
    }
    average=(int) sum/10;
    
  }
  digitalWrite(3,LOW);
  Dif=(int) abs((average-OutputReadVoltage));
  Serial.println(Dif2,DEC);
  

}

You have at least two problems.

First, the time necessary to output over the serial port will affect the interval between conversions and it will vary depending on how many characters are output. This is going to make it difficult to process the signal data. If you plot the data in Matlab without the vertical bars you should see a pattern of horizontal lines corresponding to the number of characters in the output data.

Second, time tagging on the Matlab side is going to be subject to the timing vagaries of the multitasking operating system (Windows, Linux, iOS, it doesn't matter) so your time tagging is going to jitter across some interval depending upon how often the OS services the serial buffer. This will further corrupt your measurements.

Depending upon what you're doing with the data, I would suggest either collecting a vector of A/D samples into an array and then printing once the array is full. This will ensure a consistent sample rate, but you'll be getting non-continuous snapshots rather than a continuous stream.

Alternatively, you could moderate the sampling rate by using something like the "blink without delay" paradigm at an interval that the serial port can support without backing up the buffer.

I would suggest either collecting a vector of A/D samples into an array and then printing once the array is full.

Agreed. An FFT calculation is meaningless if the sample rate is not constant.

I don't know anything about Matlab. If it can make sense of binary data from the Arduino you will reduce the amount of data if you use Serial.write(), Your variable Dif2 is a 2-byte int.

But (there is always a but) the USB system is not good with small chunks of data and you may find it works better if you save up (say) 32 2-byte samples and send them all at once.

And an Uno can communicate at 500,000 baud - in case that helps.

...R

Ok, thank you all at first.

You're are surely right that i Need to measure the time on arduino side.
But i think i cant print Arrays over Serial.print, or am i wrong?

And im not sure if a for-loop for sending the Array is helpful there

And im not sure if a for-loop for sending the Array is helpful there

It would be a good learning initiative if you'd consider the alternatives

KreinRaan:
And im not sure if a for-loop for sending the Array is helpful there

Assuming you have plenty of time you can certainly use FOR to iterate over an array and send its contents using Serial.print(). If you are happy to send the data in binary format then Serial.write() can can send a complete array and that will be a little faster.

However you have not addressed the fundamental question about how much data you need to collect in what period of time. If you take the samples at a fixed interval there will be no need to store or transmit the time data which will greatly reduce the volume of data per sample. Even then, an Arduino has very little SRAM in which to save the data from samples. A Mega has only 8k bytes of SRAM and some of that will be needed by your program even if it never collects any data.

Then, assuming you collect all the samples you have room for, it will take time to sen them to the PC and during that period you cannot collect more samples - at least not at a high sample rate.

…R