Go Down

Topic: pulseIn Timeout (Read 3324 times) previous topic - next topic

LolluPaandi

Oct 07, 2011, 09:42 pm Last Edit: Oct 07, 2011, 09:43 pm by LolluPaandi Reason: 1
I have a Mega 2560, with an LED on 13 and 12 hard-wired to ground.

Code: [Select]
unsigned long temp;
void setup(){
  pinMode(13,OUTPUT);
  pinMode(12,INPUT);
}

void loop(){
   digitalWrite(13,HIGH);
   temp = pulseIn(12,LOW,1000000L);
   digitalWrite(13,LOW);
   temp = pulseIn(12,LOW,1000000L);
}


In the above code, if I understand the pulseIn function correctly, I'm expecting to see the LED on for a second and off for a second. But it flashes much faster (on for ~250 ms and off for ~250 ms).

Any thoughts? Thanks!

EDIT - I'm using Arduino 0022.

dc42

#1
Oct 07, 2011, 10:41 pm Last Edit: Oct 07, 2011, 10:46 pm by dc42 Reason: 1
Looks like a bug in the library. The code for pulseIn calls the following macro, with the timeout you pass as the parameter:

#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 1000L)) / 1000L )

With F_CPU = 16000000L, the expression becomes (a * 16000L) / 1000L. The multiplication will overflow if 'a' (the timeout value you are passing) exceeds 268435. So a timeout of one million is too much for it. [The multiplication is done using unsigned arithmetic, because that's the type of the 'timeout' parameger to pulseIn.]
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

nickgammon



In the above code, if I understand the pulseIn function correctly, I'm expecting to see the LED on for a second and off for a second. But it flashes much faster (on for ~250 ms and off for ~250 ms).

Any thoughts? Thanks!


dc42 is probably right. Also when a parameter like "timeout" is specified in microseconds, you should be wary of supplying a million of them. The implication is that you are expecting a pulse within a "few" microseconds, and if you don't get it you timeout.

Also, a "counted" loop (like pulseIn does) is unlikely to be accurate at such high intervals (interrupts would throw the interval out).
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

LolluPaandi

dc42 is right. I changed the define in wiring.h to

Code: [Select]
#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 10000L)) /100L )

and now my LED flashes every ~1 second.

I see your point Nick. Which is why my LED flashes approximately every one second, and not accurately. But my application can tolerate this - I'm trying to detect a light pattern from an external device (flashing 'fast' or flashing 'slow' or steady) where 'fast' is every second and 'slow' is every 3 seconds.

Also, in the documentation of pulseIn, it is mentioned that the default value of timeout is one second. But I don't see how this is implemented. Is that a bug as well?

I'm fairly new to Arduino. Is there a place to log bugs?

Thanks. I love this community.

dc42


Also, in the documentation of pulseIn, it is mentioned that the default value of timeout is one second. But I don't see how this is implemented. Is that a bug as well?


Yes, I think it is. This illustrates well the perils of untested, unverified code.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

nickgammon


Also, in the documentation of pulseIn, it is mentioned that the default value of timeout is one second. But I don't see how this is implemented. Is that a bug as well?


It's implemented in the function prototype for pulseIn in the file WProgram.h:

Code: [Select]
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);

It's pretty standard in C++ to put defaults on (trailing) arguments to functions in this fashion.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

robtillaart

See also - http://arduino.cc/forum/index.php/topic,74813.0.html -

I posted a bug report yesterday for pulseIn() - http://code.google.com/p/arduino/issues/detail?id=675&q=pulsein -

Updated it today with reference to both threads as backgrounder and a fixed version of pulsein().

-
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

ubay

I posted the same bug back in September (http://arduino.cc/forum/index.php/topic,72657.0.html)

A better fix was suggested that only requires a change to the pulsein function and won't affect other code that uses microsecondsToClockCycles and wiring.h

This seems not have made it to 023 or 1.0

Go Up