Skip to content

Commit

Permalink
Added library
Browse files Browse the repository at this point in the history
  • Loading branch information
pAIgn10 committed Jan 10, 2014
1 parent b698d68 commit 95aef9c
Show file tree
Hide file tree
Showing 5 changed files with 467 additions and 0 deletions.
201 changes: 201 additions & 0 deletions LiFuelGauge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/**
* Name: LiFuelGauge
* Author: Nick Lamprianidis { paign10.ln@gmail.com }
* Version: 1.0
* Description: A library for interfacing the MAXIM MAX17043/MAX17044
* Li+ fuel gauges. These ICs report the relative state of charge
* of the connected Lithium Ion Polymer battery, and the library
* can help you configure them and communicate with them
* Source: https://github.com/pAIgn10/LiFuelGauge
* License: Copyright (c) 2014 Nick Lamprianidis
* This library is licensed under the MIT license
* http://www.opensource.org/licenses/mit-license.php
*
* Filename: LiFuelGauge.cpp
* File description: Implementations of methods for the LiFuelGauge library
*/

#include "LiFuelGauge.h"

// Initializes variables and the Wire library
LiFuelGauge::LiFuelGauge(gaugeType ic) : _ic(ic), _f(NULL) { Wire.begin(); }

// Initializes varaibles and the Wire library
// Assigns ISR f to interrupt intr (for Alert Interrupt)
LiFuelGauge::LiFuelGauge(gaugeType ic, uint8_t intr, func f) : _ic(ic), _f(f)
{
attachInterrupt(intr, f, FALLING);
Wire.begin();
}

// Returns a measurement of the voltage of the connected LiIon Polymer battery
// 0-5V range w/ 1.25mV resolution for the MAX17043
// 0-10V range w/ 2.5mV resolution for the MAX17044
double LiFuelGauge::getVoltage()
{
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_VCELL_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(MAX1704X_ADDR, (uint8_t)2);
return ( (Wire.read() << 4) + (Wire.read() >> 4) ) * 0.00125 * _ic;
}

// Returns the relative state of charge of the connected LiIon Polymer battery
// as a percentage of the full capacity w/ resolution 1/256%
double LiFuelGauge::getSOC()
{
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_SOC_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(MAX1704X_ADDR, (uint8_t)2);
return Wire.read() + (double) Wire.read() / 256;
}

// Returns the production version of the IC
uint16_t LiFuelGauge::getVersion()
{
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_VERSION_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(MAX1704X_ADDR, (uint8_t)2);
return ( Wire.read() << 8 ) + Wire.read();
}

// Returns a value used to optimize IC performance
// to different operating conditions
uint8_t LiFuelGauge::getCompensation()
{
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_RCOMP_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(MAX1704X_ADDR, (uint8_t)1);
return Wire.read();
}

// Returns the alert threshold as a percentage
// below which an alert interrupt is generated
uint8_t LiFuelGauge::getAlertThreshold()
{
return ( ~getStatus() & 0x1F ) + 1;
}

// Helper method. Returns the LSByte of the CONFIG register
uint8_t LiFuelGauge::getStatus()
{
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_ATHRD_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(MAX1704X_ADDR, (uint8_t)1);
return Wire.read();
}

// Sets a value to the MSByte of the CONFIG register used to optimize
// IC performance to different operating conditions
// Returns the status of transmission
uint8_t LiFuelGauge::setCompensation(uint8_t comp)
{
uint8_t status = getStatus();

Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_CONFIG_ADDR);
Wire.write(comp);
Wire.write(status);
return Wire.endTransmission();
}

// Sets the alert threshold below which an alert interrupt is generated
// The acceptable range is 1-32%. Default threshold is 4%
// Returns the status of transmission
uint8_t LiFuelGauge::setAlertThreshold(uint8_t thrd)
{
if ( thrd > 32 ) thrd = 32;
else if ( thrd < 1 ) thrd = 1;
thrd = ( ~thrd + 1 ) & 0x1F;

uint8_t comp, sleepBit;
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_CONFIG_ADDR);
Wire.endTransmission(false);
Wire.requestFrom(MAX1704X_ADDR, (uint8_t)2);
comp = Wire.read();
sleepBit = Wire.read() & 0x80;

Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_CONFIG_ADDR);
Wire.write(comp);
Wire.write(sleepBit | thrd);
return Wire.endTransmission();
}

// After an alert interrupt has been generated,
// it clears the alert bit on the CONFIG register
// Returns the status of transmission
uint8_t LiFuelGauge::clearAlertInterrupt()
{
uint8_t comp = getCompensation();
uint8_t status = getStatus();

Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_CONFIG_ADDR);
Wire.write(comp);
Wire.write(0xDF & status);
return Wire.endTransmission();
}

// It puts the MAX1704X to sleep
// All IC operations are halted
// Returns the status of transmission
uint8_t LiFuelGauge::sleep()
{
uint8_t comp = getCompensation();
uint8_t thrd = getAlertThreshold();

Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_CONFIG_ADDR);
Wire.write(comp);
Wire.write(0x80 | thrd);
return Wire.endTransmission();
}
// It wakes the MAX1704X from sleep mode
// Returns the status of transmission
uint8_t LiFuelGauge::wake()
{
uint8_t comp = getCompensation();
uint8_t thrd = getAlertThreshold();

Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_CONFIG_ADDR);
Wire.write(comp);
Wire.write(0x7F & thrd);
return Wire.endTransmission();
}

// Returns a value corresponding to
// whether the MAX1704X is in sleep mode
boolean LiFuelGauge::sleeping()
{
return ( getStatus() & 0x80 ) == 0x80;
}

// It forces the MAX1704X to
// restart fuel-gauge calculations
// Returns the status of transmission
uint8_t LiFuelGauge::quickStart()
{
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_MODE_ADDR);
Wire.write(0x40);
Wire.write(0x00);
return Wire.endTransmission();
}

// It forces the MAX1704X to completely reset
// Returns the status of transmission
uint8_t LiFuelGauge::reset()
{
Wire.beginTransmission(MAX1704X_ADDR);
Wire.write(MAX1704X_COMMAND_ADDR);
Wire.write(0x54);
Wire.write(0x00);
return Wire.endTransmission();
}
72 changes: 72 additions & 0 deletions LiFuelGauge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Name: LiFuelGauge
* Author: Nick Lamprianidis { paign10.ln@gmail.com }
* Version: 1.0
* Description: A library for interfacing the MAXIM MAX17043/MAX17044
* Li+ fuel gauges. These ICs report the relative state of charge
* of the connected Lithium Ion Polymer battery, and the library
* can help you configure them and communicate with them
* Source: https://github.com/pAIgn10/LiFuelGauge
* License: Copyright (c) 2014 Nick Lamprianidis
* This library is licensed under the MIT license
* http://www.opensource.org/licenses/mit-license.php
*
* Filename: LiFuelGauge.h
* File description: Definitions and methods for the LiFuelGauge library
*/

#ifndef LiFuelGauge_h
#define LiFuelGauge_h

#include <Arduino.h>
#include <Wire.h>

// MAX1704X register addresses
const uint8_t MAX1704X_ADDR = 0x36;
const uint8_t MAX1704X_VCELL_ADDR = 0x02;
const uint8_t MAX1704X_SOC_ADDR = 0x04;
const uint8_t MAX1704X_MODE_ADDR = 0x06;
const uint8_t MAX1704X_VERSION_ADDR = 0x08;
const uint8_t MAX1704X_CONFIG_ADDR = 0x0C;
const uint8_t MAX1704X_RCOMP_ADDR = 0x0C;
const uint8_t MAX1704X_ATHRD_ADDR = 0x0D;
const uint8_t MAX1704X_COMMAND_ADDR = 0xFE;

// Signature of the ISR for the ALERT Interrupt
typedef void (*func)();

// Names of the two supported ICs
// Used for reporting the correct voltage measurement (see getVoltage method)
enum gaugeType
{
MAX17043 = 1,
MAX17044 = 2
};

// Class for interfacing the MAX17043/MAX17044 Li+ fuel gauges
class LiFuelGauge
{
public:
LiFuelGauge(gaugeType ic);
LiFuelGauge(gaugeType ic, uint8_t intr, func f);
double getVoltage();
double getSOC();
uint16_t getVersion();
uint8_t getCompensation();
uint8_t getAlertThreshold();
uint8_t setCompensation(uint8_t comp);
uint8_t setAlertThreshold(uint8_t thrd);
uint8_t clearAlertInterrupt();
uint8_t sleep();
uint8_t wake();
boolean sleeping();
uint8_t quickStart();
uint8_t reset();

private:
gaugeType _ic;
func _f;
uint8_t getStatus();
};

#endif // LiFuelGauge
68 changes: 68 additions & 0 deletions examples/FuelGauge/FuelGauge.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* This is an example demonstrating the use of the LiFuelGauge library
* The example prints battery status information on the serial monitor
* When an Alert Threshold interrupt is generated, the lowPower ISR is
* called and afterwards (hypothetically) any running operations are
* getting finalized before the system enters sleep mode
*
* Note:
* After exiting sleep mode or resetting, give the MAX17043/4
* half a second to perform the first measurements
*/

#include <Wire.h>
#include <LiFuelGauge.h>

// LiFuelGauge constructor parameters
// 1. IC type, MAX17043 or MAX17044
// 2. Number of interrupt to which the alert pin is associated (Optional)
// 3. ISR to call when an alert interrupt is generated (Optional)
//
// Creates a LiFuelGauge instance for the MAX17043 IC
// and attaches lowPower to INT0 (PIN2 on most boards, PIN3 on Leonardo)
LiFuelGauge gauge(MAX17043, 0, lowPower);

// A flag to indicate a generated alert interrupt
volatile boolean alert = false;


void setup()
{
Serial.begin(9600); // Initializes serial port
// Waits for serial port to connect. Needed for Leonardo only
while ( !Serial ) ;

gauge.reset(); // Resets MAX17043
delay(200); // Waits for the initial measurements to be made

// Sets the Alert Threshold to 10% of full capacity
gauge.setAlertThreshold(10);
Serial.println(String("Alert Threshold is set to ") +
gauge.getAlertThreshold() + '%');
}

void loop()
{
Serial.print("SOC: ");
Serial.print(gauge.getSOC()); // Gets the battery's state of charge
Serial.print("%, VCELL: ");
Serial.print(gauge.getVoltage()); // Gets the battery voltage
Serial.println('V');

if ( alert )
{
Serial.println("Beware, Low Power!");
Serial.println("Finalizing operations...");
gauge.clearAlertInterrupt(); // Resets the ALRT pin
alert = false;
Serial.println("Storing data...");
Serial.println("Sending notification...");
Serial.println("System operations are halted...");
gauge.sleep(); // Forces the MAX17043 into sleep mode
while ( true ) ;
}

delay(2000);
}

void lowPower() { alert = true; }
Loading

0 comments on commit 95aef9c

Please sign in to comment.