I created 2 boards communicating each other like an intercom system. One of them has a button to send a ring signal to the other. The ring signal consists of PWM signals created by an MCU. I want to detect the ringtone by the MCU of the receiver side.

My ringtone contains 4 outer pulses with a period of 300 ms:

outer view

200ms of this signal contains the inner pulses with a period of 1.25ms:

enter image description here

So, I want to add a filter circuit to the receiver side of the ringtone and convert the outer signal to a straight PWM signal. Below is an example output

enter image description here:

So far, I have tried adding an RC low pass filter with a cut of frequency of the outer signal (1/300ms = 3.33Hz). But I couldn't even get close to the example output. Is there anything I misunderstand about the concept since I'm not very experienced in circuit designs?

Regarding my circuit: I just added a series resistor and a parallel capacitor to the node:

enter image description here

Edit: I didn't want to talk about the circuit that handles converting the audio line signal back to the PWM since this is not the subject on this question. But I suspect that my RC filter does not work properly because of that part. I tried the solutions on the answer but they didn't work as expected.

Below is the schematic of my optocoupler side, line input contains the audio signal of the PWM. The audio signal converted back to the PWM by the optocoupler then I get the PWM signal which I gave the screenshots above. But when I add the RC parts to the OPTO_OUTPUT node, PWM signal changes in terms of volts too. Do you think I have a mistake on adding the RC parts?

enter image description here

  • \$\begingroup\$ You are connecting the input signal to another micro controller ? Are you interested by a software solution that would have better accuracy and does not require external components? \$\endgroup\$
    – Damien
    Commented Oct 9, 2018 at 8:47
  • \$\begingroup\$ @Damien Of course, I would like to hear it. I'm trying the solutions on the answers but different ideas can be good too. FYI, I'm sending these audio signals by a line driver (TEA1062). \$\endgroup\$ Commented Oct 9, 2018 at 9:08

4 Answers 4


If you want the 300ms signal to be received, while filtering the 1.25ms one, then it's the high frequency signal you need to filter out, not the other. Which means your chosen time constant is too large and affects the 300ms one. The high frequency signal has a period of 1.25ms, so choose a time constant that is more than 10x larger, say 25ms, which is also more than 10x smaller than the 300ms. Here's a quick test in LTspice:


V(a) shows the modulated output, V(b) shows the filtered output with a time constant of 22ms, and V(c) shows the recovered signal with a minor hysteresis of 10mV to counter the non-ideal filtering of the RC. Notice that the filtered signal has a somewhat thicker trace, that's because of the residual. You could use a Bessel or Gaussian filter for better results, but that would only add to the complexity and, besides, you'll still need the recovery of the signal, so that means you can simplify things.

If your Vcc's value is 5V, then the collector resistor is too much, remember the optoisolators have a strong Ic dependency. If so, then try a 2k2 resistor, which will only use Ic~2.2mA, and you could give up the extra R and place C directly across the collector (10uF, adapted value for time constant). This will get Ic higher when C discharges, though. Otherwise make R=2k7 and C=3u9 (for example). Don't forget that the signal is inverted now, so I've used an inverting hysteresis comparator (the Schmitt trigger). I don't have a TLP opto, so I've just used whatever you see, adapt to your needs. I'm not home right now, but here's an attempt at exemplifying (V(n004) is the 300ms signal):


  • \$\begingroup\$ I can get that your answer should work very well but I couldn't get it to work yet. I guess the problem might be about the circuitry between the MCU and the line input. Can you please look at my edit? \$\endgroup\$ Commented Oct 9, 2018 at 13:47
  • 1
    \$\begingroup\$ @abdullahcinar I've updated my answer, see if it answers your edit. Forgot to add, but the input resistance (R1) might be a bit too low for your needs, as it is it draws ~20mA, but I only did it to make sure the collector doesn't skip pulses. As I said, feel free to adjust to fit your needs. \$\endgroup\$ Commented Oct 9, 2018 at 14:12
  • \$\begingroup\$ Thank you so much for the detailed answer, you are very kind! I'm trying to test it on my setup but it's a little bit hard for me to do it when I don't have this schematic on my PCB. But as you said, I think I will just need to re-calculate the resistors according to my opto (maybe not necessary) and it should work. I will add the results. \$\endgroup\$ Commented Oct 9, 2018 at 14:56
  • \$\begingroup\$ It works very well! \$\endgroup\$ Commented Oct 9, 2018 at 16:20
  • \$\begingroup\$ Using a low-pass filter introduces a delay which doesn't have to be there, and creates slow rising/falling edges which require Schmitt triggers or comparators in order to generate fast edges for digital logic. Not that any of the above has to be a problem (it doesn't seem to be for the OP), but it might be for someone trying to apply this idea to a similar situation. \$\endgroup\$ Commented Oct 15, 2018 at 7:18

Depending on how tightly you want to detect the ring signal, you may need to band-pass filter the received signal (at F = 800 Hz) and then envelope detect it. Alternatively (and this may be preferable) you could use a retriggerable monostable circuit that will produce a constant high output when the "inner signal" is activated. Given your ringing profile, this signal will disappear for about 100 ms every 300 ms. This detects the "envelope" of your ringing signal. You would then need some logic to determine that the envelope shape was approximately correct.

There are other things to look for. There are tone decoder ICs that spring to mind - the LM567 has been used in applications like this many times. Or you could change your basic 800 Hz signal incorporating two tones and use a DTMF decoder chip.


I would use an envelope detector:

enter image description here

If you pick the RC time constant somewhere between the carrier frequency and the signal frequency, you'll get the output looking like this:

enter image description here


You can achieve this directly by the micro-controller.

Doing so has some advantages:

  • No need of external components.
  • No response time / delay caused by the filtering.
  • Higher accuracy.

Basically, I understand you want to know the duty cycle of the PWM signal.

To do that with a micro controller is fairly simple, given your frequency is relatively low, it shouldn't be an issue for the uC to handle it.

You only need a timer and an interrupt.

  • Connect the signal directly to your uC input.
  • Setup a pin driven interrupt in both low and high edge.
  • Setup a timer with a known time period.

When the interrupt is called, first read the value of the timer, then read the state of the pin (low or high).

On the next interrupt, do the same, you then know how long the pin was high or low, do the same for the other edge.

After 4 edge changes happened, you will know precisely how long it was high and low, then you simply need to compute the ratio.

You can repeat this for the whole 200ms signal, recording all the timing and do an average to further improve the stability.


The interrupt will introduce some delay, it is why it is important to read the timer first, so you have minimum delay. You can use high priority interrupt to avoid having other interrupt blocking.

We consider the interrupt delay (with high priority) will always be relatively similar and small differences averaged over the 200ms signal.

  • \$\begingroup\$ We are also considering detecting the signal by the software but we will start with the hardware solution. What you said is a good way, I will consider using this approach. But it will depend on how much will our software be complex. We don't want it to interrupt our other important routines on every 1.25ms. But as I said, this is a good approach which I will consider if we decide to use a software routine to detect the ring. Thank you! \$\endgroup\$ Commented Oct 10, 2018 at 11:48
  • \$\begingroup\$ @abdullahcinar To be honest, this is something I would avoid, unless you already have fast interrupts in your system. You won't be able to disable interrupts for more than 1.25ms without risking to get false results from the detection algorithm, and you'll have to be more careful when writing any time-critical code. \$\endgroup\$ Commented Oct 15, 2018 at 7:10

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.