43#ifdef ARDUINO_ARCH_ESP32
50#define WIFI_SSID "YourSSID"
53#define WIFI_PASSWORD "YourPassword"
81 default:
return "Unknown";
93 default:
return "Unknown";
100 Serial.println(
"╔══════════════════════════════════════════╗");
101 Serial.println(
"║ AXP517 Charger Web Monitor Test ║");
102 Serial.println(
"╚══════════════════════════════════════════╝");
110 Serial.
begin(115200);
116 Serial.println(
"AXP517 begin() failed. Check wiring.");
122 Serial.println(
"AXP517 initialized successfully");
125 bmu.enableModule(PmicAXP517::Module::CHARGE,
true);
132 if (!rlst) Serial.println(
"setPreChargeCurrent failed");
135 if (!rlst) Serial.println(
"setFastChargeCurrent failed");
138 if (!rlst) Serial.println(
"setTerminationCurrent failed");
141 if (!rlst) Serial.println(
"setChargeVoltage failed");
143 Serial.print(
"Pre Charge Current: ");
145 Serial.print(
"Fast Charge Current: ");
147 Serial.print(
"Termination Current: ");
149 Serial.print(
"Charge Voltage: ");
160 Serial.print(
"Input Current Limit: ");
162 Serial.print(
"Input Voltage Limit: ");
164 Serial.print(
"Minimum System Voltage: ");
177 const char *ssid = WIFI_SSID;
178 const char *password = WIFI_PASSWORD;
179 WiFi.begin(ssid, password);
180 while (WiFi.status() != WL_CONNECTED) {
185 Serial.print(
"WiFi connected, IP: ");
186 Serial.println(WiFi.localIP());
188 server.on(
"/boost/on", []() {
189 bool ret =
bmu.
power().enableBoost(
true);
190 server.send(200,
"text/plain", ret ?
"OK" :
"FAILED");
193 server.on(
"/boost/off", []() {
195 server.send(200,
"text/plain", ret ?
"OK" :
"FAILED");
198 server.on(
"/ship/on", []() {
201 server.send(400,
"text/plain",
"ERROR: Remove USB power first to enable ship mode");
205 server.send(200,
"text/plain", ret ?
"OK" :
"FAILED");
208 server.on(
"/led/mode", []() {
209 if (!server.hasArg(
"mode")) {
210 server.send(400,
"text/plain",
"Missing mode argument");
213 String mode = server.arg(
"mode");
215 if (mode ==
"auto") {
217 }
else if (mode ==
"manual") {
219 }
else if (mode ==
"breath") {
221 }
else if (mode ==
"disable") {
224 server.send(400,
"text/plain",
"Invalid mode");
227 server.send(200,
"text/plain", ret ?
"OK" :
"FAILED");
230 server.on(
"/led/state", []() {
231 if (!server.hasArg(
"state")) {
232 server.send(400,
"text/plain",
"Missing state argument");
235 String state = server.arg(
"state");
237 if (state ==
"off") {
239 }
else if (state ==
"low") {
241 }
else if (state ==
"high") {
243 }
else if (state ==
"blink1") {
245 }
else if (state ==
"blink4") {
248 server.send(400,
"text/plain",
"Invalid state");
251 server.send(200,
"text/plain", ret ?
"OK" :
"FAILED");
254 server.on(
"/", []() {
256 time_t now = millis() / 1000;
257 int hrs = (now / 3600) % 24;
258 int mins = (now / 60) % 60;
260 sprintf(timeStr,
"%02d:%02d:%02d", hrs, mins, secs);
266 String html =
"<html><head><meta charset='utf-8'><title>AXP517 Charger Monitor</title>";
268 html +=
"function toggleBoost(enable) {";
269 html +=
" var xhr = new XMLHttpRequest();";
270 html +=
" xhr.open('GET', enable ? '/boost/on' : '/boost/off', true);";
271 html +=
" xhr.onload = function() { if(xhr.status==200) location.reload(); else alert(xhr.responseText); };";
272 html +=
" xhr.send();";
274 html +=
"function enableShipMode() {";
275 html +=
" if(!confirm('WARNING: Ship mode will disconnect the battery and power off the device!\\n\\nYou must connect USB power or press PWR button to keep the device running after enabling ship mode.\\n\\nAre you sure you want to continue?')) return;";
276 html +=
" var xhr = new XMLHttpRequest();";
277 html +=
" xhr.open('GET', '/ship/on', true);";
278 html +=
" xhr.onload = function() { if(xhr.status==200) { alert('Ship mode enabled! Device will power off.'); location.reload(); } else { alert(xhr.responseText); } };";
279 html +=
" xhr.send();";
281 html +=
"function setLedMode(mode) {";
282 html +=
" var xhr = new XMLHttpRequest();";
283 html +=
" xhr.open('GET', '/led/mode?mode=' + mode, true);";
284 html +=
" xhr.onload = function() { if(xhr.status==200) location.reload(); else alert(xhr.responseText); };";
285 html +=
" xhr.send();";
287 html +=
"function setLedState(state) {";
288 html +=
" var xhr = new XMLHttpRequest();";
289 html +=
" xhr.open('GET', '/led/state?state=' + state, true);";
290 html +=
" xhr.onload = function() { if(xhr.status==200) location.reload(); else alert(xhr.responseText); };";
291 html +=
" xhr.send();";
294 html +=
"</head><body>";
295 html +=
"<h1>AXP517 Charger Status</h1>";
296 html +=
"<p><strong>Last Update: " + String(timeStr) +
"</strong></p>";
298 html +=
"<h2>Boost Control</h2>";
299 html +=
"<p>Boost Status: <strong>" + String(boostEnabled ?
"ON" :
"OFF") +
"</strong></p>";
301 html +=
"<button onclick='toggleBoost(false)' style='background:#f44336;color:white;padding:10px 20px;border:none;cursor:pointer;'>Turn OFF Boost</button>";
303 html +=
"<button onclick='toggleBoost(true)' style='background:#4CAF50;color:white;padding:10px 20px;border:none;cursor:pointer;'>Turn ON Boost</button>";
306 html +=
"<h2>Ship Mode (Battery Off)</h2>";
307 html +=
"<p>Ship mode is <strong>" + String(shipEnabled ?
"Enabled" :
"Disabled") +
"</strong></p>";
308 html +=
"<p>Ship mode disconnects the battery and powers off the device.</p>";
309 html +=
"<p>To exit ship mode, connect USB power.</p>";
310 html +=
"<button onclick='enableShipMode()' style='background:#FF9800;color:white;padding:10px 20px;border:none;cursor:pointer;'>Enable Ship Mode</button>";
312 html +=
"<h2>LED Control</h2>";
313 html +=
"<p>LED Mode: <strong>" + String(ledModeStr(
bmu.
led().
getMode())) +
"</strong></p>";
315 html +=
"<button onclick='setLedMode(\"auto\")' style='background:#2196F3;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Auto</button>";
316 html +=
"<button onclick='setLedMode(\"manual\")' style='background:#2196F3;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Manual</button>";
317 html +=
"<button onclick='setLedMode(\"breath\")' style='background:#2196F3;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Breath</button>";
318 html +=
"<button onclick='setLedMode(\"disable\")' style='background:#f44336;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Disable</button>";
320 html +=
"<p>Manual State: <strong>" + String(ledStateStr(
bmu.
led().
getManualState())) +
"</strong></p>";
322 html +=
"<button onclick='setLedState(\"off\")' style='background:#607D8B;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Off (Hi-Z)</button>";
323 html +=
"<button onclick='setLedState(\"low\")' style='background:#607D8B;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Low</button>";
324 html +=
"<button onclick='setLedState(\"high\")' style='background:#4CAF50;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>High</button>";
325 html +=
"<button onclick='setLedState(\"blink1\")' style='background:#FF9800;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Blink 1Hz</button>";
326 html +=
"<button onclick='setLedState(\"blink4\")' style='background:#FF9800;color:white;padding:8px 16px;border:none;cursor:pointer;margin:2px;'>Blink 4Hz</button>";
329 html +=
"<h2>Charger Status</h2>";
330 html +=
"<table border='1' cellpadding='10'>";
335 html +=
"<tr><td>Chip</td><td>AXP517</td></tr>";
338 html +=
"<tr><td>VBUS Voltage</td><td>" + String(ret ? val : -1) +
" mV</td></tr>";
341 html +=
"<tr><td>VBUS Current</td><td>" + String(ret ? val : -1) +
" mA</td></tr>";
344 html +=
"<tr><td>Battery Voltage</td><td>" + String(ret ? val : -1) +
" mV</td></tr>";
347 html +=
"<tr><td>Battery Current</td><td>" + String(ret ? val : -1) +
" mA</td></tr>";
350 html +=
"<tr><td>VSYS Voltage</td><td>" + String(ret ? val : -1) +
" mV</td></tr>";
353 html +=
"<tr><td>Die Temperature</td><td>" + String(ret ? val : -1) +
" C</td></tr>";
356 html +=
"<tr><td>NTC Temperature</td><td>" + String(ret ? val : -1) +
" %</td></tr>";
358 html +=
"<tr><td>Charging</td><td>" + String(status.
charging ?
"Yes" :
"No") +
"</td></tr>";
359 html +=
"<tr><td>Online</td><td>" + String(status.
online ?
"Yes" :
"No") +
"</td></tr>";
360 html +=
"<tr><td>VBUS Present</td><td>" + String(status.
vbusPresent ?
"Yes" :
"No") +
"</td></tr>";
361 html +=
"<tr><td>Battery Present</td><td>" + String(status.
batteryPresent ?
"Yes" :
"No") +
"</td></tr>";
362 html +=
"<tr><td>Charge Done</td><td>" + String(status.
chargeDone ?
"Yes" :
"No") +
"</td></tr>";
363 html +=
"<tr><td>Fault</td><td>" + String(status.
fault ?
"Yes" :
"No") +
"</td></tr>";
365 String chargingStatusStr;
378 html +=
"<tr><td>Charging Status</td><td>" + chargingStatusStr +
"</td></tr>";
380 html +=
"<tr><td>Boost Enabled</td><td>" + String(boostEnabled ?
"Yes" :
"No") +
"</td></tr>";
393 html +=
"<meta http-equiv='refresh' content='1'>";
394 html +=
"<p>Auto-refresh every 1 second</p>";
395 html +=
"</body></html>";
397 server.send(200,
"text/html", html);
401 Serial.println(
"Web server started");
403 Serial.println(
"Setup complete!");
417 server.handleClient();
423 uint32_t irqStatus =
bmu.irq().readStatus(
true);
425 Serial.print(
"IRQ Status: 0x");
426 Serial.println(irqStatus, HEX);
427 if (
bmu.irq().isVbusInsert(irqStatus)) {
428 Serial.println(
"VBUS Inserted");
430 if (
bmu.irq().isVbusRemove(irqStatus)) {
431 Serial.println(
"VBUS Removed");
433 if (
bmu.irq().isBatteryInsert(irqStatus)) {
434 Serial.println(
"Battery Inserted");
436 if (
bmu.irq().isBatteryRemove(irqStatus)) {
437 Serial.println(
"Battery Removed");
439 if (
bmu.irq().isChargeDone(irqStatus)) {
440 Serial.println(
"Charge Done");
442 if (
bmu.irq().isChargeStart(irqStatus)) {
443 Serial.println(
"Charge Started");
445 if (
bmu.irq().isVbusOverVoltage(irqStatus)) {
446 Serial.println(
"VBUS Over Voltage");
448 if (
bmu.irq().isBoostOverVoltage(irqStatus)) {
449 Serial.println(
"Boost Over Voltage");
451 if (
bmu.irq().isDieOverTempLevel1(irqStatus)) {
452 Serial.println(
"Die Over Temperature");
454 if (
bmu.irq().isChgSafetyTimer(irqStatus)) {
455 Serial.println(
"Safety Timer Expired");
457 if (
bmu.irq().isBatOverVoltage(irqStatus)) {
458 Serial.println(
"Battery Over Voltage");
460 if (
bmu.irq().isBatFetOcp(irqStatus)) {
461 Serial.println(
"Battery FET Over Current");
470 Serial.
begin(115200);
471 Serial.println(
"This example is only compatible with ESP32. Please run on ESP32 platform.");
volatile bool irqTriggered
bool enableChannels(uint32_t mask) override
Enable one or more ADC channels.
bool read(Channel ch, float &out) override
Read ADC value for specified channel.
bool setFastChargeCurrent(uint16_t mA) override
Set fast charge (constant-current) current.
uint16_t getPreChargeCurrent() override
Get pre-charge current.
uint16_t getFastChargeCurrent() override
Get fast charge current.
bool setTerminationCurrent(uint16_t mA) override
Set termination current.
bool setChargeVoltage(uint16_t mV) override
Set charge voltage (constant voltage phase)
uint16_t getChargeVoltage() override
Get charge voltage.
bool setPreChargeCurrent(uint16_t mA) override
Set pre-charge current.
uint16_t getTerminationCurrent() override
Get termination current.
Status getStatus() override
Get charger status.
bool setMode(Mode mode) override
Set LED operating mode.
ManualState getManualState() override
Get manual LED state.
bool setManualState(ManualState state) override
Set manual LED state.
Mode getMode() override
Get LED operating mode.
bool isBoostEnabled() const override
Check if boost mode is enabled.
bool enableShipMode(bool enable) override
Enable or disable ship mode.
bool setMinimumSystemVoltage(uint32_t mv) override
Set minimum system voltage.
bool setInputVoltageLimit(uint32_t mv) override
Set input voltage limit (VINDPM)
bool setInputCurrentLimit(uint32_t mA) override
Set input current limit.
bool enableBoost(bool enable) override
Enable or disable OTG (boost) mode.
uint32_t getInputVoltageLimit() const override
Get input voltage limit.
uint16_t getBoostVoltage() const override
Get boost output voltage.
uint32_t getInputCurrentLimit() const override
Get input current limit.
uint32_t getMinimumSystemVoltage() const override
Get minimum system voltage.
bool isShipModeEnabled() const override
Check if ship mode is enabled.
High-level driver facade for the X-Powers AXP517 PMIC.
@ DIE_TEMPERATURE
Die temperature.
@ BAT_VOLTAGE
Battery voltage.
@ BAT_TEMPERATURE
Battery temperature.
@ BAT_CURRENT
Battery current.
@ VBUS_CURRENT
VBUS current.
@ VBUS_VOLTAGE
VBUS voltage.
@ VSYS_VOLTAGE
VSYS voltage.
bool begin(SensorCommCustom::CustomCallback callback, SensorCommCustomHal::CustomHalCallback hal_cb, uint8_t addr)
Initialize using custom I2C callback.
BQ25896Charger & charger()
Get charger interface.
@ NO_CHARGING
Not charging, battery idle or disconnected.
@ PRE_CHARGE
Pre-charge phase (low current for weak battery)
@ TERMINATION
Charging terminated (battery full)
@ FAST_CHARGE
Fast charge phase (constant current)
ManualState
Manual LED state (portable subset).
Mode
High-level LED operating mode (portable subset).
@ BREATH
Breath/blink mode controlled by PMIC/hardware (if supported).
@ MANUAL
Manual control through registers.
@ AUTO
PMIC controls LED automatically (e.g.
@ DISABLE
LED is disabled (if supported).
Charger status structure.
bool vbusPresent
VBUS detected / good (USB power present)
bool chargeDone
Charge termination/done (battery full)
bool fault
Any fault latched/active.
bool charging
Charging state (coarse: true if in precharge/fastcharge)
bool batteryPresent
Battery present and detected.
ChargingStatus chargingStatus
Charging status enumeration.
bool online
PMIC reachable / initialized.