user10700: I would like to increase the PWM bit resolution of the Arduino Uno.
At this moment it is 8-bit which I consider too low.
Is this possible without losing the ability of interrupts and delays?
Koen
EDIT
This setup delivers a 16-bit resultion
void setupPWM16() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS11);                    /* prescaler: clock / 8 */
    ICR1 = 0xffff;                      /* TOP counter value (freeing OCR1A*/
}
/* Comments about the setup
Changing ICR1 will effect the amount of bits of resolution.
ICR1 = 0xffff; (65535) 16-bit resolution
ICR1 = 0x7FFF; (32767) 15-bit resolution
ICR1 = 0x3FFF; (16383) 14-bit resolution etc....

Changing the prescaler will effect the frequency of the PWM signal.
Frequency[Hz}=CPU/(ICR1+1) where in this case CPU=16 MHz
16-bit PWM will be>>> (16000000/8)/(65535+1)=30.5175Hz
*/

/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
    switch (pin) {
        case  9: OCR1A = val; break;
        case 10: OCR1B = val; break;
    }
}


user6959: With some calibration you could sum the outputs of two PWM channels with differing weighting resistors. At the extreme you could notionally use one output to provide 8 bits of resolution and scale the other to 1/256th the level and add them so the 2nd channel covers one bit of range and you (again notionally) get 16 bits of resolution. Without immense care and adjustment all you'd get would be a mess.
However by dividing the 2nd channel by 16 or 32 you could add several extra bits of PWM resolution. Just by adding 2 PWM channels analog filtered outputs you add an extra bit (as potential range is doubled for unchanged mV/bit).
Notionally (again) for every additional divide by 2  you get an extra bit of resolution, but this can only be carried out for maybe 4 or 5 or 6 extra bits, with increasing accuracy requirements of scaling resistors and more difficult calibration and proneness to errors. 
Brief example.
If one PWM is scaled down to give say 0 - 255 mV in 1 mV step, then summing two PWMs with equal amplitude would give a 0 - 510 mV range in 1 mV steps.
If one PWM is scaled down by a factor of 32 then instead of adding 255 mV to the initial PWMs range it would add only 8 mV to the top end (0.256.32 = 8 mV, but resolution would be in 0.03125 (1/32nd) mV steps.   
While this could perhaps be achieved purely with resistor summing and RC filtering, use of an op amp summer would greatly improve results.
Also PWM ripple could be filtered with a simple RC filter but use of one opamp as a buffer (or even just a single transistor as an emitter follower) would give you 3 or 5 poles of low pass filtering and much better chance of achieving extra PWM resolution. I have not inspected the "phase coherence" of the PWM outputs but expect that they move in relative lockstep so you don't get the smoothing advantage of adding two uncorrelated waveforms.
More comment can be made if needed. Ask if interested. 

user7508: The Arduino Uno is based on an ATmega382P microcontroller. This chip has
two 8-bit timers, driving two PWM channels each, and one 16-bit timer,
driving the last two channels.
You cannot increase the resolution of the 8-bit timers. You can,
however, put the 16-bit timer in 16-bit mode, instead of the 8-bit mode
used by the Arduino core library. This will give you two 16-bit PWM
channels, with a reduced frequency of 244 Hz (maximum). You will
probably have to configure the timer yourself, and will not benefit from
the easy to use analogWrite() function. For details, see the section
on Timer 1 in in the ATmega328P
datasheet.
Update: Here is an implementation of a 16-bit analogWrite(). It
only works on pins 9 and 10, as these are the only pins connected to the
16-bit timer.
/* Configure digital pins 9 and 10 as 16-bit PWM outputs. */
void setupPWM16() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS10);                    /* no prescaling */
    ICR1 = 0xffff;                      /* TOP counter value */
}

/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
    switch (pin) {
        case  9: OCR1A = val; break;
        case 10: OCR1B = val; break;
    }
}

You may notice that the top of the counter sequence is configured
explicitly. You can change this to a smaller value to make the PWM
faster, at the cost of decreased resolution.
And here is an example sketch illustrating its use:
void setup() {
    setupPWM16();
}

/* Test: send very slow sawtooth waves. */
void loop() {
    static uint16_t i;
    analogWrite16(9, i);
    analogWrite16(10, 0xffff - i);
    i++;
    delay(1);
}


10700: <p>I would like to increase the PWM bit resolution of the Arduino Uno.
At this moment it is 8-bit which I consider too low.
Is this possible without losing the ability of interrupts and delays?</p>

<p>Koen</p>

<p>EDIT
This setup delivers a 16-bit resultion</p>

