Battery voltage

Battery Voltage - Argon

The Argon device does not have a fuel gauge chip, however you can determine the voltage of the LiPo battery, if present.

float voltage = analogRead(BATT) * 0.0011224;

The constant 0.0011224 is based on the voltage divider circuit (R1 = 806K, R2 = 2M) that lowers the 3.6V LiPo battery output to a value that can be read by the ADC.

The charge indicator on the Argon can be read using:

pinMode(CHG, INPUT_PULLUP);
bool charging = !digitalRead(CHG);

In other words, the CHG input is 0 when charging and 1 when not charging, and the ! inverts this logic to make it easier to use. You only need to set the pinMode once, typically in setup().

On Gen 3 (nRF52) devices including the Argon, Boron, B-SoM, and Tracker, you can determine if there is USB power with this code:

bool hasVUSB() {
    // This only works with nRF52-based devices (Argon, Boron, B-SoM, Tracker)
    uint32_t *pReg = (uint32_t *)0x40000438; // USBREGSTATUS

    return (*pReg & 1) != 0;
}

This sample code for the Argon shows how to read the various states:

#include "Particle.h"

SYSTEM_MODE(SEMI_AUTOMATIC);
#ifndef SYSTEM_VERSION_v620
SYSTEM_THREAD(ENABLED); // System thread defaults to on in 6.2.0 and later and this line is not required
#endif

SerialLogHandler logHandler(LOG_LEVEL_INFO);

bool hasVUSB();

void setup() {
    RGB.control(true);
    RGB.color(64, 64, 64); // Gray

    pinMode(CHG, INPUT_PULLUP);

    // Particle.connect()
}

bool chgLast = false;
bool pwrLast = false;

void loop() {
    bool chg = !digitalRead(CHG);
    bool pwr = hasVUSB(); // Use this instead of reading PWR

    if (chgLast != chg || pwrLast != pwr) {
        String msg = String::format("chg=%d pwr=%d", chg, pwr);
        if (Particle.connected()) {
            Particle.publish("testChgBat", msg);
        }
        Log.info(msg);

        if (chg && pwr) {
            // Charging from USB power
            RGB.color(255, 165, 0); // Orange (looks kind of yellow)
        }
        else
        if (!chg && pwr) {
            // USB power, fully charged
            RGB.color(0, 255, 0); // Green            
        }
        else if (!pwr) {
            // No USB power, is powered from battery and discharging
            RGB.color(64, 64, 64); // Gray 
        }
        else {
            // Unexpected case
            RGB.color(255, 0, 0); // Red
        }

        chgLast = chg;
        pwrLast = pwr;        
    }
}

bool hasVUSB() {
    // This only works with nRF52-based devices (Argon, Boron, B-SoM, Tracker)
    uint32_t *pReg = (uint32_t *)0x40000438; // USBREGSTATUS

    return (*pReg & 1) != 0;
}

Note:

This technique applies only to the Argon and Photon 2. For the Boron, Electron, and E-Series, see the FuelGauge, below.

The Photon and P1 don't have built-in support for a battery.