Pages: [1]   Go Down
Author Topic: pulseIn timeout is puzzling me (SOLVED)  (Read 1283 times)
0 Members and 1 Guest are viewing this topic.
Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello
I'm using the PulseIn method from 1.0 and it does not behave as I expect.
According to the arduino reference pages it should take 1 second before it returns when no signal is received.
Quote
timeout (optional): the number of microseconds to wait for the pulse to start; default is one second (unsigned long)

However I think it returns in about 233 miliseconds.
To prove my point I wrote following code:
Code:
#define ir_pin 7

void setup() {
  pinMode(ir_pin,INPUT);
  Serial.begin(115200);
  Serial.println("Test pin in timeout");
}


//LOW = IR light, HIGH = no IR light (that's how my IR receiver reads)
void loop() {
  unsigned long StartMicroseconds = micros();
  unsigned long pulseInvalue = pulseIn(ir_pin,HIGH);
  unsigned long StopMicroseconds = micros();
  Serial.print("Start Test in Micro's: ");
  Serial.println(StartMicroseconds);
  Serial.print("Stop Test in Micro's: ");
  Serial.println(StopMicroseconds);  
  Serial.print("Pulse in duration in Micro's: ");
  Serial.println(StopMicroseconds - StartMicroseconds);    
   Serial.print("Pulse in response: ");
  Serial.println(pulseInvalue);    
  delay (1000);
}
I connected nothing to pin 7 and ran the code. The output of the 2 first iterations was:
Code:
Test pin in timeout
Start Test in Micro's: 752
Stop Test in Micro's: 233660
Pulse in duration in Micro's: 232908
Pulse in response: 0
Start Test in Micro's: 1238356
Stop Test in Micro's: 1471000
Pulse in duration in Micro's: 232644
Pulse in response: 0
As PulseIn returns 0 I know there is no noise and there is no need for a pull down resistor.

Looking at the PulseIn code I would say that it does not take 16 clock cycles but 5 to run a loop.
Code:
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;

The timeout is important to me as my robot can be running automatically, controlled from the web or RC controlled. When the RC is not on; a 1 second timeout is to long.
So I thought about changing the timeout with following reasoning
If I would say 2 millis is enough I would have to provide about 10000 micros to the method
I modified the above program to have a timeout of 10000 and I get following result
Code:
Test pin in timeout
Start Test in Micro's: 752
Stop Test in Micro's: 13012
Pulse in duration in Micro's: 12260
Pulse in response: 0
Start Test in Micro's: 1017540
Stop Test in Micro's: 1029544
Pulse in duration in Micro's: 12004
Pulse in response: 0

So here the 16 clock cycles seem to be OK.
Can anyone explain why PulseIn Returns after 233 miliseconds and not 1 second by default?
Best regards
Jantje
« Last Edit: April 24, 2012, 03:40:17 am by Jantje » Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I connected nothing to pin 7 and ran the code. The output of the 2 first iterations was:
completely bogus, because you have a floating pin. You MUST explicitly ground the pin or power the pin. No floating pins allowed.
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Paul
Quote
I connected nothing to pin 7 and ran the code. The output of the 2 first iterations was:
completely bogus, because you have a floating pin. You MUST explicitly ground the pin or power the pin. No floating pins allowed.
Have you also read
Quote
As PulseIn returns 0 I know there is no noise and there is no need for a pull down resistor.

To satisfy you I even tested with a pull down resister of 0 ohm and it gives the exact same result.

Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 634
Posts: 50243
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As PulseIn returns 0 I know there is no noise and there is no need for a pull down resistor.
Have you looked at the source code? pulseIn returns 0 whenever the pin status does not change within the timeout period. A floating pin is not guaranteed to be 0 or 1 or to not transition at random between 0 and 1 once or more than once in any given time period.

Quote
To satisfy you I even tested with a pull down resister of 0 ohm and it gives the exact same result.
What are the band colors on that resistor?  smiley
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As PulseIn returns 0 I know there is no noise and there is no need for a pull down resistor.
I don't completely agree with that statement. 

However,  I tried your code with a pull-up, pull-down, and floating.  All return in about 200ms.  Same behavior if I explicitly state the timeout to be 1s.

Something is up.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

James
Thanks for confirming the issue.

All
anyone can explain this behavior?
Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

from pulseIn in wiring_pulse.h
Code:
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
from Arduino.h
Code:
#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 1000L)) / 1000L )
from compiling with verbose output
Code:
-DF_CPU=16000000L
so then we get
Code:
unsigned long maxloops = ( ((timeout) * (16000000L / 1000L)) / 1000L )/16
(Why they didn't use UL is beyond me; perhaps they're providing forward compatibility for CPUs with negative clock rates?)
if timeout is 1,000,000UL (1 million microseconds = 1 second):
Code:
unsigned long maxloops = ( ((1000000UL) * (16000000L / 1000L)) / 1000L )/16
Code:
unsigned long maxloops = ( ((1000000UL) * (16000L)) / 1000L )/16
(I'm not an expert; I don't know what the multiplication of an unsigned and a signed brings, but I'm going to assume it's unsigned because that is the more dramatic case even though it makes more sense for it to be signed)
Code:
unsigned long maxloops = ( (16000000000L) / 1000L )/16
OOPS, 16000000000 is bigger than  4,294,967,295, the maximum size of an unsigned long (it's nearly 4 times bigger). If we truncate, we get 3,115,098,112 (which I BELIEVE is -1,557,549,056 if using signed arithmetic)
Code:
unsigned long maxloops = ( (3115098112UL) / 1000L )/16
Code:
unsigned long maxloops = 3115098/16
Code:
unsigned long maxloops = 194693
194693(loops)*(1/16,000,000)(seconds per clock cycle) *16(clock cycles per loop) = 0.194693 seconds. 195 milliseconds. Then there's the problem that the code assumes that it takes 16 clock cycles per loop for each of the loops, but the final one of the three loops is different (it increments an extra variable, width).


At least, there's my math for you.
Logged

Belgium
Offline Offline
Edison Member
*
Karma: 68
Posts: 1926
Arduino rocks; but with my plugin it can fly rocking the world ;-)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

WizenedEE
Thanks for solving the puzzle.
It makes perfect sense to me.
On UL versus L: From calculation point of view there is no difference between UL and L. So assuming everything is unsigned is 100% correct.
I can trust the PulseIn again  smiley
Best regards
Jantje
Logged

Do not PM me a question unless you are prepared to pay for consultancy.
Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Pages: [1]   Go Up
Jump to: