fastest possible 16 bit PWM

Hello, I need a high precision DAC output from my UNO, I was thinking about using the 16 bit PWM with an RC filter. But the frequency of the PWM is very low and so the ripple at the filter output is huge. Is there a way to increase the PWM frequency while keeping the 16 bit resolution? Here is my code:

void setup() {
     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;     

}

void loop() {
  static uint16_t i;
    analogWrite16(9, i);
    analogWrite16(10, 0xffff - i);
    i++;
    delay(1);

}

void analogWrite16(uint8_t pin, uint16_t val)
{
    switch (pin) {
        case  9: OCR1A = val; break;
        case 10: OCR1B = val; break;
    }
}

Think about this. You have a 16MHz processor and you feed this clock into a 16 bit counter. So that will give you a frequency for one cycle of:- 16000000 / 65535 = 244Hz That is the best you can do.

so the ripple at the filter output is huge

I think you need a better filter than just a single order RC filter if you want to cut down the ripple and still have a fast response to an output change.

Oh, I did not even thing about that... How about I used the approach from this video - https://www.youtube.com/watch?v=yjgZ3dQ-PFw (basically adding two 8 bit PWMs to get 16bit) Could I get effectively 2 16bit PWM otputs from 4 arduino pins? And could the frequency be much higher? (15.64 khz?)

If what you need is a DAC, why don't you use one, without dealing with PWM frequency and filter? An MCP4922 cost few bucks on offer you 12 bit resolution and SPI interface, so very easy to use.

Ciao, Ale.

It might be time to buy a high precision DAC. If you need 16 bit precision then the trace layout on the Arduino board is going to steal several bits of resolution before the signal even leaves the board.

(basically adding two 8 bit PWMs to get 16bit)

There is there problem, it is getting the lower 8 bits to be exactly 1/256th of the upper 8 bits. That guy in the video is fooling himself that he has a true 16 bit output. With the tolerance on the PWM voltage from the pin being a significant factor in the conversion this technique is not possible.

Could I get effectively 2 16bit PWM otputs from 4 arduino pins? And could the frequency be much higher? (15.64 khz?)

So that would be a no then.

What exactly are your requirements? How fast does this signal need to change? What noise can you stand? Even with a true 16 bit chip you can't just slap it on a bread board and get 16 bits resolution, it needs a carefully laid out PCB.

Ok, thinking about it, 16 bits is probably too much. I am building a power supply, and I need the DAC to select a desired output voltage. I am actually not using arduino itself, just the atmega328 microcontroller. How about 12bits at 3.9kHz? That would gave me a reasonable resolution and the filter will be quite simple.

That's not a power supply - that's a waveform generator. Why would the power supply voltage need to swing through the full range 3,900 times per second?

These 12 bit DACs are easy to use. http://www.digikey.com/product-search/en/integrated-circuits-ics/data-acquisition-digital-to-analog-converters-dac/2556292?k=mcp&k=&pkeyword=mcp&pv153=4&FV=fff40027%2Cfff80184&mnonly=0&newproducts=0&ColumnSort=0&page=1&stock=1&quantity=0&ptm=0&fid=0&pageSize=25 If need fast updates, get an SPI part, that's me preference. On-chip and off-chip reference voltage options, SMD and thruhole also.

How about 12bits at 3.9kHz? That would gave me a reasonable resolution and the filter will be quite simple.

If you don’t want to use the 12 bit DAC, then try the code in your original post with ICR1= 0xfff replacing ICR1= 0xffff in the timer setup and an analogWrite12() function. Use your simple filter, and let us know the results.

Thanks! this works perfectly! Paired it with a simple second order fileter (2x 100nF + 2x 10K res) and the ripple is very small. I will probably swap the caps for 330nF ones, to smooth it out even more. Thanks again for your help.