Discussion:
[PIC] High Frequency 16 bit PWM Dimming
Jim Ruxton
2017-09-06 21:41:57 UTC
Permalink
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.

Thanks,

Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Mark Rages
2017-09-06 22:24:44 UTC
Permalink
Have a look at how https://github.com/scanlime/fadecandy uses delta-sigma
modulation to get 16-bit resolution from the 8-bit WS2811 LED controllers.
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
Regards,
Mark
***@gmail
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Jim Ruxton
2017-09-07 05:17:38 UTC
Permalink
Thanks Mark,

I have used the Fadecandy which is quite cool and works well. I'll take
a look at the code. Thanks for the suggestion.

Jim
Post by Mark Rages
Have a look at how https://github.com/scanlime/fadecandy uses delta-sigma
modulation to get 16-bit resolution from the 8-bit WS2811 LED controllers.
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Kerry
2017-09-06 23:41:01 UTC
Permalink
I think you would need to dither it.

Set up an interrupt for each PWM cycle.  Separate the 16 bit word into
10bit and 6bit.

In interrupt:
Acc += 6bit;
if(Acc>0x3f)    // If bit 7 set
{
    Acc &= 0x3f;    // Clear 7th bit
    set_PWM(10bit+1);    // Extra long cycle
}
else
    set_PWM(10bit);    // "Normal" cycle


It will average out to your 16 bit value.

Kerry
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listi
Jim Ruxton
2017-09-07 05:26:17 UTC
Permalink
Thanks Kerry,

This looks interesting , I don't quite follow it however. How would
this work if my 16 bit value was 0x0001 for example. In that case there
would be no dithering would there as the 6 bit value would be 0 so I
would be left with 10 bit PWM or am I missing something here. Thanks for
any clarification.

Jim
Post by Kerry
I think you would need to dither it.
Set up an interrupt for each PWM cycle. Separate the 16 bit word into
10bit and 6bit.
Acc += 6bit;
if(Acc>0x3f) // If bit 7 set
{
Acc &= 0x3f; // Clear 7th bit
set_PWM(10bit+1); // Extra long cycle
}
else
set_PWM(10bit); // "Normal" cycle
It will average out to your 16 bit value.
Kerry
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Kerry
2017-09-07 16:26:25 UTC
Permalink
I guess I should have been more clear.

The leftmost 10 bits becomes the variable 10bit and the rightmost 6 bits
becomes the variable 6bit, as in:

16bit = 0x1234 = 0b0001 0010 0011 0100
10bit = 0b0001 0010 00 = 0x0048
6bit = 0b11 0100 = 0x34

If your 16bit value was 0x0001, then the 10bit would be 0 and the 6bit
would be 1.
The PWM output would be 0 for 63 cycles, the 1/1024 for 1 cycle.
If your 16bit value was 0x3000, then the 10bit would be 0x300 and the
6bit would be 0.
The PWM output would be 768/1024 for all cycles, so there would be no
dithering.  But 768/1024 is exactly equal to 12288/65536, so no
dithering is needed.

Does that help?

Kerry
Post by Jim Ruxton
Thanks Kerry,
This looks interesting , I don't quite follow it however. How would
this work if my 16 bit value was 0x0001 for example. In that case there
would be no dithering would there as the 6 bit value would be 0 so I
would be left with 10 bit PWM or am I missing something here. Thanks for
any clarification.
Jim
Post by Kerry
I think you would need to dither it.
Set up an interrupt for each PWM cycle. Separate the 16 bit word into
10bit and 6bit.
Acc += 6bit;
if(Acc>0x3f) // If bit 7 set
{
Acc &= 0x3f; // Clear 7th bit
set_PWM(10bit+1); // Extra long cycle
}
else
set_PWM(10bit); // "Normal" cycle
It will average out to your 16 bit value.
Kerry
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit
Kerry
2017-09-07 16:56:31 UTC
Permalink
OK, I got some numbers wrong.

