Hello everyone.
I've just faced the problem that I can't solve easily, so want to ask for some good ideas here
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:
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.
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.
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.
Use some blend of op-amps, Vcc, precise reference voltage, and PWM analog output. Seems too bulky to me
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.
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
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.
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.