Subscribe Bookmark RSS Feed

Extracting data from multiple continuous waveforms using JSL

pilsungpark

Community Trekker

Joined:

Sep 9, 2016

I'm trying to extract time values where continuous rectangular pulses meets V0 potentail.

Though I only showed 2 cycles for 3 wafeforms, there exist more cycles and the number of waveforms is more than 3.

The rising and falling happens in different timing for each waveform, and I wish to find a solution to extract t1_rise, t1_fall, t2_rise, t2_fall... for given data set.

If any of you can enlighten me, it will be tremendously grateful.

 

Thanks,

PiPicture1.png

1 ACCEPTED SOLUTION

Accepted Solutions
txnelson

Super User

Joined:

Jun 22, 2012

Solution

I have put together a simple little script, that with the exception of calculating the 90% and 10% of max (a little confused on what you want there), I think this is kind of what you want.

Names Default To Here( 1 );
dt = Current Data Table();
dt << New Column( "time of crossing" );
dt << New Column( "direction", character );
dt << New Column( "Which threshold", character );
max90 = 5.6;
max10 = .6;

timerise = Function( {MaxPercent},
	:time of crossing[i] = ((MaxPercent - :voltage[i - 1]) / (:voltage[i] - :voltage[i - 1])) * (:time[i] - :time[i - 1]) + :time[i - 1]
);
timefall = Function( {MaxPercent},
	:time of crossing[i] = ((:voltage[i - 1] - MaxPercent) / (:voltage[i - 1] - :voltage[i])) * (:time[i - 1] - :time[i]) + :time[i]
);

For( i = 2, i <= N Rows( dt ), i++,
	If( :waveform[i - 1] != :waveform[i],
		Show( i ),
		If( :voltage[i] >= max10 & :voltage[i - 1] < max10,
			x = timerise( max10 );
			:direction[i] = "Rise";
			:Which Threshold[i] = "10%";
		);
		If( :voltage[i] >= max90 & :voltage[i - 1] < max90,
			x = timerise( max90 );
			:direction[i] = "Rise";
			:Which Threshold[i] = "90%";
		);
		If( :voltage[i] <= max10 & :voltage[i - 1] > max10,
			x = timefall( max10 );
			:direction[i] = "Fall";
			:Which Threshold[i] = "10%";
		);
		If( :voltage[i] <= max90 & :voltage[i - 1] > max90,
			x = timefall( max90 );
			:direction[i] = "Fall";
			:Which Threshold[i] = "90%";
		);
	)
);
Jim
6 REPLIES
txnelson

Super User

Joined:

Jun 22, 2012

Making the assumption that each row has a timestamp, and a voltage value, then it is relitively simple to pass through the data and detect when the data crosses over a specified voltage.  Doing this for multiple waveforms would just be a bit more complex.  What would be helpful is to see what the structure of your data table is.  If you could provide that, I am sure that someone in the community would be able to provide you with a solution

Jim
pilsungpark

Community Trekker

Joined:

Sep 9, 2016

I really appreciate your comment

I attached a sample data table below, and really hope you can give me a solution.

 

As you said, I have equally spaced timestamps for the waveforms which are stacked together in the same column, and the waveform number is categorized in a column which I need to keep. (i.e. I cannot split the column.)

To find the rising and falling time of each rectangular pulse, I wish to find the crossing time of the voltage at 10% and 90% of maximum voltage (excluding overshoots and undershoots which is about 6V) on each rectangular pulse.

If two threshold crossing per one edge is too complicated, I wish to find the way to detect the time for just one threshold crossing.

 

Hope I can find the solution from the community.

 

Thanks,

Pil

 

 

 

 

Thanks,

Pil

txnelson

Super User

Joined:

Jun 22, 2012

Solution

I have put together a simple little script, that with the exception of calculating the 90% and 10% of max (a little confused on what you want there), I think this is kind of what you want.

Names Default To Here( 1 );
dt = Current Data Table();
dt << New Column( "time of crossing" );
dt << New Column( "direction", character );
dt << New Column( "Which threshold", character );
max90 = 5.6;
max10 = .6;

