It’s not exactly obvious how this register works. The problem is that you can detect two different things, and neither is exactly right but you can choose which one is best for your use case:
If you detect USB host it will detect when you are connected to a computer, but not a USB charger
If you detect power good, if will detect both a USB host and USB charger, but it will also detect external power on VIN. If you don’t also supply power by VIN, it’s a good option.
#include "Particle.h"
bool isUsbPowered(); // forward declaration
PMIC pmic;
bool lastPowerState = false;
void setup() {
pmic.begin();
}
void loop() {
bool powerState = isUsbPowered();
if (powerState != lastPowerState) {
Particle.publish("usbPowered", (powerState ? "true" : "false"), 60, PRIVATE);
lastPowerState = powerState;
}
delay(2000);
}
bool isUsbPowered() {
bool isUsbPowered;
// Get the system status register from the PMIC
byte systemStatus = pmic.getSystemStatus();
// Normally you want to use this. It will return true if the Electron is powered by a USB host (computer/laptop),
// USB charger, or the VIN pin. Basically, it really determines if it's externally powered, not USB powered.
isUsbPowered = (systemStatus & 0x4) != 0;
// Alternatively, you could use this. This will return true if the Electron is powered by a USB host.
// It will return false for a USB charger or VIN.
// Basically, it's not possible to tell the difference between VIN and USB Charger in software, as far as I can tell
// isUsbPowered = ((systemStatus & 0xc0) == 0x40);
return isUsbPowered;
}
/*
Fuel Gauge MAX 17043
Power Management BQ24195
//System Status Register
//NOTE: This is a read-only register
REG08
BIT
--- VBUS status
7: VBUS_STAT[1] | 00: Unknown (no input, or DPDM detection incomplete), 01: USB host
6: VBUS_STAT[0] | 10: Adapter port, 11: OTG
--- Charging status
5: CHRG_STAT[1] | 00: Not Charging, 01: Pre-charge (<VBATLOWV)
4: CHRG_STAT[0] | 10: Fast Charging, 11: Charge termination done
3: DPM_STAT 0: Not DPM
1: VINDPM or IINDPM
2: PG_STAT 0: Power NO Good :(
1: Power Good :)
1: THERM_STAT 0: Normal
1: In Thermal Regulation (HOT)
0: VSYS_STAT 0: Not in VSYSMIN regulation (BAT > VSYSMIN)
1: In VSYSMIN regulation (BAT < VSYSMIN)ault is 3.5V (101)
0: Reserved
*/