Library to interface to the TI BQ27441, a fuel gauge monitor

Dependents:   rcCar

Fork of battery-gauge-bq27441 by u-blox

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