<pre><code>void setupPWM16() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS11);                    /* prescaler: clock / 8 */
    ICR1 = 0xffff;                      /* TOP counter value (freeing OCR1A*/
}
/* Comments about the setup
Changing ICR1 will effect the amount of bits of resolution.
ICR1 = 0xffff; (65535) 16-bit resolution
ICR1 = 0x7FFF; (32767) 15-bit resolution
ICR1 = 0x3FFF; (16383) 14-bit resolution etc....

Changing the prescaler will effect the frequency of the PWM signal.
Frequency[Hz}=CPU/(ICR1+1) where in this case CPU=16 MHz
16-bit PWM will be&gt;&gt;&gt; (16000000/8)/(65535+1)=30.5175Hz
*/

/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
    switch (pin) {
        case  9: OCR1A = val; break;
        case 10: OCR1B = val; break;
    }
}
</code></pre>
 6959: <p>With some calibration you could sum the outputs of two PWM channels with differing weighting resistors. At the extreme you could notionally use one output to provide 8 bits of resolution and scale the other to 1/256th the level and add them so the 2nd channel covers one bit of range and you (again notionally) get 16 bits of resolution. Without immense care and adjustment all you'd get would be a mess.<br>
However by dividing the 2nd channel by 16 or 32 you could add several extra bits of PWM resolution. Just by adding 2 PWM channels analog filtered outputs you add an extra bit (as potential range is doubled for unchanged mV/bit).<br>
Notionally (again) for every additional divide by 2  you get an extra bit of resolution, but this can only be carried out for maybe 4 or 5 or 6 extra bits, with increasing accuracy requirements of scaling resistors and more difficult calibration and proneness to errors. </p>

<p>Brief example.<br>
If one PWM is scaled down to give say 0 - 255 mV in 1 mV step, then summing two PWMs with equal amplitude would give a 0 - 510 mV range in 1 mV steps.<br>
If one PWM is scaled down by a factor of 32 then instead of adding 255 mV to the initial PWMs range it would add only 8 mV to the top end (0.256.32 = 8 mV, but resolution would be in 0.03125 (1/32nd) mV steps.   </p>

<p>While this could perhaps be achieved purely with resistor summing and RC filtering, use of an op amp summer would greatly improve results.</p>

<p>Also PWM ripple could be filtered with a simple RC filter but use of one opamp as a buffer (or even just a single transistor as an emitter follower) would give you 3 or 5 poles of low pass filtering and much better chance of achieving extra PWM resolution. I have not inspected the "phase coherence" of the PWM outputs but expect that they move in relative lockstep so you don't get the smoothing advantage of adding two uncorrelated waveforms.</p>

<p>More comment can be made if needed. Ask if interested. </p>
 7508: <p>The Arduino Uno is based on an ATmega382P microcontroller. This chip has
two 8-bit timers, driving two PWM channels each, and one 16-bit timer,
driving the last two channels.</p>

<p>You cannot increase the resolution of the 8-bit timers. You can,
however, put the 16-bit timer in 16-bit mode, instead of the 8-bit mode
used by the Arduino core library. This will give you two 16-bit PWM
channels, with a reduced frequency of 244&nbsp;Hz (maximum). You will
probably have to configure the timer yourself, and will not benefit from
the easy to use <code>analogWrite()</code> function. For details, see the section
on Timer 1 in in the <a href="http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf">ATmega328P
datasheet</a>.</p>

<p><strong>Update</strong>: Here is an implementation of a 16-bit <code>analogWrite()</code>. It
only works on pins 9 and 10, as these are the only pins connected to the
16-bit timer.</p>



<pre class="lang-c++ prettyprint-override"><code>/* Configure digital pins 9 and 10 as 16-bit PWM outputs. */
void setupPWM16() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS10);                    /* no prescaling */
    ICR1 = 0xffff;                      /* TOP counter value */
}

/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
    switch (pin) {
        case  9: OCR1A = val; break;
        case 10: OCR1B = val; break;
    }
}
</code></pre>

<p>You may notice that the top of the counter sequence is configured
explicitly. You can change this to a smaller value to make the PWM
faster, at the cost of decreased resolution.</p>

<p>And here is an example sketch illustrating its use:</p>

<pre class="lang-c++ prettyprint-override"><code>void setup() {
    setupPWM16();
}

/* Test: send very slow sawtooth waves. */
void loop() {
    static uint16_t i;
    analogWrite16(9, i);
    analogWrite16(10, 0xffff - i);
    i++;
    delay(1);
}
</code></pre>
