help with micros() and millis() functions

Hi guys,

I'm trying to figure out how long it takes for 1 iteration of my loop() to take place.

I've put

time = micros();
Serial.println(time);

at the beginning of the loop() function and am copy/pasting all the values from the Serial monitor.

Something I've noticed is that - all else being constant - as the times recorded increase in order (1->10, 10->100, etc), the differences between each consecutive time actually increases. Can anyone help me with this?

Sounds like the results you're getting are not what you expect, you will need to clue us in on the specifics, and probably post more complete code.

Do you have even a rough idea of how fast the loop executes? If it's very fast, depending on the baud rate, Serial could be taking up more time than the loop itself, or generating output faster than can be sent to the monitor.

I might try just incrementing a variable each time through the loop, then printing it at one-second intervals or whatever.

It also sounds like you might be trying to control, rather than simply measure, how long loop() takes. Not a good idea, if that is the case.

Why are you measuring the time at all?

I’m interfacing 2 distance sensors for my device and am using median filters to reduce noise. I’m trying out filter sizes from 3 points to 53 points, and want to know how quickly the loop() runs each time I increase the filter size. I’m only trying to measure the loop() speeds so that I can pick an optimal filter size that’s both sufficiently fast and good at removing noise.

I don’t really know if a baud rate of 9600 is okay or not.

This is what I’ve got so far:

// Pin Definitions
const int sensor_1 = 0;
const int sensor_2 = 7;

// Variables & arrays for smoothing
const int filterSize = 7;
float filter1[filterSize];
float filter2[filterSize];
float tempdist1[filterSize];
float tempdist2[filterSize];
unsigned short adc_1 = 0;
unsigned short adc_2 = 0;
float temp1 = 0;
float temp2 = 0;
float median_1 = 0;
float median_2 = 0;
unsigned long time = 0;

void setup() {
Serial.begin(9600);

// Initialize all the distances to 0:
for(int thisReading = 0; thisReading < filterSize; thisReading++){
filter1[thisReading] = 0;
tempdist1[thisReading] = 0;
filter2[thisReading] = 0;
tempdist2[thisReading] = 0;
}
}

void loop() {
time = micros();
Serial.println(time);

// Shift all readings left, leaving last spot open for new reading:
for(int i = 0; i < filterSize-1; i++){
filter1 = filter1[i+1];
_ filter2 = filter2[i+1];_
* }*

* // Read from the sensors, put reading at end of each array:*
* adc_1 = analogRead(sensor_1);
filter1[filterSize-1] = adc_1;
adc_2 = analogRead(sensor_2);
filter2[filterSize-1] = adc_2;*

* // Copy into temporary arrays for sorting:*
* for(int i=0; i < filterSize; i++){*
tempdist1 = filter1*;*
tempdist2 = filter2*;*
* }*

* // Sort each temporary array into ascending order:*
* for(int i=0; i < filterSize-1; i++){*
* for(int j=i+1; j < filterSize; j++){*
_ if(tempdist1 > tempdist1[j]){
temp1 = tempdist1*;
tempdist1 = tempdist1[j];
tempdist1[j] = temp1;
}
if(tempdist2 > tempdist2[j]){
temp2 = tempdist2;
tempdist2 = tempdist2[j];
tempdist2[j] = temp2;
}
}
}*_

* // Extract median from temporary arrays:*
* median_1 = tempdist1[(filterSize-1)/2];
median_2 = tempdist2[(filterSize-1)/2];
_}
[/quote]
[quote author=Jack Christensen link=topic=100205.msg751484#msg751484 date=1333741960]
Sounds like the results you’re getting are not what you expect, you will need to clue us in on the specifics, and probably post more complete code.
Do you have even a rough idea of how fast the loop executes? If it’s very fast, depending on the baud rate, Serial could be taking up more time than the loop itself, or generating output faster than can be sent to the monitor.
I might try just incrementing a variable each time through the loop, then printing it at one-second intervals or whatever.
[/quote]*

I’m assuming you mean to use an interrupt every second or so to print out the incremented variable? I’ll try this out! Thanks for the advice._

How come this loop

  for(int thisReading = 0; thisReading < filterSize; thisReading++){
    filter1[thisReading] = 0;
    tempdist1[thisReading] = 0;
    filter2[thisReading] = 0;
    tempdist2[thisReading] = 0;
  }

has a ridiculously long name for the index variable and this one

  for(int i = 0; i < filterSize-1; i++){
    filter1 = filter1[i+1];
    filter2 = filter2[i+1];
  }

uses a much more reasonable name?

I don’t think the second one is correct. I think the forum software mangled your code because you posted it incorrectly. Code should be posted using the # icon, not the quote button or the stupid IDE function.

Averaging the readings would give you a much better value, much faster, than sorting and using the median value. Averaging would use a lot less memory, too.

The thing is, the outliers/noise that I'm picking up from the sensors are [u]very far[/u] from the mean. I thought using a median filter might be better for me because it'd essentially remove the outliers and keep them from skewing anything at all, whereas a running average would affected by each outlier. I know that I could just average more points, though, so I might have to resort to that later.

In any case, no matter the filter I use, I still need to find out how long each loop() takes to run so I can know how big I can make the filters, and I'm stuck regarding the issue with the micros() function.

void setup() {
  Serial.begin(9600);
...
}

void loop() {
  time = micros();
  Serial.println(time);
...

}

All you are really doing here is displaying how long it takes to display your debugging information. And I can predict what that will be. At 9600 baud it takes 1/960 of a second to display one digit. After 10 seconds you will be up to something like 12345678 (8 digits) plus carriage-return/newline. So, say 10 characters.

 1/960 * 10 = 0.0104167  (10.4 mS)

So this doesn't really prove anything.

utbme: Something I've noticed is that - all else being constant - as the times recorded increase in order (1->10, 10->100, etc), the differences between each consecutive time actually increases. Can anyone help me with this?

As the numbers get bigger it takes longer to display them, so they get bigger, and so on.

The thing is, the outliers/noise that I'm picking up from the sensors are very far from the mean.

Then, you should reject any that are far from the norm. Take a number of readings, developing a running average. If a value is read that is significantly above or below the average, ignore it. If it is within reason, add it the running average.

utbme: I'm assuming you mean to use an interrupt every second or so to print out the incremented variable? I'll try this out! Thanks for the advice.

Interrupts not necessary. I'd do something like below. If I run this sketch as is on an Uno, I get counts of ~206,000/sec with Arduino 0022 and ~145,000/sec with Arduino 1.0 =(

unsigned long ms, msLast, loopCount;

void setup(void)
{
    Serial.begin(115200);     //use high baud rate to minimize the time spent sending data
}

void loop(void)
{
    ++loopCount;
    ms = millis();
    if (ms - msLast >= 1000) {
        Serial.println(loopCount);
        loopCount = 0;
        msLast = ms;
    }
    
    //all the rest
    //of the code in loop()
    //goes here  
    
}