Absolute maximum precision in interrupt timing

I had a bit of trouble googling this since I'm not sure about the nomenclature I need to be searching.

Basically I have a problem with the integrated interrupt feature in the 328 because I have to time interrupt events and then take the derivative multiple times. After several derivatives, if the timing is off even in the slightest, the N'th dirivative turns into a wild and crazy sawtooth that means absolutely nothing. I need much cleaner, more reliable timing of the input events I'm detecting.

Is there such a thing as a discrete IC chip that handles interrupts and converts that to something like a number that can be sent to the Arduino (representing a duration in time between events) so that the Arduino doesn't have to do it? Cost is no object so I need the maximum possible precision in timing and basically just want to bypass the 328's interrupt feature and pass a time value straight to the main routine that needs to do calculations on it.

What would you suggest for the best piece of hardware available? Thanks.

Actually, taking a derivative of a derivative of a ... is a set of operations bound to result in a lot of noise. Integral of an integral of a ... tends to reduce noise.

I don't know of any chip that does what you suggest but perhaps you can use the internal timers of the Arduino somehow.

Don't use an interrupt for critical timing. Period.

What should I use then?

I have a big-ass auto-grade encoder I made. A wheel with 6 equidistant holes in it, and a high quality hall effect sensor (also auto-grade). It produces a 5V square wave between 0 and 200 Hz based on how fast the encoder wheel can turn. That's the mechanical side and cannot be changed.

I need to pick up those pulses as accurately as possible using discrete circuitry and give it to the arduino in a way that it no longer needs to time anything.

The processor timing subsystem has a feature for that called "input capture". It latches the value of the timer on some event such as a pin state change. Thus you can resolve accurately to one timer clock cycle. Sit down for a while with the datasheet and the drink of your choice. :slight_smile:

Gahhhrrrlic:
I had a bit of trouble googling this since I'm not sure about the nomenclature I need to be searching.

The Atmega328 (like a lot of microcontrollers) has an input capture mode for Timer1 which will capture the value of the timer on an external event pulse.

The concept is to set the timer to run at a fast rate (up to system clock i.e. 16 MHz), capture the value of the timer on the event pulse which can also generate an interrupt, and then have the interrupt routine read the captured time of pulse at its (relative) leisure.

Very interesting. BTW my OP had a typo, as I'm using the Mega 2560. I'll check if it supports input capture.

So if I buy an aftermarket 2560 board that has crystals instead of ceramic resonators and I use the INPUT CAPTURE mode, is this the best way to get a clean signal, rather than trying to use discrete IC chips?

Yes.

Awesome. Thank you. Somebody ought to make that into a library so there's a native arduino function for it, since it seems like a very important feature of the chip.

Like this one?

Derrr... I walked right into that one didn't I

I've used interrupts for timing and got reproducibility of +/- 1 clock cycle.

Of course it takes a number of clock cycles for the ISR to run but that's apparently very predictable in itself. How many clock cycles this takes was completely irrelevant, as long as it's always the same, as the whole thing has to be calibrated anyway. It just shifts the line (it's a linear fit) a little.

The ESP32 and the Pulse Counter API.

https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/pcnt.html

The PCNT is an actual hardware peripheral that is not dependent on the Core0 or Core1 or the ULP for operations. The PCNT is configured and the results are read through the software API. You can program one core to just send information and the other core to read the interrupts generated. Tasks can be assigned through the use of the ESP32's OS freeRTOS. freeRTOS is built-in so to use it does not infringe on your codes program or run space.

wvmarle:
I've used interrupts for timing and got reproducibility of +/- 1 clock cycle.

Of course it takes a number of clock cycles for the ISR to run but that's apparently very predictable in itself. How many clock cycles this takes was completely irrelevant, as long as it's always the same, as the whole thing has to be calibrated anyway. It just shifts the line (it's a linear fit) a little.

As long as there are not multiple interrupts... if another ISR is in progress when the interrupt is asserted, it won't be serviced until the first one is finished.

Anyway, 200Hz is not fast when compared with the MCU clock speed. Assuming 16MHz, you get 80,000 processor clock ticks for one of your encoder ticks.

This reference is also useful with many code samples: https://www.gammon.com.au/timers See "Timing an interval using the input capture unit"