Searching \ for '[PIC] Using PWM to generate an audio sine wave?' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/ios.htm?key=audio
Search entire site for: 'Using PWM to generate an audio sine wave?'.

Exact match. Not showing close matches.
PICList Thread
'[PIC] Using PWM to generate an audio sine wave?'
2011\01\02@050046 by MCH

flavicon
face
Has anyone ever used the PWM port to generate audio tones in a sine wave? Looking to generate a sine wave of between 600 and 2500 Hz with settable frequency. Looking for how to do this on a 18F4550.

Thanks,
Joe M

2011\01\02@051405 by Michael Watterson

face picon face
On 02/01/2011 10:00, MCH wrote:
> Has anyone ever used the PWM port to generate audio tones in a sine
> wave? Looking to generate a sine wave of between 600 and 2500 Hz with
> settable frequency. Looking for how to do this on a 18F4550.
>
> Thanks,
> Joe M.
yes
Also done similar in SW based PWM for wiggling  80286 PC speaker port pin on off and Z80. With Music score table to play tunes on z80 and Wav file playback on 80286

There are many sample programe

2011\01\02@053414 by MCH

flavicon
face
Any Assembly code examples you could point me to? How much resolution would I need? 8-bit? 16-bit? More? I want a pretty pure sounding since wave. I know the more the better, but certainly there is a point that is nearing a true sine wave for practical audio purposes.

I have been searching for hours, and didn't find anything particularly useful. Naturally, within minutes after posting the original question, I found some on-target info. One of the closer places I've found is: <http://www.brouhaha.com/~eric/pic/sine.html> which looks like it's using 8-bit encoding.

I wouldn't mind finding a 16-bit table. I guess it's really the table that is the crux of the matter and not necessarily the PWM part, but if anyone has complete tone generation ASM samples, that would be greatly appreciated. The sample could be generating any tone frequency, but with reference to the actual frequency in Hz would be a plus (IOW, it can be a sample of 1 kHz, but should have a value defined as X=1000 somewhere in the code).

Thanks again,
Joe M.

Michael Watterson wrote:
{Quote hidden}

> There are many sample programe

2011\01\02@054222 by IVP

face picon face
> Looking for how to do this on a 18F4550

Joe, there's an example of how to do this with the 18F67J10

http://ww1.microchip.com/downloads/en/AppNotes/00643c.pdf

I've not tried it myself. Been reading that AN to use just the
ADPCM section with a dsPIC audio DAC, not PWM

Jo

2011\01\02@063356 by IVP

face picon face
Joe,

Scott's pages are worth a look

http://www.dattalo.com/technical/theory/sinewave.html

http://www.dattalo.com/technical/software/software.php

He doesn't do the PWM bit but does cover the data generation

Jo

2011\01\02@072113 by Michael Watterson

face picon face
On 02/01/2011 10:34, MCH wrote:
> Any Assembly code examples you could point me to? How much resolution
> would I need? 8-bit? 16-bit? More? I want a pretty pure sounding since
> wave. I know the more the better, but certainly there is a point that is
> nearing a true sine wave for practical audio purposes.
6bits is usable but noisy & distorted
8bits is what ISDN uses (with uLaw or Alaw compression)
16bits is what CDs use.

The sample rate and bit resolution depend on post filtering and amount of distortion you want
"pretty pure sounding" can be done with 1 bit on/off at desired frequency and suitable filter. So you need to define how pure sounding, frequency and amplitude range and amount of analogue filtering to be used.

Usually I use a 1/4 table of sine values (calculated in a spreadsheet using scaled fixed point arithmetic for result where 1 = max int)  at 8bit or 16 bit resolution for output to PWM register or DAC. you change the DAC or PWM register at the audio sample rate. The PWM clock frequency will be a minimum of PWM bits x sample rate. Sample rate is a minimum of twice your highest audio frequency. Oversampling (x4, x8, x16 etc) allows for simpler single R C filter  for desired distortion level.

So pick highest speed your PWM / PIC can go at.

2011\01\02@080811 by MCH

