My poor brain struggling with tricky low pass filter challenge
Wossname
Posts: 174
Hi guys, I wonder if some of you mixed-signal guys could lend me a hand with my current task...
My goal is to generate DTMF audio tones for dialling a telephone number. I can understand how the code should work but I'm having real difficulty understanding how I should create the output filtering circuitry that will effectively low pass filter my square wave output and convert it into a nice clean audio waveform that can be amplified and passed through to a speaker.
I've tried using a PWM square wave frequency of (80_000_000 / 4096) = 19531 Hz. So the duty cycle can be changed 19531 times per second - I chose that because it's a power of two and also more than 10x higher freq than the highest tone that DTMF uses (1633Hz). So my thought was if I use a low pass filter that attenuates everything above say 3000Hz then I should get good audio without the PWM buzz. Is that sensible?
I can get my Propeller code to output a sine-modulated duty cycle square wave but I'm lost as to how to filter this modulated square wave. I've tried to calculate the values for an RC filter but it only seems to work for certain duty cycles and not others.
Has anyone done this before and have a good idea how to design a filter circuit for PWM-audio?
My goal is to generate DTMF audio tones for dialling a telephone number. I can understand how the code should work but I'm having real difficulty understanding how I should create the output filtering circuitry that will effectively low pass filter my square wave output and convert it into a nice clean audio waveform that can be amplified and passed through to a speaker.
I've tried using a PWM square wave frequency of (80_000_000 / 4096) = 19531 Hz. So the duty cycle can be changed 19531 times per second - I chose that because it's a power of two and also more than 10x higher freq than the highest tone that DTMF uses (1633Hz). So my thought was if I use a low pass filter that attenuates everything above say 3000Hz then I should get good audio without the PWM buzz. Is that sensible?
I can get my Propeller code to output a sine-modulated duty cycle square wave but I'm lost as to how to filter this modulated square wave. I've tried to calculate the values for an RC filter but it only seems to work for certain duty cycles and not others.
Has anyone done this before and have a good idea how to design a filter circuit for PWM-audio?
Comments
There may already be DTMF objects in the obj exchange, as well as sine wave generators.
A low pass filter is usually not required but if you need one a simple RC filter should work.
Take a look at http://obex.parallax.com/objects/823/. It includes a DTMF generator.
Re
A low pass filter has a fixed frequency which can't be varied (unless you use fancy things like switched capacitor filters). So if you plug in the R and the C for 3000hz and use PWM at around 20khz then you should get nice sine waves on your CRO.
Try that object kwinn mentioned.
Thinking aloud...
The plan is to pick the low tone and high tone I need for any given DTMF digit, calculate the next sine value for each, sum them, scale the result and then use that as the next duty cycle value which causes the filtered voltage to change a bit, doing this 19531 times per second (the PWM frequency) will give a nice audio waveform.
I understand the DTMF part of it and how to mix two sine values to generate a DTMF tone pair, actually I've done this before using a regular c program and a PC sound card. My problem was that I wasn't getting far enough to even start thinking about the tones themselves, because I couldn't be sure that my RC filter was working right (it wasn't, as it happens).
Yep, the PWM frequency never changes (which makes the RC filter happy), but the PWM duty cycle needs to be sine-modulated which, when passed through a sensible RC low pass filter, will cause the output voltage to become a smooth sine wave - the frequency of which is entirely determined by the PWM duty cycle (not freq) and the RC attenuation curve.
I've actually just found a nice site that helps me calculate this stuff...
http://sim.okawa-denshi.jp/en/PWMtool.php
Anyway, thanks for that link, it looks interesting. For this project, though, I'd rather do it all myself instead of using something from the OBEX, as I'm still learning electronics at a novice level. The chance to understand PWM and RC filtering at the nuts and bolts level will be more valuable to me than using someone else's code.
Anyway, I'll detail what I'm going to use for the time being (pending further analysis)...
- Propeller outputting 19,531.25Hz (80_000_000 / 4096) square wave.
- Resistor: 4.7kΩ (1% tolerance)
- Capacitor: 10nF (10% tolerance)
This should give something like -3db attenuation point of 3400Hz hopefully.
I'm having flashbacks to A-Level maths and all that hideous integration stuff they made us do.
Thanks for the tips guys.
http://www.parallaxsemiconductor.com/an001
If you want to build the code from scratch, that is fine but maybe using the DTMF object will help you understand more quickly how and what the Prop can do as a starting point.
The yellow trace in the attached image is the output from the micro, the blue trace is from a DTMF generator.
That should work.
Can I ask what it is you are driving, and more specifically, is it a high impedance load? A CRO is a high impedance load (megohms), but as an example, a speaker is a very low impedance load (8 ohms) and so will greatly distort your waveform.
A simple solution is a small amplifier, eg an amplifier chip, or amplified computer speakers or something.
In general, you want the impedance of the load to be bigger (10x bigger or more) than the resistor you use in your low pass filter.
If you ever get stuck with impedance matching, an op amp voltage follower solves the problem - put the input into the + side, join the - and the output, and the output follows the input. But the impedance of an op amp is very high so it doesn't load the low pass filter.
That's an interesting technique, but I'm trying to generate a waveform that is as close to perfect as possible with simple components.
My 3 stage filter looks like this at the moment (I've not gotten around to adding the opamp yet though)...
The output will be both a small 8 or 16ohm speaker and also some other circuitry. I'll use an opamp as Dr_Acula suggested. Although I might opt for a audio specialised opamp instead of something like a 741.
What are you trying to do by adding more stages? Do you want a sharper rolloff at the desired frequency? If so, maybe take a look at the schematics for a "third order butterworth filter". There are circuits for filters using inductors, but it is more practical to use the circuits that use op amps. I think a single chip quad op amp will do the job.
Mind you, the rolloff for a single R and C should be fine for this application.
I took some shots for my own records but they show what I mean...
When you say you have a 50% duty cycle square wave, what is the frequency of that wave?
I am assuming it is something much higher than the RC cutoff frequency, say 100khz. Then yes, you should be able to filter it with just one RC filter and get a flat line of 1.5V DC.
But if that square wave is a much lower frequency, say 1khz, then we might need to go right back to the beginning and talk about some PWM basics.
What is the time base on that CRO trace? (maybe just post a photo with the knob settings shown as well)
I deliberately made it quite a lot higher than the highest DTMF tone for that very reason you just said
Anyway, the 3 stage RC filter seems to work well, I'm able to output what appears to be a really nice smooth waveform free from nastiness...
The signal shown here is the DTMF digit "1".
(Ignore some of the measurements on that picture, I've still got to play around with some of the multiplications to make the waveform fit nicely in between 0 and 3.3v, but this is in essence exactly what I was looking for.
Thanks for the input everyone, as always it is much appreciated. This is the best and friendliest forum on the web and long may it remain so
Take a look at this page for how to do multiple filters in series http://en.wikipedia.org/wiki/Roll-off - you need op amp buffers between each stage.
Also - if you put a 19531 hz into an RC filter with a cutoff frequency of 3386Hz, it doesn't block all frequencies above 3386hz. There is a "rolloff" and for a first order filter it is 6db per octave. So a significant proportion of the 19531 square wave is going to get through, and that is exactly what you are seeing on "waveform at A".
The fundamental problem here is the sampling frequency (19531) is too close to the filter frequency (3386).
I wonder if you could try a very simple experiment - try increasing the square wave frequency by 10x to 195310 Hz and measure the waveform at A.
Does anyone have a link to an online filter simulation where you can plug in square waves as the input? If so, it would be great to replicate the waveforms on that CRO, and as Leon says, save a lot of time playing with hardware.
http://www.simetrix.co.uk/
I'll simulate that filter and post the results. It'll be interesting to compare it with the actual results shown on the scope.
A popular free SPICE implementation is LTSpice, available from Linear Technology.
-Phil
I'm an analog noob - LTSpice is waaaaaay over my head - so messing about with hardware is a bit easier even if it is slower.
I worked out how to the DSO to measure FFT spectra - I'm getting a pair of strong signals at around -20db and a few harmonics floating around at about -45db, and a bunch of noise below -60db. Each successive RC stage really suppresses the noise a great deal.
I think this will be enough to work with for the time being.
Thanks again for all your help.
The article itself has a lot of useful points. There is a worked example of a Bell Modem filter with tones of 1200 and 2400 Hz and they chose a PWM frequency of around 64Khz - in other words a frequency a "lot higher".
I also would like to add a vote in support of PhiPi's comment about Duty Mode being better than pulse width.
DUTY mode output is very simple to obtain from a counter and does not need continuously-running code to produce. After setting things up, you simply set frqx to the analog value you want (as a fraction of 232), and the counter does the rest.
-Phil
So I'd use the "DUTY single-ended" mode (%00110) CTRMODE setting? I didn't realise you were referring to the actual Propeller features when you guys mentioned "Duty Mode" - I thought it was some random generic technology I'd never heard of
So you get a 1 cycle-long pulse every time PHSx[31] goes from 1 to 0.
Am I right in the following cases?...
- For a steady 50% duty cycle you'd use a FRQx of (2<<31) -- where every other cycle would cause a carry pulse?
- For a steady 25% duty cycle you'd use a FRQx of (2<<30) -- where every 4th cycle would cause a carry pulse?
- For a steady 33.333333% duty cycle you'd use a FRQx of 715827883?
I might be an order of (binary) magnitude out with those calcs but is that the general idea?
-Phil
-Phil
A simple dual series R/ shunt C, RC filter has always worked for me.
Coming off of the Propellers output pin you have a series 1K ohm resistor, on the other end of this resistor, the end that is not connected to the processor, you will have a .1uf capacitor to ground.
from the junction of the 1K ohm and shunt .1 uf cap to ground you have another series resistor of 1K ohm, at the unconnected end of this 2nd series 1 K ohm resistor you have a .01 uf capacitor to ground.
The filtered sine wave output is at the 2nd 1k and the .01 uf to ground.
To summarize a series 1K, a shunt .1 uf another series 1K and finally a shunt .01 uf.
This will create a nice clean sine wave output passing all the required DTMf tones.
Mike
I decided that the Duty mode method was more fiddly that I was willing to deal with. I could generate sound with it but it didn't sound right and caused some really funky patterns to appear on my scope.
PWM will be more than enough for me I think.
Thanks everyone.