Sampling frequency and interfacing with matlab

Hello everybody,
i’m trying to acquire data through arduino and plotting them with matlab. I need a sampling frequency of at least 1 kHz, but from tests made with a potentiometer it seems to be around 30Hz. Is it a matlab problem or an arduino problem? Which is the maximum sampling frequency of arduino? I have an arduino uno r3, and to interface it with matlab i’ve used the specific toolbox from mathworks. I attach the matlab code used for the acquisition:

passo=1;
interv=1000;
t=1;
x=0;
while(t<interv)
b=a.analogRead(0);
x=[x,b];
plot(x);
axis([0 interv 0 1023]);
grid
t=t+passo;
drawnow
end

I’ve also tried preallocating the array but strangely performance seems to go down.
Thanks for your help.

Well the clockspeed of an arduino board is at around 16 mhz i believe.
But thats only the clock, there will be some interupts and there will be code to run.
You could time how fast your main loop code runs …

However besides that. there is another speed limit, thats the limit caused by your serial connection 9600 baud or so.
Which might not be a big problem (for example you could do 400 readings and report only the average, or return a string with more statistic info lowest fasted average standard deviation etc…)

hmm i dunno about mathlab but i do know arduino… language

define sensorPin0 = A0; // or another one
int test[100];
Long sumall=0;
void setup { Serial.begin(9600); }

void loop(){

Loop{
for(i=0;i<100;i++) { test*= Analogread(sensorpin0);}*

  • // you just took 100 readings*

_ for(i=0;i<100;i++) {sumall = sumall + test*;} // an int would be to small to store it as 100 x 1024 =102.400 (max int = 32,767 )_
_
sumall = sumall /100;_
_
Serial.println(sumall); // use the serial monitor program from arduino.exe or another com port reader*_
* dealy(200) ; // just to be sure you wont go faster then the comspeed*
* }*
}

Yes, I quote PGT..

I had the same performance as Dado, near to 50Hz.. But, changing two lines in the arduino (loaded) code and matlab arduino.m, now I have near 4800Hz of sampling frequence at 8 bit/sample. You need to remove the useless comparisons in the arduino code in order to free the sampling job. An other improvement can be obtained changing "Serial.begin(9600)" to "Serial.begin(115200)"..

If you need help with the code, send me a private message.

Snipper: You need to remove the useless comparisons in the arduino code in order to free the sampling job.

What is the useless code? How did you get such high sampling frequencies ? Please share.

Start with changing the baudrate.

The Arduino can work reliably at 500.000 baud or 230400 baud too. Dont know matlab, but I guess it is just a config you can change at the matlab side. transporting the data faster gives more time to make measurements.

Any other suggestions to get the higher sampling frequency ?

let matlab do the math

#define sensorPin0 = A0;  

void setup
{ 
  Serial.begin(230400); // or 3456000 or 500000
}

void loop()
{
  int test = analogRead(sensorpin0);  // about 8K samples per second
  Serial.print(test);
  Serial.print(','); // separator of 1 char iso \n\r which is two char
}

you can check this post to increase reading the analog signal - http://forum.arduino.cc/index.php/topic,74895.0.html -

can some one help .. i am using same code and sampling rate is ver low.. can only read upto 15 hz signal at max..

I know this is an old post, but I will still post a reply here in case of any future readings.

I am trying to sample single-channel data (16 bit) at high (>=1000 Hz) and reliable sampling rate via Matlab from an Arduino Leonardo. Sounds impossible but now I believe I have achieved it. But please let me know if I have made any mistakes.

Environment: Matlab R2017b Update 7, Windows 10 1803, Arduino Leonardo.

There are several key-points here. First, both Matlab’s Arduino support packages and built-in serial object are very slow. I have to use 3-rd party mex sampling tools. I use this one (Mex_C_Serial_Interface - File Exchange - MATLAB Central). After downloading it, modify “CSERIAL_FLOW_NONE” at line 33 of “openPort.c” to “CSERIAL_FLOW_HARDWARE”, so that Arduino can automatically transfer new data once the input buffer is being read. I compiled the mex files in Matlab using Visual Studio Ultimate 2013 without any errors.

Second, don’t set the sampling rate in Matlab code, set it in the Arduino code, and transfer the timestamp associated with each data point together. Arduino has a delayMicroseconds() function that is very precise so your sampling rate won’t have any large jitters. You can get timestamp with Arduino’s “micros()” function.

Third, at high sampling rate, you need higher baudrate and more compact data transfer. I specify baudrate=115200, and transfer data every 1 ms using Serial.write(). Here the timestamp returned by “micros()” is unsigned long (32-bits, 4 bytes), and sensor value returned by analogRead() is int (16-bits, 2 bytes), so for each sample I make a 6-elements byte array to store timestamp and sensor data together and send this byte array with Serial.write(). On the Matlab side, read serial port as fast as you can (reading interval should be smaller than Arduino’s data sending interval), so the FIFO buffer won’t filled-up (That’s why I need a high-speed serial port reader instead of MATLAB’s built-in slower one). The mex tool I mentioned can only read data in array of bytes, so I use Matlab’s “typecast()” function to combine the first 4 bytes to form the timestamp value, and combine the last 2 bytes to form the sensor data.

To validate this method, I sample my computer’s screen brightness (1000 Hz sampling rate) with an analog photo-resister attached to Arduino Leonardo. I flash the screen black-then-white with PsychToolbox’s “PerceptualVBLSyncTest” function at highest refresh rate (60 Hz) while sampling. Attached is the result. The upper part is the screen-brightness data. There are 30 cycles in a second, and in each cycle the screen refreshed twice (white-black-white), so the refreshrate is 60 Hz. The lower part is the sample interval calculated by the difference between consecutive timestamp data. The sample interval is around 0.001 s, and the jitter is about 7%. This is much better than matlab’s built-in serial object.