flavicon
face
Thanks for the reply.

I was thinking of using 1/4 of the table and calculating all 4 phases of the wave based on that (start at 0, go up to the crossover, subtract the table downward from 256 to complete the upward slopes, then reverse the previous two steps. (as a sine wave is symmetrical for each 90 degree phase - just inverted on the horizontal and/or vertical axis). Did that make sense?

Or maybe the table would use less space than the mathematical calculations? I guess I would have to try it both ways unless someone has done that and knows the answer. The math formula would require 2 bits less (I think - since that would only be 1/4 of the table size) or I could keep the same number of bits and put that into increased resolution of the wave table.

I want to keep the post-output filtering down as much as possible. I was thinking a couple of RC circuits just to better even out the transitions from the table values. Maybe just one would work. Again, I guess I'll have to try it and see if I like it.

Good info on the 8 bit vs 16 bit. I wasn't aware that CDs were only 16-bit resolution. But, they are also good to 20 kHz while I only need 1/10th that. Another 3 bits saved or put into higher resolution. Of course, 8 bits is easier to work with.

Thanks for the reply,
Joe M.



Michael Watterson wrote:
{Quote hidden}

2011\01\02@080846 by MCH

flavicon
face
Thanks. I'll check those pages out.

Joe M.

IVP wrote:
> Joe,
>
> Scott's pages are worth a look
>
> www.dattalo.com/technical/theory/sinewave.html
>
> www.dattalo.com/technical/software/software.php
>
> He doesn't do the PWM bit but does cover the data generation
>
> Jo

2011\01\02@083710 by alan.b.pearce

face picon face
> Thanks. I'll check those pages out.
>
> Joe M.
>
> IVP wrote:
> > Joe,
> >
> > Scott's pages are worth a look
> >
> > www.dattalo.com/technical/theory/sinewave.html
> >
> > www.dattalo.com/technical/software/software.php
> >
> > He doesn't do the PWM bit but does cover the data generation

Also download Olins development environment. In there is a Halloween project where he loads sounds into the flash code and then I think he uses the PWM module to generate the sound. He includes a program to convert .WAV files into a suitable form to use for the purpose.
-- Scanned by iCritical.

2011\01\02@083915 by Olin Lathrop

face picon face
MCH wrote:
> Has anyone ever used the PWM port to generate audio tones in a sine
> wave?

Of course.

> Looking to generate a sine wave of between 600 and 2500 Hz with
> settable frequency. Looking for how to do this on a 18F4550.

So go ahead.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\02@092025 by Olin Lathrop

face picon face
MCH wrote:
> Any Assembly code examples you could point me to?

There are probably several out there, but this is so simple, just write it.

> How much resolution would I need? 8-bit? 16-bit? More? I want a
> pretty pure sounding since wave.

You have to decide what signal to noise ratio "pretty pure" is.  60dB, 80dB,
96dB?  In engineering we need real numbers.  You can't design something if
you don't know what to design.  If you don't know how to quantify "pretty
pure", then that is the first design task.

Since it's just a sine wave in the 600Hz to 2.5KHz range, you can do some
post-filtering and get away with quite low resolution.  Think what the
harmonic content of a sine wave with 8 bits resolution is.  Let's say you
want the filter not to change the amplitude over your frequency range much.
Two poles of low pass filter with 5KHz rolloff frequency won't effect your
signal much, but will eliminate just about all quantization noise.

Put it another way, you can get a nice sine wave with sufficient low pass
filtering of a square wave, so starting with a 8 bit resolution sine wave is
way easier.

> I have been searching for hours,

You'd be done now if you spent the time instead just writing the code.  This
is pretty simple stuff.

> I guess it's really the table
> that is the crux of the matter and not necessarily the PWM part,

Don't guess, know.  Actually the sine table isn't the issue, selecting the
right PWM tradeoffs is.

Do the math, and then you can tell for sure what the PWM needs to do.  Let's
say you want a minimum of 60dB signal to noise ratio, and you post filter
with two poles of LPF at 5KHz as I mentioned above.  This filter needs to
attenuate the PWM frequency by 60dB, or by 1000 in voltage, or by sqrt(1000)
= 32 in voltage per filter pole.  5KHz x 32 = 160KHz, which is the minimum
PWM frequency you need to achive 60dB signal to noise ratio.

A 18F4550 can run up to 12MHz instruction rate, which is also therefore the
maximum PWM clock rate (I think, your job to look up).  12MHz / 160KHz = 75,
which is the maximum resolution minus 1 a 160KHz PWM from that PIC can have..
That's only a little more than 6 bits (log2(76) = 6.2 bits equivalent), but
as I pointed out above, resolution isn't that big a deal with the right
filter.

However, after looking all this over, I think 3 low pass filter poles will
be better.  Three at 5KHz will bite into the amplitude of the signal at
2.5KHz a bit.  I don't know whether that matters, since you said nothing
about amplitude flatness.  Still, lets move the filters out to 7.5KHz and
use three of them.  Now the minimum PWM frequency for 60dB is 75KHz, and
resolution is 161.

This is all cutting it close right at 60dB.  Personally I'd want it a bit
better than that and leave some margin.  I'd probably use something like 6
bit resolution, which would give you a PWM frequency of 191KHz.  With three
LPFs at 7.5KHz, the PWM frequency will be attenuated by 84dB.  Also keep in
mind any audio system is going to further squash frequencies in that range,
and of course they are way above what you can hear.  The real reason for
bothering to get rid of them is that they can cause undesirable things to
happen in the audio electronics.  The significant harmonics of a 64 bit sine
wave will be many multiples above the fundamental, so the filters should
squash them nicely.

If you don't care about amplitude flatness, then move the filters lower.
Move them as low as you can tolerated the amplitude variation accross your
frrequency range.  If you want to get fancy, you can add a automatic gain
adjusting circuit to the output, which will let you move the filters much
lower.  However, that is not a beginner circuit.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\02@092647 by Olin Lathrop

face picon face
Michael Watterson wrote:
> Usually I use a 1/4 table of sine values (calculated in a spreadsheet
> using scaled fixed point arithmetic for result where 1 = max int)

I prefer to do this with preprocessor code than importing a table of magic
values from elsewhere.  That way you can see how the values were generated,
and the code can be automatically reconfigured if you want to use a
different resolution or width or whatever.

The preprocessor has sine and cosine built in, and can do real floating
point math.  There is no need to mess with fixed point until the last
conversion to the number actually stored in memory.

> at 8bit or 16 bit resolution for output to PWM register or DAC.

Note that for a PIC 18, the maximum PWM resolution is 10 bits.  Anything
beyond that requires some external hardware like a D/A converter.

However, the PWM resolution isn't much of a limitation here since the
harmonic content from even a low resolution sine is well out there.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\02@093627 by Olin Lathrop

face picon face
MCH wrote:
> I was thinking of using 1/4 of the table and calculating all 4 phases
> of the wave based on that (start at 0, go up to the crossover,
> subtract the table downward from 256 to complete the upward slopes,
> then reverse the previous two steps. (as a sine wave is symmetrical
> for each 90 degree
> phase - just inverted on the horizontal and/or vertical axis). Did
> that make sense?

Yes.  That's the normal way to do it.  A good trick is to represent the
angle of a full circle as 2**N, which is another way of saying a full N bit
unsigned integer.  Angles then wrap naturally as they are added and
subtracted without any explicit code to deal with wrapping.

It also simplifies the 1/4 wave sine lookup.  The second highest bit tells
you whether to index into the table forwards or backwards.  The high bit
tells you whether to invert the result.  The remaining low bits (N-2) are
used to index into the table.  If the table itself is a power of 2 in size,
then some of the index bits specify the table entry, and the remaining lower
ones the interpolation coefficients between that entry and the next.

> Or maybe the table would use less space than the mathematical
> calculations?

Mathematical calculations of sine on a PIC 18 will take a lot of cycles to
get reasonable precision.  On small processors like PICs, table lookups are
almost always the way to go.

> I want to keep the post-output filtering down as much as possible.

Why?  Post filtering is very helpful, and if done effectively relaxes the
requirements on the rest of the system.  There is nothing like plain old
dumb and passive resistors and capacitors for squashing harmonics over a
wide range without introducing their own artifacts.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\02@094324 by Olin Lathrop

face picon face
alan.b.pearce@stfc.ac.uk wrote:
> Also download Olins development environment. In there is a Halloween
> project where he loads sounds into the flash code and then I think he
> uses the PWM module to generate the sound. He includes a program to
> convert .WAV files into a suitable form to use fo

Yes, that's a really old project now, but it worked.  I wouldn't call the
sounds it made "pretty pure", but they were plenty good enough to make
spooky sounds in the woods on either side of the driveway leading to my
house.

That project was done with a PIC 16, which has 14 bit program memory words.
I therefore used 7 bits per sample since two fit nicely into each program
memory word.  The sample rate was also lower than I would have liked, but
such are engineering tradeoffs.  At the time, the biggest PIC had 8K of 14
bit words, so the total length of sound it could store was a tradeoff with
the sample rate, and therefore the audible quantization noise.

Perhaps I should do a updated version of that project using a PIC 18 with
large program memory.  That would allow more sound and considerably higher
quality at the same time.  Maybe add a class D audio output to extend
battery life, just as a demonstration.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\02@102454 by Michael Watterson

face picon face
On 02/01/2011 14:44, Olin Lathrop wrote:
> Perhaps I should do a updated version of that project using a PIC 18 with
> large program memory.  That would allow more sound and considerably higher
> quality at the same time.  Maybe add a class D audio output to extend
> battery life, just as a demonstration.
One 18FxxJxx has up to 1M Flash. You could implement mass storage and use USB to download 8 bit sound to it.

Drive FET push-pull from PWM at highest speed (6bits or 8 bits) and series LC filter tuned to sample rate at  feeding loudspeaker. An air cored coil for a Cross-over network should be good?

2011\01\02@110023 by N. T.

picon face
Olin Lathrop wrote:
>
> Note that for a PIC 18, the maximum PWM resolution is 10 bits.  Anything
> beyond that requires some external hardware like a D/A converter.
>

Yes for this type of projects, but in general to get greater
resolution he can set CCP mode to "Compare mode", let the counters run
free and on each CCPx pin event reload 16-bit CCPRx register.

The CCPx pin - the PWM output - can be toggled once over many CCPx pin
events, so the resolution can be even greater than 16-bit. And running
the counters free means "no-jitter".

Hope it makes sense.

2011\01\02@125551 by Olin Lathrop

face picon face
N. T. wrote:
>> Note that for a PIC 18, the maximum PWM resolution is 10 bits.
>> Anything beyond that requires some external hardware like a D/A
>> converter.
>
> Yes for this type of projects, but in general to get greater
> resolution he can set CCP mode to "Compare mode", let the counters run
> free and on each CCPx pin event reload 16-bit CCPRx register.

I should have qualified 10 bits is the greatest resolution this *hardware*
can produce directly.  Of course in software you can do anything.

The method you describe uses the special hardware but also requires software
intervention every PWM pulse.  A CCP module in one-shot mode does have 16
bit resolution instead of 10, since is uses a 16 bit timer.  That can be a
useful technique if you need really high output resolution at low bandwidth..

If you are using it for repetitive PWM, you have to be very careful to count
the dead cycles between one-shot pulses, as they can add to the PWM period.
Even with interrupts this is tricky if anything else is also causing
interrupts.  Depending on how you are using the hardware, the timer may need
to be examined to actively de-jitter the period.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\02@144445 by N. T.

picon face
Olin Lathrop wrote:
> The method you describe uses the special hardware but also requires software
> intervention every PWM pulse.  A CCP module in one-shot mode does have 16
> bit resolution instead of 10, since is uses a 16 bit timer.  That can be a
> useful technique if you need really high output resolution at low bandwidth.
>
> If you are using it for repetitive PWM, you have to be very careful to count
> the dead cycles between one-shot pulses, as they can add to the PWM period.
> Even with interrupts this is tricky if anything else is also causing
> interrupts.  Depending on how you are using the hardware, the timer may need
> to be examined to actively de-jitter the period.

Yes it is tricky if the counter is reset each time. But if the counter
is "free running", that is it does not getting reset, there is no dead
cycles between PWM pulses. You need just recalculate and reload CCPRx
register anywhere between CCPx pin events. When the counter matches
new CPRx value, the pin toggles. And yes, it is software PWM. It
limits PWM frequency to some hundreds KHz on fast PICs.

2011\01\02@151918 by N. T.

picon face
Olin Lathrop wrote:
> I should have qualified 10 bits is the greatest resolution this *hardware*
> can produce directly.  Of course in software you can do anything.
>
> The method you describe uses the special hardware but also requires software
> intervention every PWM pulse.  A CCP module in one-shot mode does have 16
> bit resolution instead of 10, since is uses a 16 bit timer.

Interesting, if both approaches were 10 bits resolutions, the
described "software" approach could be more precise if PWM frequency
variation were acceptable.
- hardware 10 bit PWM: change duty cycle from 500 to 501 is 0.2% change.
- software 10 bit PWM: difference between "500 off / 500 on" mode to
"500 off / 501 on" will be
501/(501+500) - 500/(500+500) = 0.0005 that is 0.05% - 4 times less to
the hardware case (extra 2 bits).

2011\01\03@072341 by Olin Lathrop

face picon face
N. T. wrote:
> - hardware 10 bit PWM: change duty cycle from 500 to 501 is 0.2%
> change.
> - software 10 bit PWM: difference between "500 off / 500 on" mode to
> "500 off / 501 on"

But that changes the PWM period.  If you change the PWM period as you change
the desired duty cycle, you end up with low frequency components in the
signal.  That can be fine in some cases, but it's not really apples to
apples comparison.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\03@074633 by Dave Tweed

face
flavicon
face
Olin Lathrop wrote:
> N. T. wrote:
> > - hardware 10 bit PWM: change duty cycle from 500 to 501 is 0.2%
> > change.
> > - software 10 bit PWM: difference between "500 off / 500 on" mode to
> > "500 off / 501 on"
>
> But that changes the PWM period. If you change the PWM period as you change
> the desired duty cycle, you end up with low frequency components in the
> signal. That can be fine in some cases, but it's not really apples to
> apples comparison.

If the hardware PWM doesn't give you the resolution you need, couldn't you
use delta-sigma techniques to keep track of the accumulated error, and
adjust the width of future pulses based on that? Perhaps a bit of dithering
(pseudorandom noise) could be added to help hide any spurious tones generated
thereby.

-- Dave Twee

2011\01\03@082915 by Olin Lathrop

face picon face
Dave Tweed wrote:
> If the hardware PWM doesn't give you the resolution you need,
> couldn't you use delta-sigma techniques to keep track of the
> accumulated error, and adjust the width of future pulses based on
> that? Perhaps a bit of dithering (pseudorandom noise) could be added
> to help hide any spurious tones generated thereby.

You can dither the PWM duty cycle and get better duty cycle resolution, but
note that this introduces additional frequencies below the main PWM
frequency.  For example, if you are dithering between two duty cycle values
in successive cycles, then you introduce noise components at half the PWM
frequency.  Whether that matters or not depends on the application, but it's
important to keep in mind the extra resolution isn't free.  Of course making
the PWM frequency half and using a fixed duty cycle makes the power in the
lower PWM frequency much higher.

The problem with delta-sigma and accumulated error techniques in general is
that you can't guarantee a lower frequency bound of the PWM noise part of
the signal, which in turn means it's hard to not have it interpreted as the
real signal.  Again, there are ways to mitigate this, but it has to be kept
in mind.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000

2011\01\03@090932 by alan.b.pearce

face picon face
{Quote hidden}

On the other hand you could just go to a 24F device which do have a true 16 bit PWM, and the small pinout ones do come in DIP packages if that is a requirement.
-- Scanned by iCritical.

2011\01\03@110108 by N. T.

picon face
Olin Lathrop wrote:
> N. T. wrote:
>> - hardware 10 bit PWM: change duty cycle from 500 to 501 is 0.2%
>> change.
>> - software 10 bit PWM: difference between "500 off / 500 on" mode to
>> "500 off / 501 on"
>
> But that changes the PWM period.  If you change the PWM period as you change
> the desired duty cycle, you end up with low frequency components in the
> signal.  That can be fine in some cases, but it's not really apples to
> apples comparison.

Yes, from the example to tweak under 0.2% duty cycle you need  "500
off / 504 on" period, that is 0.4%.frequency modulation. For some apps
that may not be acceptable. But if you only low pass your PWM signal,
0.4%.frequency modulation seems not to be a big problem.

2011\01\03@130923 by Pete Restall

flavicon
face
On Mon, 03 Jan 2011 07:46:33 -0500, Dave Tweed wrote:

> If the hardware PWM doesn't give you the resolution you need, couldn't
> you use delta-sigma techniques to keep track of the accumulated error,
> and adjust the width of future pulses based on that? Perhaps a bit of
> dithering (pseudorandom noise) could be added to help hide any
> spurious tones generated thereby.

Forgive me if this has already been mentioned (piclist reading is a bit
sporadic of late), but could two (8-bit) PWM channels be tied together
with an R2R ladder ?  Pretty simple and has worked for me before, but it
does require a couple of external parts, plus the obvious extra PWM pin,
and of course the ability to vary the PWM duty-cycles independently.

Regards,

Pete Restall

2011\01\03@160856 by Michael Watterson

face picon face
On 03/01/2011 16:01, N. T. wrote:
> Olin Lathrop wrote:
>> N. T. wrote:
>>> - hardware 10 bit PWM: change duty cycle from 500 to 501 is 0.2%
>>> change.
>>> - software 10 bit PWM: difference between "500 off / 500 on" mode to
>>> "500 off / 501 on"
>> But that changes the PWM period.  If you change the PWM period as you change
>> the desired duty cycle, you end up with low frequency components in the
>> signal.  That can be fine in some cases, but it's not really apples to
>> apples comparison.
> Yes, from the example to tweak under 0.2% duty cycle you need  "500
> off / 504 on" period, that is 0.4%.frequency modulation. For some apps
> that may not be acceptable. But if you only low pass your PWM signal,
> 0.4%.frequency modulation seems not to be a big problem.
>
no.
F.M. can't be removed by filter. The PWM frequency must be fixed. Very bad idea if it changes

2011\01\03@164937 by N. T.

picon face
Michael Watterson wrote:
> On 03/01/2011 16:01, N. T. wrote:
>> Olin Lathrop wrote:
>>> N. T. wrote:
>>>> - hardware 10 bit PWM: change duty cycle from 500 to 501 is 0.2%
>>>> change.
>>>> - software 10 bit PWM: difference between "500 off / 500 on" mode to
>>>> "500 off / 501 on"
>>> But that changes the PWM period.  If you change the PWM period as you change
>>> the desired duty cycle, you end up with low frequency components in the
>>> signal.  That can be fine in some cases, but it's not really apples to
>>> apples comparison.
>> Yes, from the example to tweak under 0.2% duty cycle you need  "500
>> off / 504 on" period, that is 0.4%.frequency modulation. For some apps
>> that may not be acceptable. But if you only low pass your PWM signal,
>> 0.4%.frequency modulation seems not to be a big problem.
>>
> no.
> F.M. can't be removed by filter. The PWM frequency must be fixed. Very
> bad idea if it changes.

Low pass filter would detect FM?
:-)

2011\01\06@182146 by IVP

face picon face
Joe,

looking for something and came across this

http://mondo-technology.com/

Check out the Function Generator (admittedly I haven't too
closely, still chasing material for my own project)

Jo

More... (looser matching)
- Last day of these posts
- In 2011 , 2012 only
- Today
- New search...