This class provides APIs to all of the registers of the TI BQ27441 battery gauge, as used on the u-blox C030 board. The caller should instantiate an I2C interface and pass this to init(), which will initialise the chip and place it into its lowest power state. When battery gauging is enabled, the getRemainingCapacity()/getRemainingPercentage() API calls may be used; otherwise the chip will be maintained in its lowest power state until a voltage/current/temperature reading is requested.

Dependents:   example-battery-gauge-bq27441

Files at this revision

API Documentation at this revision

Comitter:
breadboardbasics
Date:
Wed Dec 13 17:14:51 2017 +0000
Parent:
5:63b325f2c21a
Commit message:
Fixes current = 0 problem and adds power measurement capability

Changed in this revision

battery_gauge_bq27441.h Show annotated file Show diff for this revision Revisions of this file
bq27441.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/battery_gauge_bq27441.h	Wed Jun 14 17:11:40 2017 +0100
+++ b/battery_gauge_bq27441.h	Wed Dec 13 17:14:51 2017 +0000
@@ -113,8 +113,20 @@
     * @return true if successful, otherwise false.
     */
     bool getVoltage (int32_t *pVoltageMV);
+    
+    /** Read the power output the battery.
+    * If battery gauging is off this function will take ~1 second
+    * to return while the ADCs are activated and the reading is taken.
+    * If battery gauging is on, the last voltage reading taken
+    * will be returned without delay.
+    * @param pPowerMW place to put the power reading.
+    * @return true if successful, otherwise false.
+    */
+    bool getPower (int32_t *pPowerMW);
 
     /** Read the current flowing from the battery.
+    * Negative value means battery is being drained
+    * Positive value means battery is being charged
     * If battery gauging is off this function will take ~1 second
     * to return while the ADCs are activated and the reading is taken.
     * If battery gauging is on, the last current reading taken
@@ -242,6 +254,14 @@
     * @return true if successful, otherwise false.
     */
     bool getTwoBytes (uint8_t registerAddress, uint16_t *pBytes);
+    
+    /** Read two bytes starting at a given address (signed int16).
+    * Note: gpI2c should be locked before this is called.
+    * @param registerAddress the register address to start reading from.
+    * @param pBytes place to put the two bytes.
+    * @return true if successful, otherwise false.
+    */
+    bool getTwoBytesSigned (uint8_t registerAddress, int16_t *pBytes);
 
     /** Compute the checksum of a block of memory in the chip.
     * @param pData a pointer to the 32 byte data block.
--- a/bq27441.cpp	Wed Jun 14 17:11:40 2017 +0100
+++ b/bq27441.cpp	Wed Dec 13 17:14:51 2017 +0000
@@ -82,6 +82,29 @@
     return success;
 }
 
+bool BatteryGaugeBq27441::getTwoBytesSigned (uint8_t registerAddress, int16_t *pBytes)
+{
+    bool success = false;
+    char data[3];
+
+    if (gpI2c != NULL) {
+        // Send a command to read from registerAddress
+        data[0] = registerAddress;
+        data[1] = 0;
+        data[2] = 0;
+
+        if ((gpI2c->write(gAddress, &(data[0]), 1) == 0) &&
+            (gpI2c->read(gAddress, &(data[1]), 2) == 0)) {
+            success = true;
+            if (pBytes) {
+                *pBytes = (((int16_t) data[2]) << 8) + data[1];
+            }
+        }
+    }
+
+    return success;
+}
+
 // Compute the checksum over a block of data.
 uint8_t BatteryGaugeBq27441::computeChecksum(const char * pData)
 {
@@ -941,28 +964,56 @@
     return success;
 }
 
+// Get the power output of the battery
+bool BatteryGaugeBq27441::getPower (int32_t *pPowerMW)
+{
+    bool success = false;
+    int16_t data = 0;
+
+    if (gReady && (gpI2c != NULL)) {
+        // Make sure there's a recent reading
+        if (gGaugeOn || makeAdcReading()) {            
+            gpI2c->lock();
+            // Read from the power register address
+            if (getTwoBytesSigned (0x18, &data)) {
+                success = true;
+
+                // The answer is in mW
+                if (pPowerMW) {
+                    *pPowerMW = (int32_t) data;
+                }
+
+            }
+
+            // Return to sleep if we are allowed to
+            if (!gGaugeOn && !setHibernate()) {
+                success = false;
+            }
+
+            gpI2c->unlock();
+        }
+    }
+    
+    return success;
+}
+
 // Get the current flowing from the battery.
 bool BatteryGaugeBq27441::getCurrent (int32_t *pCurrentMA)
 {
     bool success = false;
-    int32_t currentMA = 0;
-    uint16_t data;
+    int16_t data;
 
     if (gReady && (gpI2c != NULL)) {
         // Make sure there's a recent reading
         if (gGaugeOn || makeAdcReading()) {            
             gpI2c->lock();            
             // Read from the average current register address
-            if (getTwoBytes (0x10, &data)) {
+            if (getTwoBytesSigned  (0x10, &data)) {
                 success = true;
 
                 if (pCurrentMA) {
-                    *pCurrentMA = currentMA;
+                    *pCurrentMA = (int32_t) data;
                 }
-
-#ifdef DEBUG_BQ27441
-                printf("BatteryGaugeBq27441 (I2C 0x%02x): current %d mA.\n", gAddress >> 1, (int) currentMA);
-#endif
             }
 
             // Return to sleep if we are allowed to