I'm using TinkerCad and I want to measure the frequency of an input square wave using digital interrupts. Here's the code which I implemented for my Uno-
With this code, the serial monitor can count almost accurately till 15-20 kHz. But I need accurate results for frequencies upto 150 kHz, whereas my code can't render any output for 150 kHz. I believe I need to change my code to account for detaching interrupts and counting pulses for a certain period using the rising edge and re-attach interrupts again, but I'm a complete beginner and I can't really figure out how to deal with the interrupts in this case to get accurate results upto 150 kHz. I'm using the AFG feature in TinkerCad to generate my input square wave. Can someone help me figure out the code? It would be of great help.
It can't render any output? Does that mean you get nothing on the Serial Monitor? Or do you see a value but you don't think it's correct?
I would at least change the print() to a println(), otherwise the interpretation of the returned value is a bit tricky.
At 150kHz the MCU has about 100 clock cycles to handle the interrupt and keep some time to do the rest. The interrupt handling inside the MCU needs about 12 cycles per call (without executing any code), saving the most important registers needs also time (if all 32 registers and SREG are saved that sums up to another 33 cycles). The increment is probably about 8 cycles. So more than half of all processing power available is used at least to handle the very simple interrupt handler.
For such high frequencies I would use counter 1 and it's counter input (pin 5). That way the hardware count's the edges and all you have to do is reading the counter value after a specified time.
I didn't use the println() since it queues up outputs and takes significant amount of time for arduino to respond to other tasks beyond the interrupts. It doesn't show anything on the Serial Monitor for 150 kHz, yes.
Also, isn't counter 1 related to the digital pin 2 on arduino uno? If I need to use pin 5, I would probably have to use timer interrupts in that case.
Where did this idea come from? All serial output operations queue up whatever you're printing to an output buffer; an interrupt automatically picks a byte out of that buffer whenever the serial hardware is ready to send a byte. Serial.println() just calls Serial.print() with whatever you're printing followed by Serial.print("\r\n"). There's no difference in queuing behavior.
I'm out of ideas right now. Does anyone have any solution to this? How do I go about changing the interrupts status and such in order to count frequencies in the range of 10^5 Hz?
This should go a lot faster, though I'm not sure it will hit 150kHz.
A bit faster if you reduce count to a uint16_t (but that would also require reducing the delay() value.
(this compiles, but isn't actually tested. Most of the speedup comes from avoiding the overhead required by the dynamic callback address in attachInterrupt.)