I have recorded a square wave with scope(bit, controlling some unit). I want to measure rise/fall time, the time while the bit is on and off using python. I thought of using the 'derrivetive' np.diff, but the wave is a bit noisy. I wonder if there is some efficient technique to achieve my goal. Thank you, dear community!


1 Answer 1


If it was necessary to get a low noise high quality estimate of the rise and fall time, one idea is to generate an eye diagram and from that create an averaged transition from which we could then accurately with minimized noise compute the 10%/90% rise and fall time (or whatever criteria for settling).

Otherwise is the signal itself is not noisy, a simple approach of determining the min and max signals and 10% and 90% thresholds and establishing times of transition through the thresholds can be done using numpy.where.

Below is my own code for an eye diagram appraoch with modulated waveforms that can be easily used with a train of pulses:

Created on Mon May 20 19:34:28 2019

Eye Diagram Utility

@author: Dan Boschen
import numpy as np
import scipy.signal as sig
import matplotlib.pyplot as plt

def eye(waveform, samp_per_sym, sym_per_win, windows, oversamp=64, plot=True):
    waveform: data 
    samp_per_sym: # of samples per symbol
    sym_per_win: # of symbols to display in eye diagram
    windows: # of sweeps 
    oversamp: oversampling ratio (default = 64)
    plot: will create eyediagram plot if True (real data only)
    xaxis: xaxis time values
    eye: eye diagram magnitudes
    # resample data to emulate continuous waveform
    resamp = int(np.ceil(oversamp/samp_per_sym))
    tx_resamp = sig.resample(waveform, len(waveform) * resamp)
    samp_per_win = oversamp * sym_per_win

    # divide by number of samples per win and then
    # pad zeros to next higher multiple using tx_eye = np.array(tx_shaped),
    # tx_eye.resize(N)

    # N is total number of windows possible
    N = len(tx_resamp)//samp_per_win

    tx_eye = np.array(tx_resamp)
    tx_eye.resize(N * samp_per_win)
    grouped = np.reshape(tx_eye, [N, samp_per_win])
    eye = np.real(grouped.T)

    # create an xaxis in samples np.shape(eye) gives the
    # 2 dimensional size of the eye data and the first element
    # is the interpolated number of samples along the x axis
    nsamps = np.shape(eye)[0]
    xaxis = np.arange(nsamps)/resamp

    if plot:
        # plot showing continuous trajectory of
        plt.plot(xaxis, eye[:, :windows])
        # actual sample locations
        plt.plot(xaxis[::resamp], eye[:, :windows][::resamp], 'b.')
        plt.title("Eye Diagram")

    return xaxis, eye

Alternatively there is open source code available here that is a little more complicated but results in a nice looking plot with persistent intensity:

eye diagram

image source: https://scipy-cookbook.readthedocs.io/_static/items/attachments/EyeDiagram/eye-diagram3.png


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.