10
\$\begingroup\$

I’m working on a low-power battery-based AVR-based project that integrates a few different devices including a neopixel strip and an Adafruit pixie. When the overall device is quiescent, I’d like it to draw less than 0.1mA to maximize the LiPo battery life.

I got this all working (measured 0.035mA) but I’m not sure I necessarily did it in the “right” way and I plan to build a product based on this so would like to do it right.

enter image description here (Not shown: a flyback diode for the relay)

The core concern I have is the “parasitic” powering of devices when VCC is disconnected via current flowing from data pins. For instance, the Pixie (which communicates via serial), has no power down mode and even when “off” drains about a milliamp. So I placed a small relay to disconnect its VCC, and discovered that the serial pin was actually still powering the pixie. Hints elsewhere suggested that many chips have a diode shunting their digital input pins to VCC as power protection. To solve this, I’ve had to suspend the serial library and actually digitalWrite( PIN, LOW ) during sleep.

Same thing with the WS2812b strip — disconnecting VCC still allows the device to be powered from the data pin. And in other designs when I’ve disconnected GND with an N-Channel MOSFET, I’ve seen the reverse - a back flow of current through the data line to ground! (This had to be solved with a diode per a post on PJRC.) The WS2812b’s actually take about a milliamp each even when unlit,

So the question: Is there a general, “clean” way to disconnect VCC and GND from parts of a project during system sleep when there are data pins in the mix. What is the best practice?

Some ideas:

  1. Force VCC to GND (not sure how? Hbridge?). (If I do that, what happens to the data pins that are high?)
  2. Place a tri-state buffer between all data pins and these devices, and during sleep put the tri-state buffer in a high impedance state, disconnect VCC or GND only with P or N mosfet
  3. Disconnect GND only with N mosfet, and place diodes on all data pins
  4. Is there some kind of power latch that disconnects both VCC and GND and puts them into a “high impedance” state (like a tri-state buffer for power?) That way current has no way to flow "out" from the data lines.

