Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support USB power and charging status on GPIO pins #19

Open
synthead opened this issue May 13, 2022 · 0 comments
Open

Support USB power and charging status on GPIO pins #19

synthead opened this issue May 13, 2022 · 0 comments

Comments

@synthead
Copy link

synthead commented May 13, 2022

When Watchy hardware is plugged in, the OS has no introspection on if the device is currently being charged, or if it's connected to USB power.

In the KiCad project, TP4054 (the Li-Po charging controller) already has an LED indicator when the device is being charged:

This illuminates when charging, and stops illuminating when the battery is fully charged. When charging, TP4054 STAT (pin 1) appears to be low-impedance and pulls its input to Vss. This allows current to flow through the LED and sink into the controller, which makes it illuminate. When it isn't charging, this input appears to be high-impedance, which means that current doesn't sink to any meaningful amount, and the LED will not be illuminated.

This behavior can easily be adapted to be used with a GPIO by pulling STAT high and connecting it to an unused GPIO input on the ESP32. When the LED illuminates, STAT will pull the signal low, and this can be used to reliably tell the Watchy that we're charging.

For the "charger connected" indicator, we can simply connect VBUS to an unused GPIO pin. This pin can be pulled low. The LED is a diode at heart, so if is surrounded by pull-up and pull-down resistors in an opposite polarity, there shouldn't be any meaningful current passing though it, and it should not illuminate.

Here is the ESP32-PICO-D4 IC with its unused GPIO pins highlighted:

We'll also want to ensure that these two inputs have some kind of circuit protection, and that the signals are converted to 3.3V. There are many good answers to solving this. Even a little current-limiting resistor paired with a 3.1V zener diode should do the trick nicely.

With Watchy having some insight to its own charging hardware, in addition to a better battery and charging icons, we can also do interesting things like battery self-calibration to accommodate for battery wear. As batteries age, the amount of energy they store lessens, and that results in less voltage being stored in the cells. By reading raw voltage over an ADC without calibration (the current state of things), a worn cell may state: "I am fully charged at 60%." While accurate, this is not typically how charged worn cells are presented, which incurs UX issues. Users are used to seeing "I plugged it in until it went to 100%."

When a battery becomes fully charged (as indicated by TP4054) and USB power is still present, we know that the battery became fully charged. If the above is implemented, the charging pin will go high, and we can immediately call whatever voltage is present the "100%" mark. This can be put into EEPROM so that this calibration can survive reboots. Additionally, we can do the same with a dying battery: when calibrating, write the ADC value to EEPROM until the device shuts off on its own. When given USB power again, the OS will correctly know what "0%" is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant