arduino mega, serial.print too slow

Hi
i just got a question which i struggle for a while now

i am trying to read an analog value from a source and sample it around 200 Hz which means i want generate 200 points every second. however when i setup into arduino and use serial.print to print out, it always shows dealy. for example if i set my total points to 2000, which means at a sampling rate of 200 Hz, 200 point every second, 10 second will be the finishing time. but with the serial.print, it doesnt finish at 10 second, the larger the sampling frequency, the larger the delay.

i want to use the serial.print because i need to use matlab to read the point and plot them in matlab in real time.

anyone can help? thanks!

What baud rate are you using ?

9600

Have you tried a higher baud rate ?

that works actually... it does finish in time in arduino now
However the signal gets delayed by 1 second or 2 when seeing from the matlab real time plot. do you have any idea how to fix that?

I may be able to help, and so will others, if you post the Arduino code but I know nothing about matlab.

#include <glcd.h>
#include <glcd_Buildinfo.h>
#include <glcd_Config.h>

// Reading Heart beating 
// Digital Stethoscope Project


// include the library code:
#include <LiquidCrystal.h>

// initialize the library by providing the nuber of pins to it
LiquidCrystal lcd(8,9,4,5,6,7);


int analog_in0 = A0; // Define an integer which is the output from the microphone 1 in to arduino
int analog_in1 = A1; // Define an integer which is the output from the microphone 2 in to arduino

int sample_points = 0; // Define the interger for the initialised sampling points that we going to take
int led_green = 8;
int led_red = 7;

void setup()  // Code for run once:
{
 lcd.begin(16,2);
 
 // set cursor position to start of first line on the LCD
 lcd.setCursor(0,0);
 //text to print
 lcd.print("   16x2 LCD");
 // set cusor position to start of next line
 lcd.setCursor(0,1);
 lcd.print("   DISPLAY");

 pinMode(analog_in0,INPUT); // set the pin as input, since the sound will be collect from the microphone 1 in to arduino
 pinMode(analog_in1,INPUT); // set the pin as input, since the sound will be collect from the microphone 2 in to arduino
 pinMode(led_green,OUTPUT);
 pinMode(led_red,OUTPUT);
 Serial.begin(250000); // allows us to listen to serial communications from the arduino
 delay(2000); // wait for 2 second until the arduino to start, this is the time for wating for matlab start to run
}

void loop()  // Code for run repeately
{
while(sample_points < 2000 ) // define the maximum sampling poits we going to take
{
 digitalWrite(led_green,HIGH);
 Serial.println(analogRead(A0) - 500);
 // print the data from the value of microphone 1 take away the value from microphone 2 to a serial terminal
 delay(5); // In every second there will be 200 data to print out
 sample_points++; // everytime there is 1 data, increase sampling points by 1 until it reaches the maxmium which defined above
}
digitalWrite(led_red,HIGH);
digitalWrite(led_green,LOW);
 }

Dont worry about the lcd part.. still haven't finish yet

thanks

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

    delay(5);This is not the best way to ensure that an event happens every 5 milliseconds. Whilst it is true that it will delay the operation of the code for 5 milliseconds it takes no account of the time taken to do other things in the loop.

It would be better to use millis() for timing. Save the time that a sample was taken, process it then go round loop() until the current time from millis() equals or exceeds 5 milliseconds. See the BlinkWithoutDelay example.

As to the problem with an apparent delay when communicating with matlab, does matlab leave the serial port open or is it opened periodically ? Each time the external device opens the serial port the Arduino, or at least most of them, will reboot.

A small, but important problem with your code is that you never reset the value of sample_points to zero. If you get more than one data set in matlab that would lead me to conclude that the Arduino is rebooting.

#include <glcd.h>
#include <glcd_Buildinfo.h>
#include <glcd_Config.h>

// Reading Heart beating
// Digital Stethoscope Project
// Monash Final Year Project
// Present by
// Karl Wei
// Ce Wang
// Haoxiang Deng