If your 16bit value was 0x3000, then the 10bit would be 0x0c0 and the
6bit would be 0.
The PWM output would be 192/1024 for all cycles, so there would be no
dithering.  But 192/1024 is exactly equal to 12288/65536, so no
dithering is needed.

That's what I get for doing hex arithmetic in my head!

Kerry
Post by Kerry
I guess I should have been more clear.
The leftmost 10 bits becomes the variable 10bit and the rightmost 6 bits
16bit = 0x1234 = 0b0001 0010 0011 0100
10bit = 0b0001 0010 00 = 0x0048
6bit = 0b11 0100 = 0x34
If your 16bit value was 0x0001, then the 10bit would be 0 and the 6bit
would be 1.
The PWM output would be 0 for 63 cycles, the 1/1024 for 1 cycle.
If your 16bit value was 0x3000, then the 10bit would be 0x300 and the
6bit would be 0.
The PWM output would be 768/1024 for all cycles, so there would be no
dithering.  But 768/1024 is exactly equal to 12288/65536, so no
dithering is needed.
Does that help?
Kerry
Post by Jim Ruxton
Thanks Kerry,
This looks interesting , I don't quite follow it however. How would
this work if my 16 bit value was 0x0001 for example. In that case there
would be no dithering would there as the 6 bit value would be 0 so I
would be left with 10 bit PWM or am I missing something here. Thanks for
any clarification.
Jim
Post by Kerry
I think you would need to dither it.
Set up an interrupt for each PWM cycle. Separate the 16 bit word into
10bit and 6bit.
Acc += 6bit;
if(Acc>0x3f) // If bit 7 set
{
Acc &= 0x3f; // Clear 7th bit
set_PWM(10bit+1); // Extra long cycle
}
else
set_PWM(10bit); // "Normal" cycle
It will average out to your 16 bit value.
Kerry
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailm
Jim Ruxton
2017-09-07 18:38:37 UTC
Permalink
Thanks a lot Kerry for the clarification. I guess this would mean
however that a 1 dimming level would effectively be a PWM signal at a
frequency of 24kHz/64 = 375 Hz (assuming the 10 bit PWM is 24 kHz) . The
reason I am so concerned about the low level ie. 1 is that my
application is LED dimming at a high frequency. Currently my LED at a
PWM level of 1/1024 snaps on at too high a level. I would like it to
come on lower at the first level of dimming. 375 Hz is too low a
frequency for my application.

Jim
Post by Kerry
OK, I got some numbers wrong.
If your 16bit value was 0x3000, then the 10bit would be 0x0c0 and the
6bit would be 0.
The PWM output would be 192/1024 for all cycles, so there would be no
dithering. But 192/1024 is exactly equal to 12288/65536, so no
dithering is needed.
That's what I get for doing hex arithmetic in my head!
Kerry
Post by Kerry
I guess I should have been more clear.
The leftmost 10 bits becomes the variable 10bit and the rightmost 6 bits
16bit = 0x1234 = 0b0001 0010 0011 0100
10bit = 0b0001 0010 00 = 0x0048
6bit = 0b11 0100 = 0x34
If your 16bit value was 0x0001, then the 10bit would be 0 and the 6bit
would be 1.
The PWM output would be 0 for 63 cycles, the 1/1024 for 1 cycle.
If your 16bit value was 0x3000, then the 10bit would be 0x300 and the
6bit would be 0.
The PWM output would be 768/1024 for all cycles, so there would be no
dithering. But 768/1024 is exactly equal to 12288/65536, so no
dithering is needed.
Does that help?
Kerry
Post by Jim Ruxton
Thanks Kerry,
This looks interesting , I don't quite follow it however. How would
this work if my 16 bit value was 0x0001 for example. In that case there
would be no dithering would there as the 6 bit value would be 0 so I
would be left with 10 bit PWM or am I missing something here. Thanks for
any clarification.
Jim
Post by Kerry
I think you would need to dither it.
Set up an interrupt for each PWM cycle. Separate the 16 bit word into
10bit and 6bit.
Acc += 6bit;
if(Acc>0x3f) // If bit 7 set
{
Acc &= 0x3f; // Clear 7th bit
set_PWM(10bit+1); // Extra long cycle
}
else
set_PWM(10bit); // "Normal" cycle
It will average out to your 16 bit value.
Kerry
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinfo/piclist
Kerry
2017-09-07 21:41:49 UTC
Permalink
You might want to rethink things a bit.  Obviously I don't know the
details of what you are doing, but what you seem to be describing is
generating a pulse 636 picoseconds wide!  Rise and fall times would
probably need to be about 64 picoseconds max.  Compare this to the Jim
Williams pulse generator.

