I'd like to interface the STAT line of an MCP73831 lithium ion charge manager IC to a microcontroller to read the current charging status of it.

The datasheet explains, in the section 5.2.1, that the STAT line is tristate output and have the following status:

  • High
  • Low
  • High-Impedance

and a table is provided that explains how each level represents each charging states of the battery.

How can I connect this pin to a microcontroller I/O and read these three distinct states?

Reading High and Low is quite straightforward, but detecting a input is high impedance I've not done before.


You could tie it to ground and Vcc with two 10k resistors, and use an A/D input to read the level.

If you don't have an A/D to spare connect it to another pin of your uC with a 10k resistor. If the pin is either high or low it will of course read as high resp. low (assuming it can drive a 10k load). If it is high impedance it will read equal to what you output on the other pin.

  • \$\begingroup\$ +I like the 2nd idea. Read with output high and output low, four possibilities, of which only three are sensible. \$\endgroup\$ – Spehro Pefhany Jul 14 '14 at 23:09
  • \$\begingroup\$ Nice idea using the other pin. In this case though, the input can/will exceed the processors Vcc. Added a post instead of an extended comment. \$\endgroup\$ – carveone Jul 25 '14 at 15:44

Many microcontrollers allow you to select between either weak pullup and weak pulldown resistor on a GPIO input - in the order of about 50k-100k Ohm. If the input is high-z, a read with weak pulldown enabled will read low and a following read with weak pullup will be a high.

Remember to wait a few µs between the resistor toggle and the GPIO read to allow the voltage on the pin to settle.

Note that older AVR and 8051's may only have weak pullup but no weak pulldown resistors.

  • 2
    \$\begingroup\$ +1 ... For MPUs that do not have weak pullup & weak pulldown capability, you could add a single external resistor to another GPIO pin and use it to drive the resistor high or low. \$\endgroup\$ – Tut Jul 14 '14 at 20:17

If you read the document - section 3.3 you see that it is intended to be used with a pull up resistor.

In fact with any open-drain or tri-state signal you're not meant to be reading it when it is in tri-state mode, it is designed that way so that the signal can be shared across multiple devices. Where it gets confusing is that if you are reading the signal and it is in tri-state mode (and you don't know it) you can get spurious readings. the best way is to then apply a weak pull up so that if the signal is in a ambiguous state, then the the signal is read appropriately. Since this signal is meant to be driving a LED to indicate a charge status (i.e. low is charging) then with a pull-up and it reads high, means that it is not charging.

enter image description here

  • 1
    \$\begingroup\$ The table in section 5.2.1 indicates that (for the MCP73831) that a "HIGH Z" output indicates "Shutdown" or "No Battery Present", while a "H" (high) output indicates "Charge Complete - Standby". A pull-up resistor alone will not allow the MCU to tell the difference. \$\endgroup\$ – Tut Jul 14 '14 at 20:47
  • \$\begingroup\$ With a pull up then the modes of "shutdown", "no battery present" and "Charge-complete - standby" all map to the same reading of High. This all maps to the action of "don't do anything" looks like the datasheet is consistent. \$\endgroup\$ – placeholder Jul 14 '14 at 20:56
  • \$\begingroup\$ @placeholder that mapping may not be desired - charge compete and no battery present are extremely different cases. \$\endgroup\$ – Chris Stratton Aug 14 '16 at 15:39

If I may add a warning to this post. The MCP73831 is a battery charger chip and thus its Vdd is higher than its Vbat.

enter image description here

Assuming your microcontroller is connected to Vbat and Vdd is supplied from USB, then Vdd could be at least 1.5V higher than Vucontroller.

The catch is that, on the 73831 which has totem pole outputs, STAT is referred to Vdd. So don't connect STAT directly to an uC input. Use something like a 10k resistor in between. For a PIC micro, the input diode clamps will clamp to its Vcc (check the datasheet for max current before latchup)

As an addendum - last year I came across a hack to read hi/low/z inputs that was for a PIC but might (or might not) work for you. Something like (pseudo code):

STAT ----[10k]------ PIC
PIN starts as input

set PIN low
set PIN to output
set PIN to input
set PIN high
value = read PIN  (assuming 1 for high, 0 for low)
value = value << 1
set PIN to output
set PIN to input
value |= read PIN

Then you get 0 for low, 1 for Hi-Z and 3 for high. YMMV.

  • \$\begingroup\$ I have the same issue. What I don't understand is why would it work with the 10k and not destroy the AVR? It's limiting current, but the voltage is still 5V, which is beyond the specced VCC + 0.5V max I/O voltage. \$\endgroup\$ – da_petcu21 Nov 4 '16 at 12:02
  • \$\begingroup\$ The voltage on one side of the resistor is beyond spec but, at the micro's pin, the input protection diodes are clamping the maximum voltage to VCC + a diode drop, which is within spec. If the current is too high though you will still destroy the diodes. So if you had 200V -> 10Mohm resistor -> Pin, the current would be 20uA. I wouldn't do that now without external Schottky diodes as well but you get the idea. \$\endgroup\$ – carveone Nov 13 '16 at 18:45

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.