pulseIn Function

Hey all,

I am having trouble with the pulseIn function. I did a google search on it and it appears many people have issues with it. I'm wondering if it's defective in any way?

Anyways, I'm using this function to calculate the duration a pulse is high. I began using the example code below from this website. The only change I made is added an output high to trigger the pulse. I then jumpered the output to pin 7 for about 1 second. No pulse was read. I only get 0 in the serial monitor. Anyone have any idea on how to get this function to work properly? I added timeouts of 5 seconds with no luck. Any help/insight will be appreciated.

int pin = 7;

unsigned long duration;

void setup()

{

pinMode(pin, INPUT);

}

void loop()

{

duration = pulseIn(pin, HIGH);

}

I see “duration” as a measurement of time. And I’m not seeing any part of your sketch that has anything to do with time.

When pulseIn goes HIGH I would think you would need to record startMillis. Then when it goes back LOW record endMillis.

endMillis-startMillis would give you “duration” in millis.

Just an observation from a beginner. The pros will chime in.

What exactly is creating the pulse that you're trying to measure? Your description didn't mean much to me.

Bear in mind that a pulse has to go HIGH then LOW. Going to 5V and then removing the V so going open circuit isn't the same thing.

Steve

Hey slipstick, the pulse is coming from 5V from one of the output pins. You think that open circuiting the input pin isn't causing it to go low?

cnoah20: Hey slipstick, the pulse is coming from 5V from one of the output pins. You think that open circuiting the input pin isn't causing it to go low?

It is? I don't see that in the code you posted. Perhaps you should show us your actual code (in code tags), and a schematic.

aarg: It is? I don't see that in the code you posted. Perhaps you should show us your actual code (in code tags), and a schematic.

I think you're onto something aarg. No way his serial monitor would show 0s with the sketch supplied above either.

Please use code tags (</> button on the toolbar) when you post code or warning/error messages. The reason is that the forum software can interpret parts of your code as markup, leading to confusion, wasted time, and a reduced chance for you to get help with your problem. This will also make it easier to read your code and to copy it to the IDE or editor. If your browser doesn’t show the posting toolbar then you can just manually add the code tags:
[code]``[color=blue]// your code is here[/color]``[/code]
Using code tags and other important information is explained in the How to use this forum post. Please read it.

Please remove unnecessary blank lines from your code before posting to the forum. One or two to separate code into logical sections is fine but large spaces for no reason or random blank lines just make for more scrolling when we’re trying to read your code. Don’t double space your code!

DangerToMyself:
I see “duration” as a measurement of time. And I’m not seeing any part of your sketch that has anything to do with time.

When pulseIn goes HIGH I would think you would need to record startMillis. Then when it goes back LOW record endMillis.

endMillis-startMillis would give you “duration” in millis.

pulseIn() returns the duration of the pulse. What you’re describing would be necessary if you were using digitalRead(), essentially that’s what pulseIn() does but it also has a timeout. If the pulse is not completed withing the timeout duration then pulseIn() returns 0.

cnoah20: Hey slipstick, the pulse is coming from 5V from one of the output pins. You think that open circuiting the input pin isn't causing it to go low?

Yes. If an open circuit pin was reliably low you wouldn't see so many circuits with pull-down resistors to make sure the pin goes low.

Steve

Can't say I knew pulseIn() was a built in on the Arduino. Guess that's obvious to some from the, seemingly dumb, reply I gave earlier.

The description says it returns the value in microseconds. Does it automatically send it to the serial monitor as well? That's not clear on the webpage.

DangerToMyself: The description says it returns the value in microseconds. Does it automatically send it to the serial monitor as well? That's not clear on the webpage.

No, it just returns the duration so OP's code still makes no sense in relation to their description of the problem.

pert: No, it just returns the duration so OP's code still makes no sense in relation to their description of the problem.

That is what I was thinking after reading the webpage. Thanks for the confirmation. And, I believe the OP's code is exactly like the example given on that page. Or very near exact. Not that it matters much.

DangerToMyself: I believe the OP's code is exactly like the example given on that page. Or very near exact.

Good catch, I hadn't noticed that. Event the stupid double spacing! That definitely needs to be fixed. It would probably make sense to add some code to the example to print duration to Serial also.

I just checked and the double spacing of that example has already been removed from the updated version of the reference page, which was scheduled to go live on Oct. 30th (I guess they're a little behind schedule). I also don't like that they don't consistently follow the long established style convention of not putting braces on their own lines but that's not very urgent and I want to submit a comprehensive PR for that issue rather than only fixing it in one place.

Below is my entire code. I set up an output to toggle high on a delay. Still showing only 0's in the serial monitor.

int out1=13; //pin 13 as output
int in1=3; //pin 3 as input
unsigned long duration=0; //variable for pulseIn function

void setup()
{
pinMode(out1, OUTPUT);
pinMode(in1, INPUT);
Serial.begin(9600); 
}

void loop()
{
  digitalWrite(out1, LOW); //out1 is set to low
  delay(1000);
  duration = pulseIn(in1, HIGH, 5000000); //awaits input to toggle high then starts counting, sets timeout for 5000000 microseconds or 5 seconds
  digitalWrite(out1, HIGH); //sets output high 
  delay(1000); //output remains high for 1000 milliseconds or 1 second
  Serial.println(duration); //prints the duration the output remained high
}

That's not going to work. pulseIn() is a blocking command so once you've called it the following digitalWrite() won't happen until it times out and that point there has been no pulse to measure.

It measures external pulses. You can't get it to measure a pulse that's generated in the same Arduino.

Steve

slipstick: It measures external pulses. You can't get it to measure a pulse that's generated in the same Arduino.

You can if it is generated using a timer.

aarg: You can if it is generated using a timer.

I give up. Dunno why I bother trying to help.

Steve

PulseIn works great with an external pulse. I used a function generator to supply a square pulse and it worked as expected! Thanks for the help everyone.

slipstick: I give up. Dunno why I bother trying to help.

Steve

Why? I made a simple statement of fact about the architecture that I thought might convey some insight into the range of possibilities.