Pages: [1]   Go Down
Author Topic: High Speed Input Accuracy  (Read 461 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a project that I'm working on where I need to measure the amount of time between two inputs. Normal times would be around 4000 microseconds, going as low as 200 microseconds. I wrote two versions of the code, both of which work fine, but the question is, which one is more accurate? One uses loops that repeat if statements so I get the maximum polling frequency, the other uses interrupts.

BTW, both use the internal pull up resistors, so the logic is reversed.

Code:
const byte sensor1Pin = 2; // PIND, 2
const byte sensor2Pin = 3; // PIND, 3

unsigned long time1 = 0;
unsigned long time2 = 0;

void setup() {
  pinMode(sensor1Pin, INPUT);
  pinMode(sensor2Pin, INPUT);
  digitalWrite(sensor1Pin, HIGH);
  digitalWrite(sensor2Pin, HIGH);

  Serial.begin(9600);
}

void loop() {
  if (!bitRead(PIND, 2)) {
    time1 = micros();
    while (1) {
      if (!bitRead(PIND, 3)) {
        time2 = micros();
        Serial.println(time2-time1);
        break;
      }
    }
  }
}

Code:
const byte sensor1Pin = 2; // PIND, 2
const byte sensor2Pin = 3; // PIND, 3

volatile unsigned long time1 = 0;
volatile unsigned long time2 = 0;

void setup() {
  pinMode(sensor1Pin, INPUT);
  pinMode(sensor2Pin, INPUT);
  digitalWrite(sensor1Pin, HIGH);
  digitalWrite(sensor2Pin, HIGH);

  attachInterrupt(0, sense1, FALLING);
  attachInterrupt(1, sense2, FALLING);

  Serial.begin(9600);
}

void loop() {}

void sense1() {
  time1 = micros();
}

void sense2() {
  time2 = micros();
  if (time1 != 0) {
    Serial.println(time2-time1);
  }
  time1 = 0;
}

Which one has better accuracy? The one without interrupts seems like it would be much less prone to bouncing bugs.
« Last Edit: January 25, 2013, 08:53:51 pm by shardbearer » Logged

SE USA
Offline Offline
Faraday Member
**
Karma: 41
Posts: 3783
@ssh0le
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

interrupts stop everything when a condition is met, to deal with that condition. with a loop you have to wait until it rolls back around to deal with the condition, which may or may not be in the same state as it was when it changed
Logged


Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 208
Posts: 8821
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try this:
Code:
void loop() {
  while (bitRead(PIND, 2)) ;  // Wait for pin to go LOW
  time1 = micros();
  while (bitRead(PIND, 3)) ;  // Wait for pin to go LOW
  time2 = micros();

  Serial.println(time2-time1);
}
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Montreal
Offline Offline
Faraday Member
**
Karma: 29
Posts: 2590
Per aspera ad astra.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Most accurate would be solution based on hardware ICP - input capture. Interrupt needs time to proceeds, even "while" have some overhead - jump code.
Logged

Pages: [1]   Go Up
Jump to: