Go Down

Topic: High Speed Input Accuracy (Read 510 times) previous topic - next topic

shardbearer

Jan 26, 2013, 02:50 am Last Edit: Jan 26, 2013, 02:53 am by shardbearer Reason: 1
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: [Select]
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: [Select]
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.

Osgeld

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
http://arduino.cc/forum/index.php?action=unread;boards=2,3,4,5,67,6,7,8,9,10,11,66,12,13,15,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,86,87,89,1;ALL

johnwasser

Try this:
Code: [Select]

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);
}
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Magician

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

Go Up