# Finding period of a square wave with varying sampling frequency

I have a square wave (0-1.8V) with a varying sampling frequency (from a circuit simulator). It is also not a perfect square wave (the high and low signal could be very close to but not precisely zero or 1 Volt) and the fall time is slightly slower than the rise time.

Another factor is that I will retake the data and the period (and possibly duty cycle as well) will change when I alter another parameter, so I am not working with a fixed number of cycles per window.

I tried autocorrelation but it seems that it gave me double or so the actual period. And fft seems to need a fixed sampling rate. What would be the best solution to finding the period of this square wave?

• Can you add more details about the autocorrelation giving you double the actual period? – MBaz Mar 14 at 16:42
• @Mbaz it seems that when I autocorrelate the signal my guess is that it might be counting the period as a positive edge going to negative edge, as opposed to positive edge going to the next positive edge. However, since I am almost sure duty cycle will always be 50% I can just divide by 2. However, MATLAB records the distance between peaks in the acorrelated signal as a vector and for some reason the first and last elements are smaller than the middle ones, so I just end up clipping those edges out – user P520 Mar 14 at 18:01
• When you shift the signal by half a period, so that the rising edge of the original matches the falling edge of the shifted signal, the correlation should be zero, shouldn't it? – MBaz Mar 14 at 19:08

Pick a nice center value, say 1.0, scan across looking for crossings from down to up (or the reverse). Mark the spot of your first crossing, count up some fixed number of crossings, call the count N. Take your system timer value at your first crossing and your last crossing. Divide the time interval by N and you'll have a very good estimate of the period. How uneven the crossings are in the interval is immaterial. If you can assure the two crossing that you are timing happen in "the same state", you will lose one more level of uncertainty.

You can't do it much simpler than that. Increased accuracy will come from interpolating the crossing point rather than taking the closest sample's time.

## ----------------------

You'll have to figure the Interpolate routine out yourself. It's not that hard.

The logic is very straightforward and significantly less computationly heavy than an auto-correlation technique. More accurate in this case too.

Pseudo-code


FirstIndex = -1
N = 0

For i = 0 to PointCount
If signal[i] <= 1.0 and signal[i+1] > 1.0 Then
If FirstIndex < 0 Then
T1A = System.Time(i)
T1B = System.Time(i+1)
FirstIndex = i
Else
TNA = System.Time(i)
TNB = System.Time(i+1)
LastIndex = i
N += 1
End If
End If
Next

T1 = Interpolate( T1A, T1B, Signal[FirstIndex], Signal[FirstIndex+1] )
TN = Interpolate( TNA, TNB, Signal[LastIndex], Signal[LastIndex+1] )

Period = ( TN - T1 ) / N


You may not need to interpolate, (TNA - T1A)/N may be accurate enough.

• I really like this idea. When a line is drawn through the points it definitely gives the illusion they intersect on every rising and falling edge. However, since they are discrete points and very close together I dont see how to add in a threshold to get exactly one crossing point through that reference line. Any thoughts? @CedronDawg – user P520 Mar 17 at 0:40
• @userP520, See my followup. – Cedron Dawg Mar 17 at 1:02