strange behavior in time measurement.

Hello,

i have a really strange and really short problem.

On a hardware interrupt on pin 3 Arduino Uno R3 is time reference saved in a variable named _prevTime. Type unsigned long.
Everytime the Arduino receives a signal on that pin the current time is saved in this variable. I tried to create a sort of a watchdog timer. If there is no signal for, lets say 10.000 micro seconds than turn off a led. So the main loop() takes the current time substracts the _prevTime and if this is greater than 10.000 it will turn off the LED. That didn't worked, the led is only blinking very fast. So i decieded to send the time difference by usb to the pc. The strange thing is: If i try the following code it will send me always a number which is near to the maximum of an unsigned long:
4294967288
4294967292
4294967292
4294967288
4294967292
4294967288
if i include one of the out commented lines it works fine. Then it will give numbers that are absolutly correct. This if comparision seems to change the value of the dif variable to its maximum. I don't have a single clou why. Hope you can help me.

void loop()
{
	unsigned long dif = micros() - _prevTime;
	//Serial.println(dif); // if included it works.
	if (dif > 10000)
	{ 
		Serial.println(dif); // this line is just for controlling the value of dif
		// the LED should be turned out here.
	}
	//Serial.println(dif);  // if included it works.
}

We'd need to see all of your code. It looks _prevTime is somehow larger than now (as defined my micros).

10 micros is probably way too short. 10 millis is closer to practical.

The micros() function rounds up to 4.

From your results it looks like you are subtracting the now from the previous or getting them in the wrong order.

You are using unsigned long and not long anywhere in there?
You are ending all constant values for unsigned long with UL? Ex: const unsigned long 10UL;

If there is no signal for, lets say 10.000 micro seconds than turn off a led.

Please say that you are not using float or double. Please.

Try disabling interrupts before you calculate dif and enable them afterwards.

Thank you for your replies.

PaulS:
We'd need to see all of your code. It looks _prevTime is somehow larger than now (as defined my micros).

When i include the out commented lines it workes perfectly. _prevTime is fine as well as micros() and dif. But if i print the value "dif" in the if-condition it changes it value.
I will post the code but give me some time to clean it up

DavidOConnor:
Try disabling interrupts before you calculate dif and enable them afterwards.

I will try this and will report the results.

GoForSmoke:
10 micros is probably way too short. 10 millis is closer to practical.

The micros() function rounds up to 4.

From your results it looks like you are subtracting the now from the previous or getting them in the wrong order.

You are using unsigned long and not long anywhere in there?
You are ending all constant values for unsigned long with UL? Ex: const unsigned long 10UL;

If there is no signal for, lets say 10.000 micro seconds than turn off a led.

Please say that you are not using float or double. Please.

10.000 is not a float or double. It is ten thousand just for better reading. = 10 ms.
Lets say the last measurement was 5000 so _prevTime =5000. In the loop he takes the current time and calculates the difference. If the current time is 6000 the difference will be dif=1000 if the dif is greater then 10.000 (ten thousand) it will turn off a led or what ever. The order is correct, the results are fine if i just include the out commented lines. Thats the strange thing i cant understand.
All variables i use to calculate the time are volatile unsigned long. And they don't end with UL. I have to google it, never heard about it.

Print uses interrupt which may be messing with timing.

If the watchdog is for 10 ms then you could set a flag (byte) that loop() catches to update start time for an interval check.

Assuming that you don't need 4 microsecond precision to check a 10 millisecond timeout.......
This is less prone to being affected by Serial but does rely on loop() running as fast as the desired accuracy.

loop()
{
timeNow = millis();

if ( irqFlag ) // signal detected, even if it's more than once
{
irqFlag = 0;
timeStart = timeNow; // this will be as close to the signal event as loop is fast
}
else if ( timeNow - timeStart > 10UL ) // counting millis, not micros
{
// signal overdue -- set a flag or do something
}

....... other code
}