Go Down

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

#### shardbearer

##### Jan 26, 2013, 02:50 amLast 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, 2const byte sensor2Pin = 3; // PIND, 3unsigned 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, 2const byte sensor2Pin = 3; // PIND, 3volatile 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

#1
##### Jan 26, 2013, 03:27 am
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

#### johnwasser

#2
##### Jan 26, 2013, 03:33 am
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: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp

#### Magician

#3
##### Jan 26, 2013, 05:27 am
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