# How do I generate a trigger signal from a periodic analog signal having varying amplitude [closed]

I have an analog signal detecting a periodic vibration of low frequency (<100Hz) and want to generate a pulse whenever the signal crosses a certain threshold. The challenge is that the amplitude of that periodic waveform may vary. Is there any way to input the analog signal to an arduino and set it to generate a pulse whenever the input crosses a threshold with respect to the peak voltage of of the signal at that instant (say 0.8Vmax). A hardware solution with generic parts and ICs is also welcome.

• How fast does it change amplitude? Can you miss one cycle if it drops too fast? Commented Jul 8 at 12:52
• If the amplitude is varying, then what is the maximum and minimum amplitude you wish to detect, and what should happen outside that range -- can it read in error, should something else mask it off, etc.? Commented Jul 8 at 13:13

With edge triggering, you generally have two main levels: the arming level and the firing level. When your signal passes the arming level (e.g., a 0V DC offset sinusoid rises above 0V), your system awaits the signal to cross your firing level (e.g., some threshold to detect rising/falling edge) or is reset if the signal crosses back over your arming level.

I'm not sure of the exact nature of your signal, but if you are expecting noisy, rectangular/trapezoidal signal, bouncing between 0V (LOW) and 0.7 +/- 0.1V ("HIGH"), then you could code your arming threshold at 0.2V, and your firing threshold at 0.6V.

This stackoverflow question has some answers which address using an interrupt to detect and iterate a counter for rising edges of a 50Hz signal which may be of relevance to you.

• The signal does not have clean sharp edges....It can be thought of as a periodic rumbling that, at least in its positive half represents a very crass sine wave. The arming and firing logic explanation is helpful though and I will be sure to attempt an implementation. Commented Jul 8 at 16:49

Of course, it's impossible to have the circuit trigger as some point on the rising edge of its own cycle, since you can't know what the peak amplitude is until you reach it. You could sample the previous peaks and have the circuit trigger at e.g. 80% of the previous cycle, or the average of the last few cycles, or whatever works best for your situation.

100Hz is pretty slow but depending on your sampling rate, conversion time, and what else your program is doing, there's the chance that you will miss the peak of the incoming waveform. Maybe this error is acceptable, but a pure analog peak-hold circuit would be able to preserve the true peak value until your Arduino gets around to looking at it.

I would use the following:

Since you want a threshold relative to the signal's amplitude, first decide if this is RMS, average, or peak amplitude, and use the corresponding detector on the signal to get the desired value.

If you want to trigger on 0.8Vmax, if Vmax is the peak amplitude, then you'd need a peak detector to get the peak value and hold it in memory, or on a capacitor, depending on implementation.

Then I'd use a hysteresis comparator to compare the incoming signal with a scaled down version of the peak value.

Since frequency is low (100Hz), I'd go with a digital implementation, mostly for flexibility. First analog lowpass filtering then acquisition with a microcontroller ADC at a reasonable sample rate, perhaps a few kHz to 10 kHz. This depends on the signal's frequency content. Even if fundamental frequency is low, if the signal is spiky then it will contain high harmonics which require a higher sample rate than a smooth low-bandwidth signal.

A digital peak detector can be smarter than an analog one without adding circuit complexity. For example, digitally it is easy to measure the peak value on each period and make a per-period peak detector.

Now if you want to trigger on 0.8Vmax before the Vmax peak occurs, then you have a causality problem: your program needs to look into the future to know what Vmax will be.

A solution can be simply to use Vmax from the previous period, or an average from previous periods to reduce noise sensitivity. This is okay if Vmax changes slowly and remains roughly the same from one period to the next.

However if Vmax changes quickly, and each period may have a Vmax value completely different from the previous one(s) then this will not work.

In this case you would need to "look into the future" by buffering the signal, to move the trigger point into the past. I moved the "Now" point on the plot:

Thus when a peak is detected, for example because the derivative of the signal changes sign, get the peak value, then look back into previous memorized samples and find the point where it would have triggered. The drawback is, of course, that you do not get the trigger when voltage crosses 0.8Vmax, so depending on what you want to do with it, it may be too late. If you want to use it to perform an action that must be done when the threshold is reached, then it will be too late. But if you want to use it to perform a computation that can be done on stored signal values, and a slightly delayed result is acceptable, then it is not a problem.