@@ -39,6 +39,7 @@ PulseWidthMeasurement::PulseWidthMeasurement(const string& color)
3939 : Filter(color, CAT_MEASUREMENT)
4040{
4141 AddStream (Unit (Unit::UNIT_FS), " data" , Stream::STREAM_TYPE_ANALOG, Stream::STREAM_DO_NOT_INTERPOLATE);
42+ AddStream (Unit (Unit::UNIT_VOLTS), " Amplitude" , Stream::STREAM_TYPE_ANALOG, Stream::STREAM_DO_NOT_INTERPOLATE);
4243
4344 // Set up channels
4445 CreateInput (" din" );
@@ -91,12 +92,20 @@ void PulseWidthMeasurement::Refresh()
9192 auto uddin = dynamic_cast <UniformDigitalWaveform*>(din);
9293 auto sddin = dynamic_cast <SparseDigitalWaveform*>(din);
9394 vector<int64_t > edges;
95+ float average_voltage = 0 ;
96+ float max_value;
97+ size_t temp = 0 ;
98+
99+ if (uadin)
100+ average_voltage = GetAvgVoltage (uadin);
101+ else if (sadin)
102+ average_voltage = GetAvgVoltage (sadin);
94103
95104 // Auto-threshold analog signals at 50% of full scale range
96105 if (uadin)
97- FindZeroCrossings (uadin, GetAvgVoltage (uadin) , edges);
106+ FindZeroCrossings (uadin, average_voltage , edges);
98107 else if (sadin)
99- FindZeroCrossings (sadin, GetAvgVoltage (sadin) , edges);
108+ FindZeroCrossings (sadin, average_voltage , edges);
100109
101110 // Just find edges in digital signals
102111 else if (uddin)
@@ -111,11 +120,19 @@ void PulseWidthMeasurement::Refresh()
111120 return ;
112121 }
113122
114- // Create the output
123+ // Create the output for pulse width waveform
115124 auto cap = SetupEmptySparseAnalogOutputWaveform (din, 0 , true );
116125 cap->m_timescale = 1 ;
117126 cap->PrepareForCpuAccess ();
118127
128+ // Create the output for amplitude waveform for analog inputs only
129+ auto cap1 = (uadin || sadin) ? SetupEmptySparseAnalogOutputWaveform (din, 1 , true ) : NULL ;
130+ if (cap1)
131+ {
132+ cap1->m_timescale = 1 ;
133+ cap1->PrepareForCpuAccess ();
134+ }
135+
119136 size_t elen = edges.size ();
120137 for (size_t i=0 ; i < (elen - 2 ); i+= 2 )
121138 {
@@ -125,15 +142,81 @@ void PulseWidthMeasurement::Refresh()
125142
126143 int64_t delta = end - start;
127144
145+ // Push pulse width information
128146 cap->m_offsets .push_back (start);
129147 cap->m_durations .push_back (delta);
130148 cap->m_samples .push_back (delta);
149+
150+ // Find amplitude information for the pulses
151+ if (uadin)
152+ {
153+ int64_t start_index = (start - din->m_triggerPhase ) / din->m_timescale ;
154+ int64_t end_index = (end - din->m_triggerPhase ) / din->m_timescale ;
155+ max_value = average_voltage;
156+
157+ // Find out the maximum value of the pulse within boundary of the detected pulse
158+ for (int64_t j = start_index; j < end_index; j++)
159+ {
160+ if (uadin->m_samples [j] > max_value)
161+ max_value = uadin->m_samples [j];
162+ }
163+
164+ // Push amplitude information
165+ cap1->m_offsets .push_back (start);
166+ cap1->m_durations .push_back (delta);
167+ cap1->m_samples .push_back (max_value);
168+ }
169+ else if (sadin)
170+ {
171+ int64_t start_offs = (start - din->m_triggerPhase ) / din->m_timescale ;
172+ int64_t end_offs = (end - din->m_triggerPhase ) / din->m_timescale ;
173+ max_value = average_voltage;
174+
175+ // Parse the waveform to get to a detected pulse
176+ for (size_t j = temp; j < sadin->size (); j++)
177+ {
178+ // Find out maximum value of the pulse within boundary of the detected pulse
179+ if ((sadin->m_offsets [j] >= start_offs) && (sadin->m_offsets [j] <= end_offs))
180+ {
181+ if (sadin->m_samples [j] > max_value)
182+ max_value = sadin->m_samples [j];
183+ }
184+
185+ // End of one pulse reached. Record j, so that next time we start from this index for next pulse if any
186+ else if (sadin->m_offsets [j] > end_offs)
187+ {
188+ temp = j;
189+ break ;
190+ }
191+ }
192+
193+ // Push amplitude information
194+ cap1->m_offsets .push_back (start);
195+ cap1->m_durations .push_back (delta);
196+ cap1->m_samples .push_back (max_value);
197+ }
131198 }
132199
133200 SetData (cap, 0 );
134-
135201 cap->MarkModifiedFromCpu ();
136202
203+ if (sadin || uadin)
204+ {
205+ // Set amplitude output waveform
206+ SetData (cap1, 1 );
207+ cap1->MarkModifiedFromCpu ();
208+ }
209+ else if (uddin || sddin)
210+ {
211+ // Switch output waveform to digital
212+ m_streams[1 ].m_stype = Stream::STREAM_TYPE_DIGITAL;
213+ m_streams[1 ].m_flags = 0 ;
214+
215+ // For digital inputs, amplitude information is same as input
216+ SetData (din, 1 );
217+ din->MarkModifiedFromCpu ();
218+ }
219+
137220 if (GetVoltageRange (0 ) == 0 )
138221 SetVoltageRange (10000000000000 , 0 );
139222}
0 commit comments