Don already mentioned using an interrupt. With that method, you'll also need a counter in your ISR so you know how many pulses the timestamp corresponds to.
Here's another way to use an interrupt that gives you a bit more flexibility.
- Set up a ring buffer1
- Set up an interrupt to trigger on your sensor pulses
- In your interrupt service routine, just add the new timestamp2 to your ring buffer and return from interrupt.
- When you need a speed reading in your control code, do the following:
-- disable interrupts3
-- grab a copy of the ring buffer
-- enable interrupts
- Now you have a history of timestamps of the past N pulses (N being the size of your ring buffer). If it's not too noisy4, you can just use the difference between the latest two. Or you can use an average of the past n samples, where n<=N.
The other common way to compute speed is to have an interrupt service routine which just counts pulses. Then in your control code, you grab that counter (atomically), subtract the previous counter value, and divide by the elapsed time between the two readings (of the system timer). This works better at high speeds. As the speed gets slower the change in the counter gets smaller and the resolution becomes unacceptable.
1ask if you'd like more explanation
2e.g. read the microsecond system timer.
3operation needs to be protected to preserve data integrity
4at high speeds, the signal-to-noise ratio may suffer, in which case use more samples from the ring buffer.