timerise = Function( {MaxPercent},
	:time of crossing[i] = ((MaxPercent - :voltage[i - 1]) / (:voltage[i] - :voltage[i - 1])) * (:time[i] - :time[i - 1]) + :time[i - 1]
);
timefall = Function( {MaxPercent},
	:time of crossing[i] = ((:voltage[i - 1] - MaxPercent) / (:voltage[i - 1] - :voltage[i])) * (:time[i - 1] - :time[i]) + :time[i]
);

For( i = 2, i <= N Rows( dt ), i++,
	If( :waveform[i - 1] != :waveform[i],
		Show( i ),
		If( :voltage[i] >= max10 & :voltage[i - 1] < max10,
			x = timerise( max10 );
			:direction[i] = "Rise";
			:Which Threshold[i] = "10%";
		);
		If( :voltage[i] >= max90 & :voltage[i - 1] < max90,
			x = timerise( max90 );
			:direction[i] = "Rise";
			:Which Threshold[i] = "90%";
		);
		If( :voltage[i] <= max10 & :voltage[i - 1] > max10,
			x = timefall( max10 );
			:direction[i] = "Fall";
			:Which Threshold[i] = "10%";
		);
		If( :voltage[i] <= max90 & :voltage[i - 1] > max90,
			x = timefall( max90 );
			:direction[i] = "Fall";
			:Which Threshold[i] = "90%";
		);
	)
);
Jim
pilsungpark

Community Trekker

Joined:

Sep 9, 2016

It worked out!!

I really appreciate your help, and I'm very happy to learn from you, Jim.

 

After find the way to implement your solution into my jsl code, indeed, I found another issue.

There are few false detections due to oscillation in the waveform.

I could get rid of some false detections happeing after the pulse by removing data points.

But, for the first pulse, several waveforms have multiple detection at rising edge due to a slow rising time. (It can be also found in the sample data table which I enclosed in this thread earlier.)

 

I know I'm bothering you too much, but I cannot think of how to remove those within the pulse.

I wish you can enlighten me a way to filter/ignore them out.

 

Thanks,

Pil

 

 

 

Craige_Hales

Staff

Joined:

Mar 21, 2013

I had a distantly related post on power-line wave forms sometime back.

It includes a graph of a 60Hz wave form with a 1/2 second drop out and some poorly thought out ideas about detecting frequency by counting zero crossings...in particular the frequency calculation created an extreme outlier when the power failed.

Craige
txnelson

Super User

Joined:

Jun 22, 2012

I took the code I had included and just added a deadtime afer a crossing if observered, during which subsequest crossings are ignored.

Names Default To Here( 1 );
dt = Current Data Table();
dt << New Column( "time of crossing" );
dt << New Column( "direction", character );
dt << New Column( "Which threshold", character );
max90 = 5.6;
max10 = .6;
deadtime = .001;
lastcross = -9999999999;

timerise = Function( {MaxPercent},
	:time of crossing[i] = ((MaxPercent - :voltage[i - 1]) / (:voltage[i] - :voltage[i - 1])) * (:time[i] - :time[i - 1]) + :time[i - 1]
);
timefall = Function( {MaxPercent},
	:time of crossing[i] = ((:voltage[i - 1] - MaxPercent) / (:voltage[i - 1] - :voltage[i])) * (:time[i - 1] - :time[i]) + :time[i]
);

For( i = 2, i <= N Rows( dt ), i++,
	If( :waveform[i - 1] != :waveform[i],
		Show( i ),
		If( :voltage[i] >= max10 & :voltage[i - 1] < max10 & :time[i]> lastcross+deadtime,
			lastcross = :time[i];
			x = timerise( max10 );
			:direction[i] = "Rise";
			:Which Threshold[i] = "10%";
		);
		If( :voltage[i] >= max90 & :voltage[i - 1] < max90 & :time[i]> lastcross+deadtime,
			lastcross = :time[i];
			x = timerise( max90 );
			:direction[i] = "Rise";
			:Which Threshold[i] = "90%";
		);
		If( :voltage[i] <= max10 & :voltage[i - 1] > max10 & :time[i]> lastcross+deadtime,
			lastcross = :time[i];
			x = timefall( max10 );
			:direction[i] = "Fall";
			:Which Threshold[i] = "10%";
		);
		If( :voltage[i] <= max90 & :voltage[i - 1] > max90 & :time[i]> lastcross+deadtime,
			lastcross = :time[i];
			x = timefall( max90 );
			:direction[i] = "Fall";
			:Which Threshold[i] = "90%";
		);
	)
);
Jim