// include the library code:
#include <LiquidCrystal.h>

// initialize the library by providing the nuber of pins to it
LiquidCrystal lcd(8,9,4,5,6,7);
unsigned long previousMillis = 0;
const long interval = 5;

int analog_in0 = A0; // Define an integer which is the output from the microphone 1 in to arduino
int analog_in1 = A1; // Define an integer which is the output from the microphone 2 in to arduino

int sample_points = 0; // Define the interger for the initialised sampling points that we going to take
int led_green = 8;
int led_red = 7;

void setup() // Code for run once:
{
// lcd.begin(16,2);

// set cursor position to start of first line on the LCD
// lcd.setCursor(0,0);
//text to print
// lcd.print(" 16x2 LCD");
// set cusor position to start of next line
//lcd.setCursor(0,1);
//lcd.print(" DISPLAY");

pinMode(analog_in0,INPUT); // set the pin as input, since the sound will be collect from the microphone 1 in to arduino
pinMode(analog_in1,INPUT); // set the pin as input, since the sound will be collect from the microphone 2 in to arduino
pinMode(led_green,OUTPUT);
pinMode(led_red,OUTPUT);
Serial.begin(250000); // allows us to listen to serial communications from the arduino
delay(2000); // wait for 3 second until the arduino to start, this is the time for wating for matlab start to run
}

void loop() // Code for run repeately
{
while ( sample_points < 1000){
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
digitalWrite(led_green,HIGH);
Serial.println(analogRead(A0) - 575);
sample_points++; // everytime there is 1 data, increase sampling points by 1 until it reaches the maxmium which defined above
}
}
digitalWrite(led_red,HIGH);
digitalWrite(led_green,LOW);
}

is this correct now?
in the matlab, it opens the arduino port and reads the data from the serial.print window, and keep it open until it finishes all the reading.

karl1993:
Hi
i just got a question which i struggle for a while now

i am trying to read an analog value from a source and sample it around 200 Hz which means i want generate 200 points every second. however when i setup into arduino and use serial.print to print out, it always shows dealy. for example if i set my total points to 2000, which means at a sampling rate of 200 Hz, 200 point every second, 10 second will be the finishing time. but with the serial.print, it doesnt finish at 10 second, the larger the sampling frequency, the larger the delay.

i want to use the serial.print because i need to use matlab to read the point and plot them inmatlab in real time.
anyone can help?

When calculating for Serial you better calculate in "characters per second" than in "samples per second"

characters per second is possible up to "baudrate div 10)

So with baudrate 9600 you can send 960 characters per second
with baudrate 115200 you can send 11520 characters per second
with baudrate 250000 you can send 25000 characters per second

If you try to send faster/more characters, the Serial send buffer will get filled soon.
The Serial send buffer can hold up to 63 characters.

If the Serial send buffer is filled to max. and you still try to stuff characters into it, you will get delayed:
After one character has been sent by the hardware, one character gets fmoved from the send buffer to the hardware. You then can stuff one character into the send buffer again. If you try to stuff more, you get more delay.

ok so once i sample over 63 point per second it will have delay right...
is there anyway to solve this?
like store data in a sd card and let matlab reads the data from the sd card or something?

in the matlab, it opens the arduino port and reads the data from the serial.print window, and keep it open until it finishes all the reading.

What do you mean by "all the reading" ? Do you mean 2000 readings or a series of 2000 readings ?

I would guess the former, which would cause the Arduino to reboot when the Serial port was opened, because your code does not reset the value of sample_points except when it is declared and initialised.

karl1993:
ok so once i sample over 63 point per second it will have delay right...

Wrong. The analogRead function can return values from 0 to 1023. if you print "1023" to Serial in decimal ASCII this is at least 4 characters per sample and that would mean:
If the sample value is 1000 or above you can only send 15 samples and already have filled at least 60 characters in the Serial send buffer. Three characters more and you get a delay with the next Serial.print() command.

You can send more data when using an otimized binary data transmission protocol instead of ASCII-text protocol.