{"id":3770,"date":"2020-06-17T13:52:59","date_gmt":"2020-06-17T13:52:59","guid":{"rendered":"http:\/\/www.raymaps.com\/?p=3770"},"modified":"2022-06-03T12:20:05","modified_gmt":"2022-06-03T12:20:05","slug":"frequency-estimation-using-zero-crossing-method","status":"publish","type":"post","link":"https:\/\/www.raymaps.com\/index.php\/frequency-estimation-using-zero-crossing-method\/","title":{"rendered":"Frequency Estimation Using Zero Crossing Method"},"content":{"rendered":"\n<p>A sinusoidal signal is the most fundamental type of signal that exists in communication systems, power systems, navigation systems etc. It is controlled by three parameters which are the amplitude, phase and frequency. The last two, that is phase and frequency, are interconnected. As discussed in my previous post Instantaneous Frequency (IF) is nothing but the rate of change of phase. This can be mathematically described as:<\/p>\n\n\n<p style=\"text-align: center;\">IF=\u0394\u03c6\/\u0394t<\/p>\n\n\n<!--more-->\n\n\n\n<p>It is sometimes important in communication systems to estimate the phase and frequency of the signal arriving at the receiver. This is especially true for Phase Modulated (PM) and Frequency Modulated (FM) systems. But any synchronous communication system requires that the carrier phase and frequency is synchronized between the transmitter and receiver. For more on carrier phase and frequency synchronization error please see my previous <a href=\"http:\/\/www.raymaps.com\/index.php\/modeling-phase-and-frequency-synchronization-error\/\">post<\/a>.<\/p>\n\n\n\n<p>There are number of ways to estimate the\nfrequency of a sine wave, from Fast Fourier Transform (FFT), to Autoregressive\n(AR) methods, to high resolution spectral estimation methods such as MUSIC* and\nESPRIT**. The challenge here is to perform an accurate estimation with minimum\nnumber of samples and in presence of high noise and interference. Sometimes it\nis also required to detect multiple sinusoids simultaneously, which are\noverlapping in time domain and closely spaced in the frequency domain. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p>In this post we present the simplest method\nof frequency estimation that is called the Zero Crossing (ZC) method. Since a\nsine wave crosses the x-axis twice during each cycle, we can simply count the\nnumber of crossings and divide it by two and again divide it by the observation\nwindow size, giving us the frequency in Hertz. Please note that for this scheme\nto work we need to have a few complete cycles. Higher the length of the\nobservation window greater is the accuracy. <\/p>\n\n\n\n<p>It has been shown in [1] that at high Signal to Noise Ratio (SNR &gt; 10dB) ZC estimator approaches the Cramer Rao Lower Bound (CRLB). &nbsp;MATLAB code for the ZC method is given below. For comparison we have also included the FFT method in our simulation and results are shown in the figure below. Please remember that accuracy of the FFT method depends upon the window size T in the time domain. Mathematically, the frequency bin size is given as:<\/p>\n\n\n<p style=\"text-align: center;\">\u0394f=1\/T<\/p>\n\n\n<p>To separate two sinusoids the minimum separation must be  2\u0394f and not \u0394f as there needs to be a vacant bin between the two sinusoids. Also, we experimented with the frequency resolution of Zero Crossing detector and it was found out to be \u0394f\/2 (although, unlike FFT, this method can detect only one tone at a time). It must be noted that frequency resolution of FFT does not increase by increasing the sampling frequency. In fact if sampling frequency is increased and number of samples remains the same, frequency resolution in fact decreases.<\/p>\n\n\n\n<pre lang=\"MATLAB\">\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%     FREQUENCY ESTIMATION\n%            USING\n%     ZERO CROSSING METHOD\n%       www.raymaps.com\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\nclear all\nclose all\n\nN=1e6;              % Number of samples\nfc=1e9;             % Carrier frequency\nfs=10*fc;           % Sampling frequency\nts=1\/fs;            % Sampling interval\nt=0:ts:N*ts;        % Total time\ndp=pi\/6;            % Phase offset\ndf=20e3;            % Frequency offset\n\ntx_carrier=sqrt(2)*cos(2*pi*fc*t);\nrx_carrier=sqrt(2)*cos(2*pi*(fc+df)*t+dp)+0.1*randn(1,N+1);\n\n% Frequency Estimation at Transmitter\ncount=0;\nfor n=1:N\n  if tx_carrier(n)>0 && tx_carrier(n+1)<0   % -ve going\n    count=count+1;\n  end\n  if tx_carrier(n)<0 &#038;&#038; tx_carrier(n+1)>0   % +ve going\n    count=count+1;\n  end\nend\ntx_freq_estimate=count\/2\/t(end)\n\n% Frequency Estimation at Receiver\ncount=0;\nfor n=1:N\n  if rx_carrier(n)>0 && rx_carrier(n+1)<0   % -ve going\n    count=count+1;\n  end\n  if rx_carrier(n)<0 &#038;&#038; rx_carrier(n+1)>0   % +ve going\n    count=count+1;\n  end\nend\nrx_freq_estimate=count\/2\/t(end)\n\n% Fourier Transform\ntwo_tones=tx_carrier+rx_carrier;\nfft_two_tones=abs(fft(two_tones));\nfft_two_tones=fft_two_tones\/max(fft_two_tones);\nf=0:1\/t(end):(N)*(1\/t(end));\nplot(f,10*log10(fft_two_tones),'linewidth',3);\naxis([fc-2*df fc+2*df -15 5])\nxlabel('Frequency')\nylabel('Magnitude')\ntitle('Fourier Transform')\ngrid on\n<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"http:\/\/www.raymaps.com\/wp-content\/uploads\/2020\/06\/FFT-Two-Tones-1024x768.png\" alt=\"\" class=\"wp-image-3773\" srcset=\"https:\/\/www.raymaps.com\/wp-content\/uploads\/2020\/06\/FFT-Two-Tones-1024x768.png 1024w, https:\/\/www.raymaps.com\/wp-content\/uploads\/2020\/06\/FFT-Two-Tones-300x225.png 300w, https:\/\/www.raymaps.com\/wp-content\/uploads\/2020\/06\/FFT-Two-Tones-768x576.png 768w, https:\/\/www.raymaps.com\/wp-content\/uploads\/2020\/06\/FFT-Two-Tones.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>FFT of Two Tones Embedded in Noise<\/figcaption><\/figure>\n\n\n\n<p>Note: The frequency estimate of Zero Crossing method can be improved greatly by using a simple Moving Average (MA) filter before the detection of Zero Crossings.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Complex Exponential <\/h2>\n\n\n\n<p>Sometimes the signal is not real (sinusoid) but is complex in nature (exponential). For such a case the above code can be slightly modified to do the Zero Crossing calculation. The method we adopt is to do the Zero Crossing calculation for both the real and imaginary parts separately and then take the average. The noise that is added to the signal is also complex in nature now. Last thing we want to mention is that applying a Moving Average filter just before the ZC algorithm greatly improves the estimate. The MATLAB\/Octave code for this is given below.<\/p>\n\n\n\n<pre lang=\"MATLAB\">\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n%     FREQUENCY ESTIMATION\n%            USING\n% ZERO CROSSING METHOD (COMPLEX)\n%       www.raymaps.com\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\nclear all\nclose all\n\nN=1000;             % Number of samples\nfc=1e9;             % Carrier frequency\nfs=10*fc;           % Sampling frequency\nts=1\/fs;            % Sampling interval\nt=0:ts:N*ts;        % Total time\ndp=2*pi*(rand-0.5); % Random phase offset\ndf=1e6*(rand-0.5);  % Random frequency offset\n\nwhite_noise=sqrt(0.1\/2)*(randn(1,N+1)+i*randn(1,N+1));\ntx_carrier=exp(i*2*pi*fc*t);\nrx_carrier=exp(i*2*pi*(fc+df)*t+dp)+white_noise;\nrx_carrier=conv(rx_carrier, ones(1,5),'same');\n\n% Frequency Estimation at Receiver (Real Part)\ncount1=0;\nfor n=1:N\n  if real(rx_carrier(n))>0 && real(rx_carrier(n+1))<0   % -ve going\n    count1=count1+1;\n  end\n  if real(rx_carrier(n))<0 &#038;&#038; real(rx_carrier(n+1))>0   % +ve going\n    count1=count1+1;\n  end\nend\n\n% Frequency Estimation at Receiver (Imaginary Part)\ncount2=0;\nfor n=1:N\n  if imag(rx_carrier(n))>0 && imag(rx_carrier(n+1))<0   % -ve going\n    count2=count2+1;\n  end  \n  if imag(rx_carrier(n))<0 &#038;&#038; imag(rx_carrier(n+1))>0   % +ve going\n    count2=count2+1;\n  end\nend\n\nrx_freq_estimate=mean([count1\/2\/t(end) count2\/2\/t(end)]);\nfreq_error=(fc+df)-rx_freq_estimate\n<\/pre>\n\n\n\n<p>[1] Yizheng Liao, \u201cPhase and Frequency Estimation: High-Accuracy and Low-Complexity Techniques,\u201d MS Thesis Worcester Polytechnic Institute, May 2011.<\/p>\n\n\n\n<p>* MUSIC: Multiple Signal Classification<\/p>\n\n\n\n<p>** ESPRIT: Estimation of Signal Parameters\nvia Rotational Invariance Technique<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post we present the simplest method of frequency estimation that is called the Zero Crossing (ZC) method. Since a sine wave crosses the x-axis twice during each cycle, we can simply count the number of crossings and divide it by two and again divide it by the observation window size, giving us the frequency in Hertz.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[81],"tags":[77,82,70,220,222],"class_list":["post-3770","post","type-post","status-publish","format-standard","hentry","category-fundamentals","tag-awgn","tag-fft","tag-frequency","tag-phase","tag-zero-crossing"],"_links":{"self":[{"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/posts\/3770","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/comments?post=3770"}],"version-history":[{"count":9,"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/posts\/3770\/revisions"}],"predecessor-version":[{"id":4274,"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/posts\/3770\/revisions\/4274"}],"wp:attachment":[{"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/media?parent=3770"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/categories?post=3770"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.raymaps.com\/index.php\/wp-json\/wp\/v2\/tags?post=3770"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}