Need precise PWM DAC level with "floating" Vcc

Hello everyone.
I've just faced the problem that I can't solve easily, so want to ask for some good ideas here :slight_smile:

The Arduino is powered from "power" PCB via 20cm flat cable. The 5V regulator (7805) produces about 4.90 to 5.10V, depending on load, and due to the cable, "ground" level drop between power PCB and Arduino is about 10-20mV. The Vcc can be anywhere between 4.80 and 5.10.

The Arduino drives PWM DAC with a low-pass filter that produce very nice and clean voltage that is sent to "Power" PCB OpAmp and then used to control battery discharge current.

The problem I faced is that analog value I produce varies together with VCC, and I need it to be very precise.

I see some solutions here, but actually don't like any of them:

  1. The most reasonable seems to revise the unstable Vcc part.
    Use more solid ground/Vcc conductors than "IDC" flat cable, use some better than 7805 regulator.
    I don't actually like this idea because the way device is used actually prevents using anything than flat cable to connect boards together.

  2. Use separate power supply for "power" board and Arduino. Bad again as I don't want 2 PSUs. "ground" drift still not solved here, need better cables.

  3. Cascade PWM to drive MOSFET switch connected to some precise reference voltage (like 2.5V ref), and then low-pass filter.
    I'm not pretty sure if this will work, as reference voltages are usually low-current capable.

  4. Use some blend of op-amps, Vcc, precise reference voltage, and PWM analog output. Seems too bulky to me :frowning:

  5. Change PWM to serial DAC and power it from precise reference. Bad, but I don't have any single pin left to make it easy.

Can anyone suggest better ideas?

This is your best, possibly only viable solution:-

  1. The most reasonable seems to revise the unstable Vcc part.

That voltage regulator is not that bad, it must be being used with insufficient decoupling or an inadequate current source.

You could also replace it with a design that has a sense input, so the voltage is boosted to compensate for resistive drops along the wire.

Well, it seems to me that my biggest problem is powering Arduino, LCD, PS/2 keyboard, SD card and all the other digital circuitry via flat 10-pin cable. Maybe it's quite reasonable to change the flat cable wiring from 5V directly to input 12V and then step-down by Arduino's 7805 locally. I'll try and let you know if this works :slight_smile:

But any other ideas appreciated :slight_smile:

You answered your own question. i.e. precise reference voltage.

I2C DAC with building in precision reference voltage, MCP4725.

Breakout Board for MCP4725 I2C DAC

or SPI DAC with building in, LTC2640

LTC2640, $3.21, Digikey

Grumpy_Mike:
This is your best, possibly only viable solution:-

  1. The most reasonable seems to revise the unstable Vcc part.

Can't you feed the Arduino 3.3V line back into itself and use that as a reference? It should be quite stable.

PWM is a digital output. Aref is used for ADC purposes.

  1. Cascade PWM to drive MOSFET switch connected to some precise reference voltage (like 2.5V ref), and then low-pass filter.
    I'm not pretty sure if this will work, as reference voltages are usually low-current capable.

I would go with this option as you will be always coping with some voltage drops somewhere.
A LDO voltage regulator (ie MCP1700 3V3, 250mA), one mosfet (ie BS170), one drain resistor (ie 1k), and maybe 2 decoupling caps to the regulator and it will be more stable than current solution (you have to invert the PWM logic, maybe it could be done in sw). You feed the signal to the opamp, so no large power is required, imho.

kosha:
5) Change PWM to serial DAC and power it from precise reference. Bad, but I don't have any single pin left to make it easy.

You already have one dedicated pin available (the one you currently use for PWM). In most designs, it is easy to save a few pins by sharing some of them between multiple functions. So you can probably drive a SPI DAC using the dedicated pin to drive CS and using shared pins to drive SCLK and SDATA.

"So you can probably drive a SPI DAC using the dedicated pin to drive CS and using shared pins to drive SCLK and SDATA."

I favor that approach as well.
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en024016
datasheet:

Dual 12-bit DAC with internal Vref.

Thanks everyone for help, just wanted to share what's done in this topic.

First of all, I changed the PWM+RC filter DAC to hardware 12-bit SPI DAC (DAC8512). It has the internal vRef, so the output is clear from 0 to 4.095V. Pretty good device, a little bit expensive though.

Next, I revised all that "ground" stuff, eliminating 7805 from "Power" board, and feeding Arduino with DC12V. Also I reconfigured the IDC flat cable pinout, so to make each even wire to be grounded. So 5 signal wires, 5 ground wires interleaved. I also revised the "Analog" part of the circuit, as far as it was possible on a solder breadboard, separating it with decoupling capacitors with digital and high-powered part, and keeping ground return paths as short as possible for Digital, Analog and Power separate, connected in one single point.

Overall, that helped a lot with ground difference between boards, which is less than 7mV average now, and stable under different loads. Noise level decreased also, but it's still a little bit high, about 35mV peak-to-peak. That's coming from lots of ground loops and different "ground" connection points, and I can't make different design with a breadboard. I hope when moving to real PCB, I'd be able do decrease it even further.

Again thanks a lot to everyone participated :slight_smile:

Why not measure the output voltage and adjust for any error.

you mean voltage-dividing Vcc and forwarding it to some ADC channel?