# Failed to use a low pass filter in order to convert PWM input to digital output

I want to convert a servo control signal to a digital 5V or 0V output.

This is the format of my PWM signal:

The different thing is my input pulse width will be either 1ms (minimum) or 2ms (maximum.) There can be a slight noise but there are no values like 1.5 ms. Only 1 or 2.

I tried to create a circuit that does this:

When I measure Vout:

• 1 ms pulse width: 170 mV
• 2 ms pulse width: 295 mV

I really do not know why it did not work. I was expecting this:

• 1 ms pulse width: 0V
• 2ms pulse width: 5V

Do you guys know why didn't it work and what I can do to improve it?

• Your filter gives you more or less the average of your signal. The average of a PWM signal that goes from 0 to 5v cannot be zero since anything larger than zero averaged with zero still gives a non-zero value. Sep 16, 2020 at 15:19
• I think I kind of assumed this was the case but still the upper limit is just 295 mV while circuit is powered by 5v. Do you know why is that? I only want to get logic levels so low logic < 0.3 V and high logic > 2.7 V will be enough. What should I do to achieve that? Sep 16, 2020 at 15:31
• That isn't a regular PWM waveform but a "PWM" control signal for a hobby servo. A low pass filter well below the frame rate (like 5 Hz) will "work" but give disappointing results, like ranging between 5% and 10% of the pulse voltage. You need something that can distinguish between 1 ms and 2 ms pulses : you could do that with a couple of 555s and gates, or in software on an Arduino. Sep 16, 2020 at 15:32
• What do you mean by "disappointing results". I am planning on using the output dc voltage to turn on and off a transistor Sep 16, 2020 at 15:35
• Use a servo-actuator to flip a toggle switch! Sep 16, 2020 at 16:06

From the link in the diagram, I assume you are using a microcontroller, possibly an Arduino?

In that case, I would connect the PWM input to an interrupt pin and use the pin-change interrupt to trigger an Interrupt Service Routine (ISR) to measure the on-time of the pulse. The ISR would set/reset a flag to indicate whether it was 1 ms or 2 ms.

• I am currently handling the situation exactly as you described. However, I am actually designing this circuit as a microcontroller fail-safe kind of think. I know microcontrollers are reliable but I have some software issued that can jam the main thread. I am debugging those issues but I still want to solve this particular problem independent from the microcontroller. But thank you for your answer. Sep 16, 2020 at 15:48
• Sounds like you may want to look into using the MCU's watchdog timer. Sep 16, 2020 at 16:57

Do you guys know why didn't it worked and what can I do to improve?

The filter can only average your signal into a DC value. If you directly connected a DC voltage multimeter to your pulsing signal, you'd get exactly the same DC value.

$$\boxed{\text{In other words, the filter isn't bringing any magic to the party}}$$

If you want to do it more effectively you could use a monostable circuit. The monostable would be triggered by the positive rising edge of your digital servo control signal. It would produce a pulse of duration of around 1.5 ms (i.e. it would time-out half way between the two logic level times).

And, when that pulse times out you would use that event to sample the digital servo control signal. You would likely use a D type flip-flop for this and the output would resolve to a 0 or a 1 representing the logic-level behind the digital servo control signal output.

That's how I'd do it anyway.

You could use a comparator after your filtered signal make the logic output but then there are other things to consider such as how much hysteresis is needed, how much RC filtering is needed and how much delay time can be tolerated due to the filter. The monostable/flip-flop will resolve the digital value in one cycle (20 ms) maximum.

• Thank you for your answer sir. It is very informative. I don't understand it currently but I will do my research on the things you said. Hopefully, I will do it. Sep 16, 2020 at 16:10

One Rube Goldberg (UK: Heath Robinson) approach would be to dissect an RC servo and replace the motor with an DC-input optocoupler + series resistor eg. PC817 + 330 ohms. Set the feedback pot to approximately 50% of travel or (more reliable) replace it with two 2.49K resistors.

When the arriving pulses are less than ~1.5ms the servo ASIC will attempt to drive the motor in one direction and the optocoupler LED will conduct. When they are greater than 1.5ms the ASIC will attempt to drive the motor in the reverse direction and the LED will block.

On the receiving end you just need a pullup resistor such as 10K.

You might be able to find the servo ASICs as components, but I don't know the part numbers offhand and most are apparently made by obscure Chinese suppliers.

• I am a beginner so just confirming. You are saying that I should disassemble a micro servo and get the output from where the motor used to be, this way I should get a 5 or 0 v logic signal Sep 16, 2020 at 16:09
• Yes. I'm suggesting putting an optoisolator such as PC817 with the LED input + series resistor where the motor was. The motor is driven with an H-bridge. You might also be able to get a 0V/5V signal right out of one side of the motor driver but I'm suggesting something that should work first time. You can measure and see if you need the optoisolator. There will also be the matter of which state the output goes into when signal is lost, and picking one side or the other of the motor driver may or may not change that, and may or may not require a pullup or pulldown resistor. Sep 16, 2020 at 16:13