Can someone enlighten me to the cleanest, most repeatable way of handling this sort of “load disconnect” problem? (Needless to say, I have spent hours googling this problem with little luck, although I did find this tech note on load switching but it doesn't address back-feed and parasitic power)

\$\endgroup\$
  • \$\begingroup\$ Ya this is super annoying, I've actually seen cases where power reaching a GPIO pin can turn an AVR on (executing code) even with no power reaching the VCC pins... \$\endgroup\$ – vicatcu Dec 28 '16 at 17:17
  • 2
    \$\begingroup\$ Funny observation: i did some more google searches since posting this question and this question on SE came up as top rank. Google indexed this page in less than 10 minutes. \$\endgroup\$ – Jeremy Gilbert Dec 28 '16 at 17:24
  • \$\begingroup\$ Comment only: Proper isolation switches as others have suggested are best solution when a remote voltage cannot be eliminated. It MAY be that using Schottky diodes to input pins with Cathodes commoned and usually at Vcc and clamped to ground when isolation is wanted , will provide adequate elimination of highish impedance voltages. Obviously, Schottky clamping a power feed line with low impedance is liable to spoil your day. \$\endgroup\$ – Russell McMahon Jan 4 '17 at 13:45
  • \$\begingroup\$ Probably Hi-Z-ing all your connections some way (tri-state µC pins, tri-state buffers, analog switches, whatever), as Peter Smith and CL have suggested, is the best bet. Which one of the methods is better, I'm not sure. In any case: why do you use a relay for the switching, and not a P-MOSFET (or a lowside N-MOSFET for that matter, though lowside switching will probably be a bit harder here)? \$\endgroup\$ – FlashCactus Jan 4 '17 at 19:20
5
\$\begingroup\$

When I do this, I usually use CMOS analog switches on the affected data lines.

Something like the ADG812 has 4 channels of SPST switches that are easily suitable for quite fast logic, and provide a really high impedance between the switch nodes when in the off state.

ADG812 off leakage

The nice thing about this is that the technique works for both unidirectional and bidirectional data lines.

These parts also run on a bright smile:

ADG812 power requirements

The usual sequence for power down:

  1. Turn off data path switches

  2. Power down domain.

Power up is the opposite, of course.

[Update]

These are indeed known by other names, such as pass gates and transmission gates.

These are significantly different from a true tri-state buffer (as you can see in the diagrame in the link above), but for ordinary logic, the effect is better (this is inherently a bidirectional device) but with lower power.

\$\endgroup\$
  • \$\begingroup\$ Forgive the ignorance of the question, but is this markedly different than a tri-state buffer? (And thanks for the answer!) \$\endgroup\$ – Jeremy Gilbert Dec 28 '16 at 17:23
  • \$\begingroup\$ These are also known as "pass gates" \$\endgroup\$ – vicatcu Dec 28 '16 at 17:25
3
\$\begingroup\$

If the data signals are connected to your microcontroller, you can simply make them high impedance by configuring those pins as inputs. (If the other chip uses very little power, you can treat its Vcc like a data signal.)

Otherwise, you can use analog switches (74x66 logic chips) to disconnect them. For unidirectional signals, 74x125 would work, too.

\$\endgroup\$
  • \$\begingroup\$ You actually don't need to make them high-Z, you can just drive the micro's GPIO lines low. \$\endgroup\$ – DoxyLover Dec 28 '16 at 19:56
  • 1
    \$\begingroup\$ That would be more dangerous if the other chip could ever drive the signal high. \$\endgroup\$ – CL. Dec 29 '16 at 5:32
  • \$\begingroup\$ Just so I fully understand, is switching the pins to inputs always the same as putting them in a high impedance state? Is that generalized to most MCUs or just the AVRs? Is that state the same as you'd get from the 74x125 when OE is disabled? \$\endgroup\$ – Jeremy Gilbert Dec 29 '16 at 15:50
  • \$\begingroup\$ @JeremyGilbert All CMOS inputs have high impedance (they are MOSFET gates, which behave like very small capacitors). A disabled '125 output has no gate, but the difference is negligible. \$\endgroup\$ – CL. Dec 29 '16 at 16:11
  • 1
    \$\begingroup\$ @JeremyGilbert Inputs are generally high-Z in most applications; after all, it's hard to sense anything when you're driving the line. That said, with AVRs at least (and probably others too, but I don't know the specifics), you have to watch out for the internal pullups: if the pin is in input mode (configured via DDRx) and you write LOW to it (via PORTx), it's in regular Hi-Z mode. However if you write HIGH while in input mode, the internal pullup is enabled, and from outside the pin looks like a ~50K resistor to VCC instead of a floating line. \$\endgroup\$ – FlashCactus Jan 4 '17 at 19:07
1
\$\begingroup\$

I don't think there's a one size fits all strategy unfortunately. Switch power to subsystems as you've already done. In software, drive pins low for low power states, unless doing so would cause a high power steady state condition. In that case, drive the pin high. Never let inputs float. Sequence power as necessary to establish safe initial conditions.

\$\endgroup\$
1
\$\begingroup\$

A nasty problem that can cause microcontrollers to do very strange things.
The nice solution is to use pull-down serial I/O like \$ I^2C \$. This requires pull-up resistors on SCK, SDA lines. The pull-up resistors are tied to the switched Vcc line. Ensure that the switched Vcc line falls nicely to zero volts when it is switched off (don't let it float).

You don't have that option - you're forced to use asynchronous serial I/O. Some microcontrollers allow a similar approach as I2C to solve the problem. If you can program the serial output pin to be pull-down-only rather than the more common pull-up-for-1, pull-down-for-0, then you can add a pull-up resistor to switched-Vcc to establish a logic high.
This solution is not as noise-robust as your present approach, but it should solve the problem of back-powering your I/O modules from the AVR. It isn't really a "clean" solution, but it is far safer for the microcontroller(s) in your IO modules.

schematic

simulate this circuit – Schematic created using CircuitLab

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.