<div dir="ltr">Richie, <div>Thanks for explaining more clearly. Seems my visualization skills are better than my writing skills. </div><div><br></div><div>I saw mention of the "bit reversed PWM", but couldn't find the email describing it.</div><div>Can you sketch the idea? I'll try making a chart of that too.</div><div>-David K.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Dec 11, 2023 at 2:10 AM <<a href="mailto:rburnett@richieburnett.co.uk">rburnett@richieburnett.co.uk</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">For each constant that you repeatedly add to the NCO you get a unique <br>
bit-pattern generated. And the amount of 1's in one period of that bit <br>
pattern is proportional to the constant that you add into the NCO. The <br>
funky pattern is a graphical representation of this...<br>
<br>
Notice how the plot is lighter at the bottom and darker towards the top. <br>
That is because the density of 1's and 0's changes as you move up the <br>
plot and the constant being added into the NCO is larger. White pixels <br>
look like they represent 0's and black pixels represent 1's. The bottom <br>
row is white right across, so that is a run of 256 zeros. The top row <br>
is black right across, so that's a run of 256 ones. And all of the rows <br>
in between have varying numbers of 0's and 1's roughly evenly <br>
distributed across the row.<br>
<br>
Now if you look at the equivalent picture for PWM you'll see that all of <br>
the 0's (white pixels) and 1's (black pixels) are grouped together in <br>
each row. That is because PWM goes high for the programmed pulse width <br>
then returns low for the remainder of the period.<br>
<br>
Now I'm wondering what my "bit reversed PWM" would look like on one of <br>
these plots...?<br>
<br>
-Richie,<br>
<br>
<br>
On 2023-12-11 09:54, cheater cheater via Synth-diy wrote:<br>
>> He's plotted the output from the algorithm as black and white pixels <br>
>> (the x axis) for each "DAC output value" (the y-axis).<br>
> <br>
> ugh, still struggling. i don't know what that means. :S<br>
> <br>
> On Mon, Dec 11, 2023 at 10:29 AM Tom Wiltshire <<a href="mailto:tom@electricdruid.net" target="_blank">tom@electricdruid.net</a>> <br>
> wrote:<br>
>> <br>
>> He's plotted the output from the algorithm as black and white pixels <br>
>> (the x axis) for each "DAC output value" (the y-axis).<br>
>> <br>
>> The difference between the "carry-bit NCO" approach (or whatever we <br>
>> want to call it) and the PWM output (the final diagram, half black, <br>
>> half white) is clear to see.<br>
>> <br>
>> The important thing is the way that the black and white pixels are far <br>
>> more mixed up- e.g. the noise is of much higher frequency, and <br>
>> therefore much easier to filter out.<br>
>> <br>
>> <br>
>> On 11 Dec 2023, at 08:59, cheater cheater via Synth-diy <br>
>> <<a href="mailto:synth-diy@synth-diy.org" target="_blank">synth-diy@synth-diy.org</a>> wrote:<br>
>> <br>
>> Thanks, sorry, I still don't understand this:<br>
>> <br>
>> > Each horizontal row of the chart is the waveform generated for the constant input on the y-axis.<br>
>> <br>
>> what do you mean by that?<br>
>> <br>
>> BTW, it's probably useful to send these emails to the list.<br>
>> <br>
>> <br>
>> On Mon, Dec 11, 2023 at 3:01 AM David Kantowitz <<a href="mailto:dkantowitz@gmail.com" target="_blank">dkantowitz@gmail.com</a>> <br>
>> wrote:<br>
>>> <br>
>>> "carry-bit NCO" is how I summarized the approach Tom uses: output a <br>
>>> pulse whenever the counter overflows.<br>
>>> <br>
>>> Each horizontal row of the chart is the waveform generated for the <br>
>>> constant input on the y-axis.<br>
>>> y=0 -> row of all zeros (white)<br>
>>> y=256 -> row of all ones (black)<br>
>>> y=128 -> row of alternating ones and zeros<br>
>>> <br>
>>> The interesting parts are really:<br>
>>> a) Overflow bit approach is _vastly_ better than PWM.<br>
>>> b) Most microcontrollers have a timer/counter peripheral where you <br>
>>> can implement this in hardware, having almost no s/w cost, and runnig <br>
>>> around the uC's clock rate (several MHz).<br>
>>> c) 1st order sigma delta converters are garbage: need a hefty <br>
>>> oversampling rate and noise rises like a 45 degree line through the <br>
>>> passband.<br>
>>> <br>
>>> <br>
>>> <br>
>>> On Sun, Dec 10, 2023 at 12:43 PM cheater cheater <br>
>>> <<a href="mailto:cheater00social@gmail.com" target="_blank">cheater00social@gmail.com</a>> wrote:<br>
>>>> <br>
>>>> <br>
>>>> <br>
>>>> On Sun, Dec 10, 2023 at 8:36 PM David Kantowitz <br>
>>>> <<a href="mailto:dkantowitz@gmail.com" target="_blank">dkantowitz@gmail.com</a>> wrote:<br>
>>>>> <br>
>>>>> The carry-bit NCO technique is also equivalent to a 1-bit first <br>
>>>>> order sigma delta DAC.<br>
>>>> <br>
>>>> <br>
>>>> Sorry,what carry-bit NCO technique? The word "carry" isn't mentioned <br>
>>>> before your email.<br>
>>>> <br>
>>>>> <br>
>>>>> Probably doesn't make it much easier to understand, but it does <br>
>>>>> make the design conclusions from sigma delta usable. Ex. noise <br>
>>>>> shaping curves, required Over Sampling Rates vs ENOB, <br>
>>>>> reconstruction filtering (see: <br>
>>>>> <a href="https://en.wikipedia.org/wiki/Delta-sigma_modulation" rel="noreferrer" target="_blank">https://en.wikipedia.org/wiki/Delta-sigma_modulation</a>).<br>
>>>>> <br>
>>>>> To help myself visualize this, I plotted the output bit patterns <br>
>>>>> for each input level. Both modulation algorithms (1-bit carry NCO <br>
>>>>> and SD-1) produced the same chart.<br>
>>>>> <br>
>>>>> DC level is y-axis, time is x-axis.<br>
>>>> <br>
>>>> <br>
>>>> I'm having trouble understanding these graphs. What's going on in <br>
>>>> them? "DC level is y-axis" doesn't seem to make sense in a plot that <br>
>>>> has multiple y values per one x value. What am I missing here?<br>
>>>> <br>
>>>>> <br>
>>>>> <image.png><br>
>>>>> Repeated 4 times to help imagine the oversampling:<br>
>>>>> <image.png><br>
>>>>> <br>
>>>>> For comparison basic PWM looks like:<br>
>>>>> <image.png><br>
>>>>> <br>
>>>>> By looking across a horizontal line, you can easily see the <br>
>>>>> carry-bit approach has a vast reduction in low frequency content <br>
>>>>> compared to PWM. That is, the digital signal 'noise' is being <br>
>>>>> pushed into higher frequencies. However, there's still plenty of <br>
>>>>> repeating pattern in the NCO/SD-1<br>
>>>>> <br>
>>>>> <br>
>>>>> On Fri, Dec 8, 2023 at 1:43 PM Tom Wiltshire <br>
>>>>> <<a href="mailto:tom@electricdruid.net" target="_blank">tom@electricdruid.net</a>> wrote:<br>
>>>>>> <br>
>>>>>> Honestly, it's not. It's just that damn simple. The version I <br>
>>>>>> actually wrote was all hardware module set-up specific to the <br>
>>>>>> device, and basically nothing else, so wouldn't tell you anything. <br>
>>>>>> Turning it all into software loses a lot of the benefit, so <br>
>>>>>> doesn't make much sense, except to explain it.<br>
>>>>>> <br>
>>>>>> Play with some NCOs a bit, and then get them to make a single <br>
>>>>>> pulse when they wrap. And then - Bingo! You're there!<br>
>>>>>> <br>
>>>>>> If you thought something was missing, what exactly? Ask a more <br>
>>>>>> specific question and perhaps I can help fill in a blank. I well <br>
>>>>>> remember how weird this stuff seemed when I first met it, so I <br>
>>>>>> think I understand the position you're in now.<br>
>>>>>> <br>
>>>>>> <br>
>>>>>> > On 8 Dec 2023, at 21:18, cheater cheater <<a href="mailto:cheater00social@gmail.com" target="_blank">cheater00social@gmail.com</a>> wrote:<br>
>>>>>> ><br>
>>>>>> > I don't get it. Most of the algorithm is missing.<br>
>>>>>> ><br>
>>>>>> > On Fri, Dec 8, 2023 at 10:07 PM Tom Wiltshire <<a href="mailto:tom@electricdruid.net" target="_blank">tom@electricdruid.net</a>> wrote:<br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >> On 8 Dec 2023, at 20:30, cheater cheater <<a href="mailto:cheater00social@gmail.com" target="_blank">cheater00social@gmail.com</a>> wrote:<br>
>>>>>> >><br>
>>>>>> >> On Fri, Dec 8, 2023 at 5:06 PM Tom Wiltshire <<a href="mailto:tom@electricdruid.net" target="_blank">tom@electricdruid.net</a>> wrote:<br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >> On 8 Dec 2023, at 14:41, Matthew Skala via Synth-diy <<a href="mailto:synth-diy@synth-diy.org" target="_blank">synth-diy@synth-diy.org</a>> wrote:<br>
>>>>>> >><br>
>>>>>> >> If PDM means PWM with bit-reversal before the comparison (such as Richie<br>
>>>>>> >> describes), then it does indeed lock you into a lower sampling rate, and<br>
>>>>>> >> that's one reason I skipped describing *that* technique. But PWM with<br>
>>>>>> >> bit-reversal seems not to be what you mean when you say PDM.<br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >> That's not what I meant when I said PDM, certainly.<br>
>>>>>> >><br>
>>>>>> >> The way I generated it is using an NCO. The NCO generates a single-shot output pulse everytime the phase accumulator wraps.<br>
>>>>>> >><br>
>>>>>> >> Now consider what happens with a simple 8-bit NCO. If our frequency increment is 2, for example, we get a single output pulse every 128 clocks, or 2 pulses per 256 clocks. Notice that they will be nicely spaced apart, not next to each other like PWM. The output frequency would be (clock frequency / 128) in this situation.<br>
>>>>>> >> If the increment is 8, we get a output pulse every 32 clocks, 8 pulses per 256 clocks, and again, they're nicely spaced out. The output frequency is now up to (clock /32) so there's been a big improvement, just by getting away from those extreme values a little bit.<br>
>>>>>> >> As the increment climbs, the accumulator wraps more and more often. At freq=128, every other clock is an output and we reach our maximum output frequency of (clock/2). As the increment goes above half, we start staying high for more than a single pulse, and the waveform effectively turns the other way up and we get a mirror image of the effect we've seen from 0-128.<br>
>>>>>> >><br>
>>>>>> >> HTH,<br>
>>>>>> >> Tom<br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >> I've read this a few times but I'm struggling to understand what's<br>
>>>>>> >> going on. Can someone type out an algorithm or something like that?<br>
>>>>>> >> Would appreciate it a lot. Thanks.<br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >> Ok, it'd look something like this:<br>
>>>>>> >><br>
>>>>>> >> phase: 16-bit variable (for example)<br>
>>>>>> >> freq: 16-bit variable (same as phase)<br>
>>>>>> >><br>
>>>>>> >> So we do:<br>
>>>>>> >><br>
>>>>>> >> // Increment phase accumulator<br>
>>>>>> >> phase = phase + freq<br>
>>>>>> >><br>
>>>>>> >> // Did phase wraparound?<br>
>>>>>> >> If (phase>65535) { // There are probably better ways to do this test, if it's even required.<br>
>>>>>> >> // Ok, phase wrapped<br>
>>>>>> >> phase = phase % 65536<br>
>>>>>> >> // output a pulse a single clock in length<br>
>>>>>> >> <this is implementation dependent!><br>
>>>>>> >> }<br>
>>>>>> >><br>
>>>>>> >> All you need to do is run this code at a fast clock rate and you're off. Of course, the better way is if you can hand some of this overhead to hardware, and some modern uPs include NCOs as a peripheral and can be set up for this "single shot pulse output" mode, which means that the while thing boils down to simply updating the "freq" frequency increment variable with your current output. It's dead simple.<br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> >> There's a page about NCOs in general on my website:<br>
>>>>>> >><br>
>>>>>> >> <a href="https://electricdruid.net/direct-digital-synthesis/" rel="noreferrer" target="_blank">https://electricdruid.net/direct-digital-synthesis/</a><br>
>>>>>> >><br>
>>>>>> >> HTH,<br>
>>>>>> >> Tom<br>
>>>>>> >><br>
>>>>>> >><br>
>>>>>> <br>
>>>>>> <br>
>>>>>> _______________________________________________<br>
>>>>>> Synth-diy mailing list<br>
>>>>>> <a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br>
>>>>>> <a href="http://synth-diy.org/mailman/listinfo/synth-diy" rel="noreferrer" target="_blank">http://synth-diy.org/mailman/listinfo/synth-diy</a><br>
>>>>>> Selling or trading? Use <a href="mailto:marketplace@synth-diy.org" target="_blank">marketplace@synth-diy.org</a><br>
>> <br>
>> ________________________________________________________<br>
>> This is the Synth-diy mailing list<br>
>> Submit email to: <a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br>
>> View archive at: <a href="https://synth-diy.org/pipermail/synth-diy/" rel="noreferrer" target="_blank">https://synth-diy.org/pipermail/synth-diy/</a><br>
>> Check your settings at: <br>
>> <a href="https://synth-diy.org/mailman/listinfo/synth-diy" rel="noreferrer" target="_blank">https://synth-diy.org/mailman/listinfo/synth-diy</a><br>
>> Selling or trading? Use <a href="mailto:marketplace@synth-diy.org" target="_blank">marketplace@synth-diy.org</a><br>
>> <br>
>> <br>
> <br>
> ________________________________________________________<br>
> This is the Synth-diy mailing list<br>
> Submit email to: <a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br>
> View archive at: <a href="https://synth-diy.org/pipermail/synth-diy/" rel="noreferrer" target="_blank">https://synth-diy.org/pipermail/synth-diy/</a><br>
> Check your settings at: <br>
> <a href="https://synth-diy.org/mailman/listinfo/synth-diy" rel="noreferrer" target="_blank">https://synth-diy.org/mailman/listinfo/synth-diy</a><br>
> Selling or trading? Use <a href="mailto:marketplace@synth-diy.org" target="_blank">marketplace@synth-diy.org</a><br>
________________________________________________________<br>
This is the Synth-diy mailing list<br>
Submit email to: <a href="mailto:Synth-diy@synth-diy.org" target="_blank">Synth-diy@synth-diy.org</a><br>
View archive at: <a href="https://synth-diy.org/pipermail/synth-diy/" rel="noreferrer" target="_blank">https://synth-diy.org/pipermail/synth-diy/</a><br>
Check your settings at: <a href="https://synth-diy.org/mailman/listinfo/synth-diy" rel="noreferrer" target="_blank">https://synth-diy.org/mailman/listinfo/synth-diy</a><br>
Selling or trading? Use <a href="mailto:marketplace@synth-diy.org" target="_blank">marketplace@synth-diy.org</a><br>
</blockquote></div>