A more practical approach might be 10 bit PWM and 6 bit A/D to set the
LED current. (Assuming you really are just dimming, not looking for
extremely narrow pulses.)

Kerry
Post by Jim Ruxton
Thanks a lot Kerry for the clarification. I guess this would mean
however that a 1 dimming level would effectively be a PWM signal at a
frequency of 24kHz/64 = 375 Hz (assuming the 10 bit PWM is 24 kHz) . The
reason I am so concerned about the low level ie. 1 is that my
application is LED dimming at a high frequency. Currently my LED at a
PWM level of 1/1024 snaps on at too high a level. I would like it to
come on lower at the first level of dimming. 375 Hz is too low a
frequency for my application.
Jim
Post by Kerry
OK, I got some numbers wrong.
If your 16bit value was 0x3000, then the 10bit would be 0x0c0 and the
6bit would be 0.
The PWM output would be 192/1024 for all cycles, so there would be no
dithering. But 192/1024 is exactly equal to 12288/65536, so no
dithering is needed.
That's what I get for doing hex arithmetic in my head!
Kerry
Post by Kerry
I guess I should have been more clear.
The leftmost 10 bits becomes the variable 10bit and the rightmost 6 bits
16bit = 0x1234 = 0b0001 0010 0011 0100
10bit = 0b0001 0010 00 = 0x0048
6bit = 0b11 0100 = 0x34
If your 16bit value was 0x0001, then the 10bit would be 0 and the 6bit
would be 1.
The PWM output would be 0 for 63 cycles, the 1/1024 for 1 cycle.
If your 16bit value was 0x3000, then the 10bit would be 0x300 and the
6bit would be 0.
The PWM output would be 768/1024 for all cycles, so there would be no
dithering. But 768/1024 is exactly equal to 12288/65536, so no
dithering is needed.
Does that help?
Kerry
Post by Jim Ruxton
Thanks Kerry,
This looks interesting , I don't quite follow it however. How would
this work if my 16 bit value was 0x0001 for example. In that case there
would be no dithering would there as the 6 bit value would be 0 so I
would be left with 10 bit PWM or am I missing something here. Thanks for
any clarification.
Jim
Post by Kerry
I think you would need to dither it.
Set up an interrupt for each PWM cycle. Separate the 16 bit word into
10bit and 6bit.
Acc += 6bit;
if(Acc>0x3f) // If bit 7 set
{
Acc &= 0x3f; // Clear 7th bit
set_PWM(10bit+1); // Extra long cycle
}
else
set_PWM(10bit); // "Normal" cycle
It will average out to your 16 bit value.
Kerry
Post by Jim Ruxton
I got a reality check today when I thought I would try setting up a PIC
for 24 KHz 16 bit PWM . I had been using 10 bit and wanted to up the
resolution. After doing some calculations using something like the PIC
16F1779 with integrated 16 bit PWM , I would require a 1.6 GHz clock to
achieve 16 bits at 24 kHz . Just curious what other folks would use for
such an application. Highest frequency one could get using 16 bit PWM
with a 32 MHz clock is about 488 Hz.
Thanks,
Jim
--
http://www.piclist.com/techref/piclist PIC/SX FAQ & list archive
View/change your membership options at
http://mailman.mit.edu/mailman/listinf
Loading...