3

So I need to output a varying voltage off an Arduino Mega in a range of 17 to 32 millivolts, which I've attempted to do by sending a PWM signal off the board into a low-pass filter which steps down the voltage.

This works, but the problem is that Arduino's analogWrite function accepts a value of 0 - 255 to represent the duty cycle of the PWM which isn't precise enough. A value of 1 yields around 20 millivolts and a value of 2 yields around 40 millivolts. Is there some way to have a duty cycle that is more precise than the 0 - 255 range like 0 - 1023 (I think even this isn't really precise enough)? Or is there a better way to get precise voltage output?

The mega is running on and outputting a max voltage of 5 volts, and the low pass filter contains an 11 kiloohm resistor and a 1 microfarad capacitor.

Cains
  • 131
  • 2
  • 1
    why not also drop the voltage when you filter it? then you'd have more of the 255 range to use rather than just 1 and 2. a simple voltage divider could do the trick. – Octopus May 07 '14 at 22:46

1 Answers1

4

analogWrite() does not support a higher range of duty cycle.

However the timers on the AVR chip do support higher precision/resolution, so you can bang the registers directly, especially if you don't need to use the rest of the Arduino libraries. I recommend using avr-gcc with avr-libc and avrdude for programming, and let go of Arduino IDE/libraries entirely.

You have up to 16 bit timers, where the duty cycle can be up to 0-65535. However, at 16 MHz, a 16 bit timer only ticks over 244 times a second, so the filter has to be very low-frequency and thus the lag in the output will be long (although the default PWM frequency for 8-bit timers is only 490 Hz or so, so only twice as good.)

The second thing you can do is output to a resistor divider. If you output to a 9.9k:100ohm divider, the voltage at the 1ohm resistor will vary from 0 to 50 mV even though the voltage across the top will vary from 0 to 5V. Note that the source impedance is kind-of high here, so you might want to re-buffer with an opamp if the load is low-impedance.

Jon Watte
  • 720
  • 5
  • 8