As Majenko wrote, when you only rely on software to measure the frequency on a IO pin, it will always be rather slow. And it also depends on the code, that you use. Functions like digitalRead()
are always slower than directly working with the control registers of the pin (Reference). As you didn't show your code, we cannot say more about that.
If you need to measure higher frequencies or you want to do other things in between (like outputting the data somewhere), it is better to use the microcontrollers buildin hardware. There are multiple ways to measure the frequency. 2 immediately come to my mind:
You could assign an ExternalInterrupt or a PinChangeInterrupt to the signal pin (limited choice of pins here), which triggers each time you see a rising (or falling) edge on the signal. In the ISR (Interrupt Service Routine) you could count up a variable. That value is the number of rising (or falling) edges, thus periods of the signal. The frequency is this value divided by the duration of the measurement. Every time you calculate the frequency, you reset the counter; reading it again after a defined duration. This should be better than just polling, but its not the best. (Note that a PinChangeInterrupt triggers on every edge, so you have to divide the frequency by 2)
You could configure an unused Hardware Timer/Counter to use your signal as external clock source. Let it count up until it overflows (or up to a value defined by you) and let it trigger an interrupt. Since the Arduino framework already uses Timer0 for timekeeping, you could divide the max value of the Timer/Counter by the time passed and you will get the frequency. I think this can get you in the MHz range.(As with PinChangeInterrupt, the Counter will increment on every edge, so again a factor of 2 here)
Both ways will calculate the frequency as a mean over a specific time. If you have a changing frequency, you might wanna manipulate measurement frequency. In the first case you can change the interval, in which you read the counter variable. In the second case you can change the max value, to which the Timer/Counter will count.
what the highest frequency digital signal that I could read?
(I assume you just want to read the frequency of the signal) That depends on many factors. If we use the second case from above (configuring a Hardware Timer as Counter connected to the signal) we have a limit on the maximum frequency, that we can provide. I found the relevant part in the datasheet of Atmega328p (which is the microcontroller on the Nano):
Each half period of the external clock applied must be longer than one system clock cycle to ensure correct
sampling. The external clock must be guaranteed to have less than half the system clock frequency (f ExtClk < f clk_I/O /2) given a 50/50% duty cycle. Since the edge detector uses sampling, the maximum frequency of an
external clock it can detect is half the sampling frequency (Nyquist sampling theorem). However, due to
variation of the system clock frequency and duty cycle caused by Oscillator source (crystal, resonator, and
capacitors) tolerances, it is recommended that maximum frequency of an external clock source is less than
f clk_I/O /2.5.
So we should stay below the controllers clock frequency divided by 2.5, which would be 16MHz / 2.5 = 6.4MHz
for the Nano. But before you reach that, your code might introduce further delays, which make the measurement less accurate. That depends on the implementation.