Strange Interrupt behaviour - any ideas why?

Robin2:
I don't see how it could because my ISR would have disabled interrupts.

That's sort of the point. Since TCNT0 keeps counting even with interrupts disabled, it can get out of date with timer0_overflow_count.

As Nick pointed out in the linked thread, however, micros() is actually pretty clever. It uses (TIFR0 & _BV(TOV0) as a sort of 9th bit for TCNT0, so you can detect when TCNT0 gets out of date with timer0_overflow_count.

That means you don't have a problem until your ISR >1.024ms. Your ISR certainly is not >1.024ms, so this isn't the cause of your issue.

Robin2:
@Coding Badly, thanks.

Too early for a thanks; I made some mistakes. But I do appreciate it.

There is a race condition. The code in #10 does eliminate it. However, under what you've described as the normal working conditions, it is a distinction without a difference. The code eliminates a problem that will never occur.

I believe the code in #10 will actually help with troubleshooting. It preserves the order of events.

I think the simplest thing may be to reject readings that are significantly different from the norm.

That would be my strategy.

However I remain puzzled by why the other version using a CHANGE interrupt does not exhibit the same problem.

I suspect the CHANGE code takes longer to run which suppresses the symptom.

Incidently, using the concept in Reply #10 slightly increased the number of glitches.

Very likely because interrupts are disabled for a shorter time span.

Please post about 100 readings. Maybe someone can spot a pattern.

Can you tell us a bit about the project's geometry? Things like, the reflector's width, its radius of rotation, and how close it is to the detector when it passes by.

The reflector is one side of a wooden cube about 5mm x 5mm x 5mm. The cube is glued to the end of a worm gear of about 5mm diameter - in other words it is rotating about the centre of the cube.

The cube is painted black with a piece of white card stuck on one face. When the face is pointing at the QRE1113 it is about 3mm away.

From looking at my oscilloscope I think the mechanics and optics are working OK.

And in case anyone suggests it, I don't have space for a bigger reflector and I did not get good results with a cylinder in place of the cube.

...R

Almost two weeks have elapsed. Sorry, I let myself get distracted by my day job.

Are you still interested in pursuing this? Maybe it's solved.

Robin2:
The reflector is one side of a wooden cube about 5mm x 5mm x 5mm.
... rotating about the centre of the cube.
... black with a piece of white card stuck on one face.

Ingenious.

I suspect that the detector output rises so slowly, relative to the sampling clock, and that it spends a few cycles near the switching point for the input. I think extra changes may be detected while the signal passes through that point. That's essentially bounce, as others have said, but, it wouldn't look particularly bouncy on an oscilloscope. The datasheet quotes a 20 microsecond rise time, and I'd guess that's measured with everything in its optimal position, running at its optimal speed, with both known only to the manufacturer.

From looking at my oscilloscope I think the mechanics and optics are working OK.

What kind of rise time do you see on the oscilloscope?

And in case anyone suggests it, I don't have space for a bigger reflector and I did not get good results with a cylinder in place of the cube.

Far be it from me to suggest such a thing. Instead, I'll suggest that you try these:

  • Clear the interrupt flag at the end of the ISR. That will add a delay equal to the ISR's execution time before interrupts are reenabled. It's not much time, but it might be enough.
  • Instead of using the external interrupt, use the on-board comparator with 1/2*VCC as the other input. That may still yield the same problem. I've seen software-controlled hysteresis, in which the program controls the comparison voltage by switching one of its outputs, which may work if you can unambiguously decide what state the physical system is really in.
  • Use an external comparator with some old-fashioned analog hysteresis.

I'm interested to know how you centered that cube on the shaft to avoid vibration.

I have been distracted by other things myself. As far as I can remember it was working OK last time I tried - but as I write this I can't remember why or how.

I can answer your last question easily - I centred it by eye and it is not perfect but I have not noticed any vibration - the cube is very light.

It will probably be next week before I get back to it.

Thanks for your input.

...R