LTC2941-1 - 1A I2C Battery Gas Gauge with Internal Sense Resistor
Features
- Indicates Accumulated Battery Charge and Discharge
- SMBus/I2C Interface
- Integrated 50mΩ High Side Sense Resistor
- ±1A Sense Current Range
- High Accuracy Analog Integration
- 1% Charge Accuracy
- Configurable Alert Output/Charge Complete Input
- 2.7V to 5.5V Operating Range
- Quiescent Current Less than 100μA
- Small 6-Pin 2mm × 3mm DFN package
Typical Application
Description
The LTC2941-1 measures battery charge state in battery-powered handheld PC and portable product applications. Its operating range is perfectly suited for single cell Li-Ion batteries. A precision coulomb counter integrates current through an internal sense resistor between the battery’s positive terminal and the load or charger. The measured charge is stored in internal registers. An SMBus/I2C interface accesses and configures the device.
The LTC2941-1 features programmable high and low thresholds for accumulated charge. If a threshold is exceeded, the device communicates an alert using either the SMBus alert protocol or by setting a flag in the internal status register.
| Integrated Sense Resistor | |
|---|---|
| LTC2941 | No |
| LTC2941-1 | Yes |
Packaging
CAD Symbols and Footprints: The downloadable Zip file below contains the schematic symbol and PCB footprints.
For complete and up to date package information and drawings, please refer to our packaging page
| Part Number | Package | Code | Temp | Package Drawing |
RoHS |
|---|---|---|---|---|---|
| LTC2941CDCB-1#PBF | 2x3 DFN-6 | DCB | C | 05-08-1715 | Yes |
| LTC2941CDCB-1#TRMPBF | 2x3 DFN-6 | DCB | C | 05-08-1715 | Yes |
| LTC2941CDCB-1#TRPBF | 2x3 DFN-6 | DCB | C | 05-08-1715 | Yes |
| LTC2941IDCB-1#PBF | 2x3 DFN-6 | DCB | I | 05-08-1715 | Yes |
| LTC2941IDCB-1#TRMPBF | 2x3 DFN-6 | DCB | I | 05-08-1715 | Yes |
| LTC2941IDCB-1#TRPBF | 2x3 DFN-6 | DCB | I | 05-08-1715 | Yes |
Order Info
- Part numbers ending in PBF are lead free. Solder plated terminal finish (SnPb) versions are non-standard and special terms and conditions and pricing applies if available. Please contact LTC marketing for information.
- Part numbers containing TR or TRM are shipped in tape and reel or 500 unit mini tape and reel, respectively
- Please refer to our general ordering information or the product datasheet for more details
Package Variations and Pricing
| Part Number | Package | Temp | Price (1-99) |
Price (1k)* |
RoHS | |
|---|---|---|---|---|---|---|
| LTC2941CDCB-1#PBF | 2x3 DFN-6 | C | $2.40 | Yes | ||
| LTC2941CDCB-1#TRMPBF | 2x3 DFN-6 | C | $2.41 | $1.70 | Yes | |
| LTC2941CDCB-1#TRPBF | 2x3 DFN-6 | C | $1.65 | Yes | ||
| LTC2941IDCB-1#PBF | 2x3 DFN-6 | I | $2.87 | Yes | ||
| LTC2941IDCB-1#TRMPBF | 2x3 DFN-6 | I | $2.88 | $2.03 | Yes | |
| LTC2941IDCB-1#TRPBF | 2x3 DFN-6 | I | $1.98 | Yes | ||
| Buy Now • Request Samples | ||||||
Demo Boards
Linear Technology offers many demo boards free of charge to qualified customers. Contact your local sales office or distributor to inquire about a demo board. Certain demo boards are also available for sale via credit card on this website. Demo boards are for evaluation purposes only. It remains the customer’s responsibility to verify proper and reliable operation in the actual end application.| Part Number | Description | Price | Documentation |
|---|---|---|---|
| DC1496B-C | LTC2941-1 Demo Board | 2.7V to 5.5V Battery Gas Gauge w/ I2C (requires DC590B) | $50.00 | |
| Buy Now | |||
Companion Boards
| Part Number | Description | Price | Documentation |
|---|---|---|---|
| DC590B | Isolated USB Serial Controller for Linear Technology QuikEval-Compatible Demo Boards | $50.00 | |
| Buy Now | |||
Applications
- Low Power Handheld Products
- Cellular Phones
- MP3 Player
- Cameras
- GPS
People Who Viewed This Product Also Viewed
- LTC2941 - Battery Gas Gauge with I2C Interface
- LTC2942 - Battery Gas Gauge with Temperature, Voltage Measurement
- LTC4150 - Coulomb Counter/Battery Gas Gauge
- LTC2942-1 - 1A Battery Gas Gauge with Internal Sense Resistor and Temperature/Voltage Measurement
- LTC2943 - Multicell Battery Gas Gauge with Temperature, Voltage and Current Measurement
- LTC4000 - High Voltage High Current Controller for Battery Charging and Power Management
- LT3652 - Power Tracking 2A Battery Charger for Solar Power
- LT3796/LT3796-1 - 100V Constant-Current and Constant-Voltage Controller with Dual Current Sense
- LT3761/LT3761-1 - 60VIN LED Controller with Internal PWM Generator
- LTM8062 - 32VIN, 2A μModule (Power Module) Power Tracking Battery Charger
Product Notifications
Please login to your MyLinear account for notifications of datasheet updates, new document releases and LTspice model announcements for your favorite products. If you do not have a MyLinear account you may Sign Up Now.
Forgot your password? Click here.
Need help? Email mylinear@linear.com with questions and comments.
Design Tools
LTspice
LTspice® software is a powerful, fast and free simulation tool, schematic capture and waveform viewer with enhancements and models for improving the simulation of switching regulators. Click here to download LTspice
Models for the following parts are available in LTspice:
LTC2941
LTC2941-1
Linduino
Linduino is an Arduino compatible platform for developing and distributing firmware libraries and code for SPI and I²C-compatible integrated circuits. The Linduino One board interfaces to more than 300 QuikEval demonstration cards, supporting a variety of product types including analog-to-digital converters (ADCs), digital-to-analog converters (DACs), power monitors, and more. Firmware libraries for individual devices are written in C and designed to be portable to a wide variety of processors and microcontrollers. Each library has a demonstration program that can be uploaded to the Linduino One platform to allow the circuit and software to be quickly and easily verified.
Code
Linduino is Linear Technology's Arduino compatible system for developing and distributing firmware libraries and example code for Linear Technology’s integrated circuits. The code below can be downloaded or copied and pasted into your project. Please visit the Linduino Home Page for demo board, manual and setup information.
This part is Family Supported: There is example code available for a part in this family. The code may require some changes to work with this specific part, however it still provides many good examples of how certain interactions should take place. The code below may rely on other drivers available in the full library.
Download LTC2942 - DC1496BB.ino
/*!
Linear Technology DC14968B-B Demonstration Board.
LTC2942: Battery Gas Gauge with Temperature, Voltage Measurement
Linear Technology DC14968B-A Demonstration Board.
LTC2941: Battery Gas Gauge with I2C Interface
@verbatim
Setup:
Apply a voltage source to the V_BATT terminal and a load at the V_CHRG/LD terminal.
Refer to the Demo Manual Guide for a detailed setup description. Ensure that JP1 is
set to AL# position.
Explanation of Commands:
1 - Automatic Mode - Scans Voltage, Temperature and charge every 60ms.
Scanning interval has been increased to 1s for ease of reading on the Serial Prompt.
Displays an alert if it is set in the status register at the time of scan.
2 - Manual Voltage Mode - Provides a SnapShot of the Voltage, and Accumulated Charge.
After the initial SnapShot, the part goes into sleep mode where it only counts charge.
Displays an alert if it is set in the status register at the time of scan.
3 - Manual Temperature Mode - Provides a SnapShot of the Temperature, and Accumulated Charge.
After the initial SnapShot, the part goes into sleep mode where it only counts charge.
Displays an alert if it is set in the status register at the time of scan.
4 - Sleep Mode - The ADC portion of the LTC2942 is shutdown. In this mode only charge is accumulated.
5 - Shutdown Mode - The LTC2942 goes into low power mode.
6 - Settings - Allows user to set alert thresholds, set prescalar, set AL#/CC# pin mode and change the temperature and charge units.
NOTES
Setup:
Set the terminal baud rate to 115200 and select the newline terminator.
Requires a power supply.
Refer to demo manual DC1812A-A.
For use with LTC2941 ignore calls to temperature and voltage as these are not present in LTC2941.
All of the functionality of LTC2941 is supported except Control Register B[7:6]
USER INPUT DATA FORMAT:
decimal : 1024
hex : 0x400
octal : 02000 (leading 0 "zero")
binary : B10000000000
float : 1024.0
@endverbatim
http://www.linear.com/product/LTC2942
http://www.linear.com/product/LTC2941
http://www.linear.com/product/LTC2942#demoboards
http://www.linear.com/product/LTC2941#demoboards
REVISION HISTORY
$Revision: 6595 $
$Date: 2017-02-27 15:04:18 -0800 (Mon, 27 Feb 2017) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC2942
*/
#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_I2C.h"
#include "UserInterface.h"
#include "QuikEval_EEPROM.h"
#include "LTC2942.h"
#include <Wire.h>
// Function Declaration
void print_title(); // Print the title block
void print_prompt(); // Print the Prompt
void store_alert_settings(); // Store the alert settings to the EEPROM
int8_t restore_alert_settings(); // Read the alert settings from EEPROM
#define AUTOMATIC_MODE_DISPLAY_DELAY 1000 //!< The delay between readings in automatic mode
#define SCAN_MODE_DISPLAY_DELAY 10000 //!< The delay between readings in scan mode
const float resistor = .100; //!< resistor value on demo board
// Error string
const char ack_error[] = "Error: No Acknowledge. Check I2C Address."; //!< Error message
// Global variables
static int8_t demo_board_connected; //!< Set to 1 if the board is connected
static uint8_t alert_code = 0; //!< Value stored or read from ALERT register. Shared between loop() and restore_alert_settings()
//! Initialize Linduino
void setup()
{
char demo_name[] = "DC1496"; //! Demo Board Name stored in QuikEval EEPROM
quikeval_I2C_init(); //! Configure the EEPROM I2C port for 100kHz
quikeval_I2C_connect(); //! Connects to main I2C port
Serial.begin(115200); //! Initialize the serial port to the PC
print_title();
demo_board_connected = discover_demo_board(demo_name);
if (demo_board_connected)
{
print_prompt();
}
else
{
demo_board_connected = true;
Serial.println("Did not read ID String, attempting to proceed anyway...\nPlease ensure I2C lines of Linduino are connected to the LTC device");
print_prompt();
}
}
//! Repeats Linduino loop
void loop()
{
int8_t ack = 0; //! I2C acknowledge indicator
static uint8_t user_command; //! The user input command
static uint8_t mAh_or_Coulombs = 0;
static uint8_t celcius_or_kelvin = 0;
static uint16_t prescalar_mode = LTC2942_PRESCALAR_M_128;
static uint16_t prescalarValue = 128;
static uint16_t alcc_mode = LTC2942_ALERT_MODE;
if (demo_board_connected) //! Do nothing if the demo board is not connected
{
if (Serial.available()) //! Do nothing if serial is not available
{
user_command = read_int(); //! Read user input command
if (user_command != 'm')
Serial.println(user_command);
Serial.println();
ack = 0;
switch (user_command) //! Prints the appropriate submenu
{
case 1:
ack |= menu_1_automatic_mode(mAh_or_Coulombs, celcius_or_kelvin, prescalar_mode, prescalarValue, alcc_mode); //! Automatic Mode
break;
case 2:
ack |= menu_2_manual_voltage_mode(mAh_or_Coulombs, celcius_or_kelvin, prescalar_mode, prescalarValue, alcc_mode); //! Manual Voltage Mode
break;
case 3:
ack |= menu_3_manual_temperature_mode(mAh_or_Coulombs, celcius_or_kelvin, prescalar_mode, prescalarValue, alcc_mode); //! Manual Temperature Mode
break;
case 4:
ack |= menu_4_sleep_mode(mAh_or_Coulombs, prescalar_mode, prescalarValue, alcc_mode); //! Sleep Mode
break;
case 5:
ack |= menu_5_shutdown_mode(); //! Shutdown Mode
break;
case 6:
ack |= menu_6_settings(&mAh_or_Coulombs, &celcius_or_kelvin, &prescalar_mode, &prescalarValue, &alcc_mode); //! Settings Mode
break;
}
if (ack != 0) //! If ack is not recieved print an error.
Serial.println(ack_error);
Serial.print(F("*************************"));
print_prompt();
}
}
}
// Function Definitions
//! Print the title block
void print_title()
{
Serial.println(F("\n*****************************************************************"));
Serial.print(F("* DC1496B-B Demonstration Program *\n"));
Serial.print(F("* *\n"));
Serial.print(F("* This program communicates with the LTC2942 Coulomb Counter *\n"));
Serial.print(F("* found on the DC1496B-B demo board. *\n"));
Serial.print(F("* Set the baud rate to 115200 and select the newline terminator.*\n"));
Serial.print(F("* *\n"));
Serial.print(F("*****************************************************************\n"));
}
//! Print the Prompt
void print_prompt()
{
Serial.print(F("\n1-Automatic Mode\n"));
Serial.print(F("2-Manual Voltage Mode\n"));
Serial.print(F("3-Manual Temperature Mode\n"));
Serial.print(F("4-Sleep Mode\n"));
Serial.print(F("5-Shutdown Mode\n"));
Serial.print(F("6-Settings\n"));
Serial.print(F("Enter a command: "));
}
//! Automatic Mode.
int8_t menu_1_automatic_mode(int8_t mAh_or_Coulombs, int8_t celcius_or_kelvin ,uint16_t prescalar_mode, uint16_t prescalarValue, uint16_t alcc_mode)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
int8_t LTC2942_mode;
int8_t ack = 0;
LTC2942_mode = LTC2942_AUTOMATIC_MODE|prescalar_mode|alcc_mode ; //! Set the control register of the LTC2942 to automatic mode as well as set prescalar and AL#/CC# pin values.
Serial.println();
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_CONTROL_REG, LTC2942_mode); //! Writes the set mode to the LTC2942 control register
if (ack)
{
Serial.println(F("could not configure LTC2942"));
return(ack);
}
do
{
Serial.print(F("*************************\n\n"));
uint8_t status_code, hightemp_code, lowtemp_code;
uint16_t charge_code, current_code, voltage_code, temperature_code;
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_ACCUM_CHARGE_MSB_REG, &charge_code); //! Read MSB and LSB Accumulated Charge Registers for 16 bit charge code
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_VOLTAGE_MSB_REG, &voltage_code); //! Read MSB and LSB Voltage Registers for 16 bit voltage code
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_TEMPERATURE_MSB_REG, &temperature_code); //! Read MSB and LSB Temperature Registers for 16 bit temperature code
ack |= LTC2942_read(LTC2942_I2C_ADDRESS, LTC2942_STATUS_REG, &status_code); //! Read Status Register for 8 bit status code
Serial.print(F("CHARGE: "));
Serial.println(charge_code,HEX);
Serial.print(F("VOLTAGE: "));
Serial.println(voltage_code, HEX);
Serial.print(F("TEMPERATURE: "));
Serial.println(temperature_code,HEX);
float charge, voltage, temperature;
if (mAh_or_Coulombs)
{
charge = LTC2942_code_to_coulombs(charge_code, resistor, prescalarValue); //! Convert charge code to Coulombs if Coulomb units are desired.
Serial.print("Coulombs: ");
Serial.print(charge, 4);
Serial.print(F(" C\n"));
}
else
{
charge = LTC2942_code_to_mAh(charge_code, resistor, prescalarValue); //! Convert charge code to mAh if mAh units are desired.
Serial.print("mAh: ");
Serial.print(charge, 4);
Serial.print(F(" mAh\n"));
}
voltage = LTC2942_code_to_voltage(voltage_code); //! Convert voltage code to Volts
Serial.print(F("Voltage "));
Serial.print(voltage, 4);
Serial.print(F(" V\n"));
if (celcius_or_kelvin)
{
temperature = LTC2942_code_to_kelvin_temperature(temperature_code); //! Convert temperature code to kelvin
Serial.print(F("Temperature "));
Serial.print(temperature, 4);
Serial.print(F(" K\n"));
}
else
{
temperature = LTC2942_code_to_celcius_temperature(temperature_code); //! Convert temperature code to celcius
Serial.print(F("Temperature "));
Serial.print(temperature, 4);
Serial.print(F(" C\n"));
}
checkAlerts(status_code); //! Check status code for Alerts. If an Alert has been set, print out appropriate message in the Serial Prompt.
Serial.print(F("m-Main Menu\n\n"));
Serial.flush();
delay(AUTOMATIC_MODE_DISPLAY_DELAY); //! Delay for 1s before next polling
}
while (!Serial.available() && !(ack)); //! if Serial is not available and an NACK has not been recieved, keep polling the registers.
read_int(); // clears the Serial.available
return(ack);
}
//! Manual Voltage Mode
int8_t menu_2_manual_voltage_mode(int8_t mAh_or_Coulombs ,int8_t celcius_or_kelvin ,uint16_t prescalar_mode, uint16_t prescalarValue, uint16_t alcc_mode)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t LTC2942_mode;
int8_t ack = 0;
LTC2942_mode = LTC2942_MANUAL_VOLTAGE|prescalar_mode|alcc_mode ; //! Set the control mode of the LTC2942 to manual mode as well as set prescalar and AL#/CC# pin values.
Serial.println();
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_CONTROL_REG, LTC2942_mode); //! Writes the set mode to the LTC2942 control register
int staleData = 0; //! Stale Data Check variable. When set to 1 it indicates that stale data is being read from the voltage, current and temperature registers.
do
{
Serial.print(F("*************************\n\n"));
uint8_t status_code;
uint16_t charge_code, voltage_code;
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_ACCUM_CHARGE_MSB_REG, &charge_code); //! Read MSB and LSB Accumulated Charge Registers for 16 bit charge code
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_VOLTAGE_MSB_REG, &voltage_code); //! Read MSB and LSB Voltage Registers for 16 bit voltage code
ack |= LTC2942_read(LTC2942_I2C_ADDRESS, LTC2942_STATUS_REG, &status_code); //! Read Status Registers for 8 bit status code
float charge, voltage, temperature;
if (mAh_or_Coulombs)
{
charge = LTC2942_code_to_coulombs(charge_code, resistor, prescalarValue); //! Convert charge code to Coulombs if Coulomb units are desired.
Serial.print("Coulombs: ");
Serial.print(charge, 4);
Serial.print(F(" C\n"));
}
else
{
charge = LTC2942_code_to_mAh(charge_code, resistor, prescalarValue); //! Convert charge code to mAh if mAh units are desired.
Serial.print("mAh: ");
Serial.print(charge, 4);
Serial.print(F(" mAh\n"));
}
voltage = LTC2942_code_to_voltage(voltage_code); //! Convert voltage code to Volts
Serial.print(F("Voltage "));
Serial.print(voltage, 4);
Serial.print(F(" V"));
if (staleData) Serial.print(F(" ***** Stale Data ******\n")); //! If Stale data is inside the register after initial snapshot, Print Stale Data message.
else Serial.println("");
if (staleData) Serial.print(F(" ***** Stale Data ******\n"));
else Serial.println("");
checkAlerts(status_code); //! Check status code for Alerts. If an Alert has been set, print out appropriate message in the Serial Prompt
Serial.print(F("m-Main Menu\n\n"));
staleData = 1;
Serial.flush();
delay(AUTOMATIC_MODE_DISPLAY_DELAY);
}
while (!Serial.available() && !(ack));
read_int(); // clears the Serial.available
return(ack);
}
//! Manual Voltage Mode
int8_t menu_3_manual_temperature_mode(int8_t mAh_or_Coulombs ,int8_t celcius_or_kelvin ,uint16_t prescalar_mode, uint16_t prescalarValue, uint16_t alcc_mode)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t LTC2942_mode;
int8_t ack = 0;
LTC2942_mode = LTC2942_MANUAL_TEMPERATURE|prescalar_mode|alcc_mode ; //! Set the control mode of the LTC2942 to manual mode as well as set prescalar and AL#/CC# pin values.
Serial.println();
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_CONTROL_REG, LTC2942_mode); //! Writes the set mode to the LTC2942 control register
int staleData = 0; //! Stale Data Check variable. When set to 1 it indicates that stale data is being read from the voltage, current and temperature registers.
do
{
Serial.print(F("*************************\n\n"));
uint8_t status_code;
uint16_t charge_code, temperature_code;
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_ACCUM_CHARGE_MSB_REG, &charge_code); //! Read MSB and LSB Accumulated Charge Registers for 16 bit charge code
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_TEMPERATURE_MSB_REG, &temperature_code); //! Read MSB and LSB Temperature Registers for 16 bit temperature code
ack |= LTC2942_read(LTC2942_I2C_ADDRESS, LTC2942_STATUS_REG, &status_code); //! Read Status Registers for 8 bit status code
float charge, temperature;
if (mAh_or_Coulombs)
{
charge = LTC2942_code_to_coulombs(charge_code, resistor, prescalarValue); //! Convert charge code to Coulombs if Coulomb units are desired.
Serial.print("Coulombs: ");
Serial.print(charge, 4);
Serial.print(F(" C\n"));
}
else
{
charge = LTC2942_code_to_mAh(charge_code, resistor, prescalarValue); //! Convert charge code to mAh if mAh units are desired.
Serial.print("mAh: ");
Serial.print(charge, 4);
Serial.print(F(" mAh\n"));
}
if (celcius_or_kelvin)
{
temperature = LTC2942_code_to_kelvin_temperature(temperature_code); //! Convert temperature code to Kelvin if Kelvin units are desired.
Serial.print(F("Temperature "));
Serial.print(temperature, 4);
Serial.print(F(" K"));
}
else
{
temperature = LTC2942_code_to_celcius_temperature(temperature_code); //! Convert temperature code to Celcius if Celcius units are desired.
Serial.print(F("Temperature "));
Serial.print(temperature, 4);
Serial.print(F(" C"));
}
if (staleData) Serial.print(F(" ***** Stale Data ******\n"));
else Serial.println("");
checkAlerts(status_code); //! Check status code for Alerts. If an Alert has been set, print out appropriate message in the Serial Prompt
Serial.print(F("m-Main Menu\n\n"));
staleData = 1;
Serial.flush();
delay(AUTOMATIC_MODE_DISPLAY_DELAY);
}
while (!Serial.available() && !(ack));
read_int(); // clears the Serial.available
return(ack);
}
//! Sleep Mode
int8_t menu_4_sleep_mode(int8_t mAh_or_Coulombs ,uint16_t prescalar_mode, uint16_t prescalarValue, uint16_t alcc_mode)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t LTC2942_mode;
int8_t ack = 0;
LTC2942_mode = LTC2942_SLEEP_MODE|prescalar_mode|alcc_mode ; //! Set the control mode of the LTC2942 to sleep mode as well as set prescalar and AL#/CC# pin values.
Serial.println();
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_CONTROL_REG, LTC2942_mode); //! Writes the set mode to the LTC2942 control register
do
{
Serial.print(F("*************************\n\n"));
delay(100);
uint8_t status_code;
uint16_t charge_code;
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_ACCUM_CHARGE_MSB_REG, &charge_code); //! Read MSB and LSB Accumulated Charge Registers for 16 bit charge code
ack |= LTC2942_read(LTC2942_I2C_ADDRESS, LTC2942_STATUS_REG, &status_code); //! Read Status Registers for 8 bit status code
float charge;
if (mAh_or_Coulombs)
{
charge = LTC2942_code_to_coulombs(charge_code, resistor, prescalarValue); //! Convert charge code to Coulombs if Coulomb units are desired.
Serial.print("Coulombs: ");
Serial.print(charge, 4);
Serial.print(F(" C\n"));
}
else
{
charge = LTC2942_code_to_mAh(charge_code, resistor, prescalarValue); //! Convert charge code to mAh if mAh units are desired.
Serial.print("mAh: ");
Serial.print(charge, 4);
Serial.print(F(" mAh\n"));
}
Serial.print(F("Voltage "));
Serial.print(F(" ADC Sleep...\n"));
Serial.print(F("Temperature "));
Serial.print(F(" ADC Sleep...\n"));
Serial.print(F("m-Main Menu\n\n"));
checkAlerts(status_code);
Serial.flush();
delay(AUTOMATIC_MODE_DISPLAY_DELAY);
}
while (!Serial.available() && !(ack));
read_int(); // clears the Serial.available
return(ack);
}
//! Shutdown Mode
int8_t menu_5_shutdown_mode()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_CONTROL_REG, LTC2942_SHUTDOWN_MODE); //! Sets the LTC2942 into shutdown mode
Serial.print("LTC2942 Has Been ShutDown\n");
return(ack);
}
//! Settings Menu
int8_t menu_6_settings(uint8_t *mAh_or_Coulombs, uint8_t *celcius_or_kelvin, uint16_t *prescalar_mode, uint16_t *prescalarValue, uint16_t *alcc_mode)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
int8_t user_command;
do
{
Serial.print(F("*************************\n\n"));
Serial.print(F("1-Set Alert Thresholds\n"));
Serial.print(F("2-Set Prescalar Value\n"));
Serial.print(F("3-Set AL#/CC# Pin State\n"));
Serial.print(F("4-Set Units\n"));
Serial.print(F("m-Main Menu\n\n"));
Serial.print(F("Enter a command: "));
user_command = read_int();
if (user_command == 'm')
Serial.println("m");
else
Serial.println(user_command);
Serial.println();
switch (user_command)
{
case 1:
ack |= menu_6_settings_menu_1_set_alert_thresholds(); //! Settings Menu to set Alert Thresholds
break;
case 2:
ack |= menu_6_settings_menu_2_set_prescalar_values(prescalar_mode, prescalarValue); //! Settings Menu to set Prescalar Values
break;
case 3:
ack |= menu_6_alert_menu_3_set_allcc_state(alcc_mode); //! Settings Menu to set AL#/CC# mode
break;
case 4:
ack |= menu_6_alert_menu_4_set_units(mAh_or_Coulombs, celcius_or_kelvin); //! Settings Menu to set Temperature and Charge Units
break;
default:
if (user_command != 'm')
Serial.println("Incorrect Option");
break;
}
}
while (!((user_command == 'm') || (ack)));
return(ack);
}
//! Alert Threshold Menu
int8_t menu_6_settings_menu_1_set_alert_thresholds()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
int8_t user_command;
do
{
Serial.print(F("*************************\n\n"));
Serial.print(F("1-Set Charge Thresholds\n"));
Serial.print(F("2-Set Voltage Thresholds\n"));
Serial.print(F("3-Set Temperature Thresholds\n"));
Serial.print(F("m-Main Menu\n\n"));
Serial.print(F("Enter a command: "));
user_command = read_int();
if (user_command == 'm')
Serial.println("m");
else
Serial.println(user_command);
Serial.println();
switch (user_command)
{
case 1:
ack |= menu_6_alert_menu_1_set_charge_thresholds(); //! Set Max and Min Charge Thresholds. The ACR charge lsb size changes with respect to the prescalar and sense resistor value. Due to this variability, for the purpose of this demo enter values in hexadecimal.
break;
case 2:
ack |= menu_6_alert_menu_2_set_voltage_thresholds(); //! Set Max and Min Voltage Thresholds. Enter Values in Volts
break;
case 3:
ack |= menu_6_alert_menu_3_set_temperature_thresholds(); //! Set Max and Min Temperature Thresholds. Enter Values in Celcius.
break;
default:
if (user_command != 'm')
Serial.println("Incorrect Option");
break;
}
}
while (!((user_command == 'm') || (ack)));
return(ack);
}
//! Set Charge Threshold Function
int8_t menu_6_alert_menu_1_set_charge_thresholds()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
Serial.print(F("Enter RAW Max Charge Threshold:"));
uint16_t max_charge_threshold;
max_charge_threshold = read_int(); //! Read user entered value
Serial.println(max_charge_threshold);
ack |= LTC2942_write_16_bits(LTC2942_I2C_ADDRESS, LTC2942_CHARGE_THRESH_HIGH_MSB_REG, max_charge_threshold); //! write user entered value to HIGH threshold register
Serial.print(F("Enter RAW Min Charge Threshold:"));
float min_charge_threshold;
min_charge_threshold = read_int(); //! Read user entered value
Serial.println(min_charge_threshold);
ack |= LTC2942_write_16_bits(LTC2942_I2C_ADDRESS, LTC2942_CHARGE_THRESH_LOW_MSB_REG, min_charge_threshold); //! write user entered value to HIGH threshold register
return(ack);
}
//! Set Voltage Thresholds
int8_t menu_6_alert_menu_2_set_voltage_thresholds()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
Serial.print(F("Enter Max Voltage Threshold:"));
float max_voltage_threshold;
max_voltage_threshold = read_float(); //! Read user entered value
Serial.print(max_voltage_threshold, 3);
Serial.println("V");
uint16_t max_voltage_threshold_code_16 =max_voltage_threshold*(0xFFFF)/(LTC2942_FULLSCALE_VOLTAGE);
uint8_t max_voltage_threshold_code = max_voltage_threshold_code_16>>8; //! Convert user entered voltage into adc code.
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_VOLTAGE_THRESH_HIGH_REG, max_voltage_threshold_code); //! Write adc code to HIGH threshold register
Serial.print(F("Enter Min Voltage Threshold:"));
float min_voltage_threshold;
min_voltage_threshold = read_float(); //! Read user entered value
Serial.println(min_voltage_threshold, 3);
Serial.println("V");
uint16_t min_voltage_threshold_code_16 =(min_voltage_threshold*(0xFFFF)/(LTC2942_FULLSCALE_VOLTAGE));
uint8_t min_voltage_threshold_code = min_voltage_threshold_code_16>>8; //! Convert user entered voltage into adc code.
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_VOLTAGE_THRESH_LOW_REG, min_voltage_threshold_code); //! Write adc code to LOW threshold register
return(ack);
}
//! Set Temperature Thresholds
int8_t menu_6_alert_menu_3_set_temperature_thresholds()
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
Serial.print(F("Enter Max Temperature Threshold in Celcius:"));
float max_temperature_threshold;
max_temperature_threshold = read_float(); //! Read user entered value
Serial.print(max_temperature_threshold, 2);
Serial.println("C");
uint16_t max_temperature_threshold_code_16 =((max_temperature_threshold + 273.15)*(0xFFFF)/(LTC2942_FULLSCALE_TEMPERATURE));
uint8_t max_temperature_threshold_code = max_temperature_threshold_code_16>>8; //! Convert user entered temperature into adc code.
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_TEMPERATURE_THRESH_HIGH_REG, max_temperature_threshold_code); //! Write adc code to HIGH threshold register
Serial.print(F("Enter Min Temperature Threshold in Celcius:"));
float min_temperature_threshold;
min_temperature_threshold = read_float(); //! Read user entered value
Serial.print(min_temperature_threshold, 2);
Serial.println("C");
uint16_t min_temperature_threshold_code_16 = ((min_temperature_threshold + 273.15)*(0xFFFF)/(LTC2942_FULLSCALE_TEMPERATURE));
uint8_t min_temperature_threshold_code = min_temperature_threshold_code_16>>8; //! Convert user entered temperature into adc code.
ack |= LTC2942_write_16_bits(LTC2942_I2C_ADDRESS, LTC2942_TEMPERATURE_THRESH_LOW_REG, min_temperature_threshold_code); //! Write adc code to LOW threshold register
return(ack);
}
//! Prescalar Menu
int8_t menu_6_settings_menu_2_set_prescalar_values(uint16_t *prescalar_mode, uint16_t *prescalarValue)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
int8_t user_command;
do
{
Serial.print(F("*************************\n\n"));
Serial.print(F("1-Set Prescalar M = 1\n"));
Serial.print(F("2-Set Prescalar M = 2\n"));
Serial.print(F("3-Set Prescalar M = 4\n"));
Serial.print(F("4-Set Prescalar M = 8\n"));
Serial.print(F("5-Set Prescalar M = 16\n"));
Serial.print(F("6-Set Prescalar M = 32\n"));
Serial.print(F("7-Set Prescalar M = 64\n"));
Serial.print(F("8-Set Prescalar M = 128\n"));
Serial.print(F("m-Main Menu\n\n"));
Serial.print(F("Enter a command: "));
user_command = read_int();
if (user_command == 'm')
Serial.println("m");
else
Serial.println(user_command);
Serial.println();
switch (user_command)
{
case 1:
*prescalar_mode = LTC2942_PRESCALAR_M_1; //! Set Prescalar Value M = 1
*prescalarValue = 1;
Serial.println(F("\nPrescalar Set to 1\n"));
break;
case 2:
*prescalar_mode = LTC2942_PRESCALAR_M_2; //! Set Prescalar Value M = 2
*prescalarValue = 2;
Serial.println(F("\nPrescalar Set to 2\n"));
break;
case 3:
*prescalar_mode = LTC2942_PRESCALAR_M_4; //! Set Prescalar Value M = 4
*prescalarValue = 4;
Serial.println(F("\nPrescalar Set to 4\n"));
break;
case 4:
*prescalar_mode = LTC2942_PRESCALAR_M_8; //! Set Prescalar Value M = 8
*prescalarValue = 8;
Serial.println(F("\nPrescalar Set to 8\n"));
break;
case 5:
*prescalar_mode = LTC2942_PRESCALAR_M_16; //! Set Prescalar Value M = 16
*prescalarValue = 16;
Serial.println(F("\nPrescalar Set to 16\n"));
break;
case 6:
*prescalar_mode = LTC2942_PRESCALAR_M_32; //! Set Prescalar Value M = 32
*prescalarValue = 32;
\
Serial.println(F("\nPrescalar Set to 32\n"));
break;
case 7:
*prescalar_mode = LTC2942_PRESCALAR_M_64; //! Set Prescalar Value M = 64
*prescalarValue = 64;
Serial.println(F("\nPrescalar Set to 64\n"));
break;
case 8:
*prescalar_mode = LTC2942_PRESCALAR_M_128; //! Set Prescalar Value M = 128
*prescalarValue =128;
Serial.println(F("\nPrescalar Set to 128\n"));
default:
if (user_command != 'm')
Serial.println("Incorrect Option");
break;
}
}
while (!((user_command == 'm') || (ack)));
return(ack);
}
//! AL#/CC# Pin Mode Menu
uint8_t menu_6_alert_menu_3_set_allcc_state(uint16_t *alcc_mode)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
int8_t user_command;
do
{
Serial.print(F("*************************\n\n"));
Serial.print(F("1-Enable Alert Mode\n"));
Serial.print(F("2-Enable Charge Complete Mode\n"));
Serial.print(F("3-Disable AL#/CC# Pin\n"));
Serial.print(F("m-Main Menu\n\n"));
Serial.print(F("Enter a command: "));
user_command = read_int();
if (user_command == 'm')
Serial.println("m");
else
Serial.println(user_command);
Serial.println();
switch (user_command)
{
case 1:
*alcc_mode = LTC2942_ALERT_MODE; //! Set AL#/CC# mode to Alert Mode
Serial.println(F("\nAlert Mode Enabled\n"));
break;
case 2:
*alcc_mode = LTC2942_CHARGE_COMPLETE_MODE; //! Set AL#/CC# mode to Charge Complete Mode
Serial.println(F("\nCharge Mode Enabled\n"));
break;
case 3:
*alcc_mode = LTC2942_DISABLE_ALCC_PIN; //! Disable AL#/CC# pin.
Serial.println(F("\nAL#/CC# Pin Disabled\n"));
break;
default:
if (user_command != 'm')
Serial.println("Incorrect Option");
break;
}
}
while (!((user_command == 'm') || (ack)));
return(ack);
}
//! Set Charge and Temperature Units Menu
uint8_t menu_6_alert_menu_4_set_units(uint8_t *mAh_or_Coulombs, uint8_t *celcius_or_kelvin)
//! @return Returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge
{
int8_t ack = 0;
int8_t user_command;
do
{
Serial.print(F("*************************\n\n"));
Serial.print(F("1-Set Charge Units to mAh\n"));
Serial.print(F("2-Set Charge Units to Coulombs\n"));
Serial.print(F("3-Set Temperature Units to Celsius\n"));
Serial.print(F("4-Set Temperature Units to Kelvin\n"));
Serial.print(F("m-Main Menu\n\n"));
Serial.print(F("Enter a command: "));
user_command = read_int();
if (user_command == 'm')
Serial.println("m");
else
Serial.println(user_command);
Serial.println();
switch (user_command)
{
case 1:
*mAh_or_Coulombs = 0;
Serial.println(F("\nCharge Units Set to mAh\n"));
break;
case 2:
*mAh_or_Coulombs = 1;
Serial.println(F("\nCharge Units Set to Coulombs\n"));
break;
case 3:
*celcius_or_kelvin = 0;
Serial.println(F("\nTemperature Units Set to Celcius\n"));
break;
case 4:
*celcius_or_kelvin = 1;
Serial.println(F("\nTemperature Units Set to Kelvin\n"));
break;
default:
if (user_command != 'm')
Serial.println("Incorrect Option");
break;
}
}
while (!((user_command == 'm') || (ack)));
return(ack);
}
//! Checks to see if a bit in a certain position is set.
bool isBitSet(uint8_t value, uint8_t position)
//! @return Returns the state of a bit at "position" in a byte. 1 = Set, 0 = Not Set
{
return((1<<position)&value);
}
//! Check Alerts Function - Checks to see if an alert has been set in the status register. If an alert has been set, it prints out the appropriate message.
void checkAlerts(uint8_t status_code)
//! @return
{
if (isBitSet(status_code,5))
{
Serial.print(F("\n***********************\n"));
Serial.print(F("Alert: "));
Serial.print(F("Charge Over/Under Flow Alert\n"));
Serial.print(F("***********************\n"));
}
if (isBitSet(status_code,4))
{
Serial.print(F("\n***********************\n"));
Serial.print(F("Alert: "));
Serial.print(F("Temperature Alert\n"));
Serial.print(F("***********************\n"));
}
if (isBitSet(status_code,3))
{
Serial.print(F("\n***********************\n"));
Serial.print(F("Alert: "));
Serial.print(F("Charge High Alert\n"));
Serial.print(F("***********************\n"));
}
if (isBitSet(status_code,2))
{
Serial.print(F("\n***********************\n"));
Serial.print(F("Alert: "));
Serial.print(F("Charge Low Alert\n"));
Serial.print(F("***********************\n"));
}
if (isBitSet(status_code,1))
{
Serial.print(F("\n***********************\n"));
Serial.print(F("Alert: "));
Serial.print(F("Voltage Alert\n"));
Serial.print(F("***********************\n"));
}
if (isBitSet(status_code,0))
{
Serial.print(F("\n***********************\n"));
Serial.print(F("Alert: "));
Serial.print(F("UVLO Alert\n"));
Serial.print(F("***********************\n"));
}
}
Download LTC2942 - Linduino Header File
/*!
LTC2942: Battery Gas Gauge with Temperature, Voltage Measurement.
LTC2941: Battery Gas Gauge with I2C Interface.
@verbatim
The LTC®2942 measures battery charge state, battery
voltage and chip temperature in handheld PC and portable
product applications. Its operating range is perfectly suited
for single-cell Li-Ion batteries. A precision coulomb counter
integrates current through a sense resistor between the
battery’s positive terminal and the load or charger. Battery
voltage and on-chip temperature are measured with an
internal 14-bit No Latency ∆∑™ ADC. The three measured
quantities (charge, voltage and temperature) are stored in
internal registers accessible via the onboard SMBus/I2C
interface.
I2C DATA FORMAT (MSB FIRST):
Data Out:
Byte #1 Byte #2 Byte #3
START SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK C7 C6 C5 C4 C3 C2 C1 C0 SACK D7 D6 D5 D4 D3 D2 D1 D0 SACK STOP
Data In:
Byte #1 Byte #2 Byte #3
START SA6 SA5 SA4 SA3 SA2 SA1 SA0 W SACK C7 C6 C5 C4 C3 C2 C1 C0 SACK Repeat Start SA6 SA5 SA4 SA3 SA2 SA1 SA0 R SACK
Byte #4 Byte #5
MSB LSB
D15 D14 D13 D12 D11 D10 D9 D8 MACK D7 D6 D5 D4 D3 D2 D1 D0 MNACK STOP
START : I2C Start
Repeat Start: I2c Repeat Start
STOP : I2C Stop
SAx : I2C Address
SACK : I2C Slave Generated Acknowledge (Active Low)
MACK : I2C Master Generated Acknowledge (Active Low)
MNACK : I2c Master Generated Not Acknowledge
W : I2C Write (0)
R : I2C Read (1)
Cx : Command Code
Dx : Data Bits
X : Don't care
Example Code:
Read charge, current, and voltage.
adc_command = LTC2942_SENSE_MONITOR | LTC2942_AUTOMATIC_MODE; // Builds commands to set LTC2942 to automatic mode
ack |= LTC2942_write(LTC2942_I2C_ADDRESS, LTC2942_CONTROL_REG, adc_command); // Sets the LTC2942 to automatic mode
resistor = .1; // Resistor Value On Demo Board
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_CHARGE_MSB_REG, &charge_code); // Reads the ADC registers that contains charge value
charge = LTC2942_code_to_coulombs(charge_code, resistor, prescalarValue); // Calculates charge from charge code, resistor and prescalar
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_CURRENT_MSB_REG, ¤t_code); // Reads the voltage code across sense resistor
current = LTC2942_code_to_current(current_code, resistor); // Calculates current from current code, resistor value.
ack |= LTC2942_read_16_bits(LTC2942_I2C_ADDRESS, LTC2942_VOLTAGE_MSB_REG, &voltage_code); // Reads voltage voltage code
VIN = LTC2942_VIN_code_to_voltage(voltage_code); // Calculates VIN voltage from VIN code and lsb
@endverbatim
http://www.linear.com/product/LTC2942
http://www.linear.com/product/LTC2941
http://www.linear.com/product/LTC2942#demoboards
http://www.linear.com/product/LTC2941#demoboards
REVISION HISTORY
$Revision: 6595 $
$Date: 2017-02-27 15:04:18 -0800 (Mon, 27 Feb 2017) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
/*! @file
@ingroup LTC2942
Header for LTC2942: Battery Gas Gauge with Temperature, Voltage Measurement
*/
#ifndef LTC2942_H
#define LTC2942_H
#include <Wire.h>
/*!
| LTC2942 I2C Address Assignment | Value |
| :-------------------------------- | :---: |
| LTC2942_I2C_ADDRESS | 0xC8 |
*/
/*! @name LTC2942 I2C Address
@{ */
#define LTC2942_I2C_ADDRESS 0x64
#define LTC2942_I2C_ALERT_RESPONSE 0x0C
//! @}
/*!
| Name | Value |
| :------------------------------------------------ | :---: |
| LTC2942_STATUS_REG | 0x00 |
| LTC2942_CONTROL_REG | 0x01 |
| LTC2942_ACCUM_CHARGE_MSB_REG | 0x02 |
| LTC2942_ACCUM_CHARGE_LSB_REG | 0x03 |
| LTC2942_CHARGE_THRESH_HIGH_MSB_REG | 0x04 |
| LTC2942_CHARGE_THRESH_HIGH_LSB_REG | 0x05 |
| LTC2942_CHARGE_THRESH_LOW_MSB_REG | 0x06 |
| LTC2942_CHARGE_THRESH_LOW_LSB_REG | 0x07 |
| LTC2942_VOLTAGE_MSB_REG | 0x08 |
| LTC2942_VOLTAGE_LSB_REG | 0x09 |
| LTC2942_VOLTAGE_THRESH_HIGH_REG | 0x0A |
| LTC2942_VOLTAGE_THRESH_LOW_REG | 0x0B |
| LTC2942_TEMPERATURE_MSB_REG | 0x0C |
| LTC2942_TEMPERATURE_LSB_REG | 0x0D |
| LTC2942_TEMPERATURE_THRESH_HIGH_REG | 0x0E |
| LTC2942_TEMPERATURE_THRESH_LOW_REG | 0x0F |
*/
/*! @name Registers
@{ */
// Registers
#define LTC2942_STATUS_REG 0x00
#define LTC2942_CONTROL_REG 0x01
#define LTC2942_ACCUM_CHARGE_MSB_REG 0x02
#define LTC2942_ACCUM_CHARGE_LSB_REG 0x03
#define LTC2942_CHARGE_THRESH_HIGH_MSB_REG 0x04
#define LTC2942_CHARGE_THRESH_HIGH_LSB_REG 0x05
#define LTC2942_CHARGE_THRESH_LOW_MSB_REG 0x06
#define LTC2942_CHARGE_THRESH_LOW_LSB_REG 0x07
#define LTC2942_VOLTAGE_MSB_REG 0x08
#define LTC2942_VOLTAGE_LSB_REG 0x09
#define LTC2942_VOLTAGE_THRESH_HIGH_REG 0x0A
#define LTC2942_VOLTAGE_THRESH_LOW_REG 0x0B
#define LTC2942_TEMPERATURE_MSB_REG 0x0C
#define LTC2942_TEMPERATURE_LSB_REG 0x0D
#define LTC2942_TEMPERATURE_THRESH_HIGH_REG 0x0E
#define LTC2942_TEMPERATURE_THRESH_LOW_REG 0x0F
//! @}
/*!
| Command Codes | Value |
| :-------------------------------------------- | :-------: |
| LTC2942_AUTOMATIC_MODE | 0xC0 |
| LTC2942_MANUAL_VOLTAGE | 0x80 |
| LTC2942_MANUAL_TEMPERATURE | 0x40 |
| LTC2942_SLEEP_MODE | 0x00 |
| LTC2942_PRESCALAR_M_1 | 0x00 |
| LTC2942_PRESCALAR_M_2 | 0x08 |
| LTC2942_PRESCALAR_M_4 | 0x10 |
| LTC2942_PRESCALAR_M_8 | 0x18 |
| LTC2942_PRESCALAR_M_16 | 0x20 |
| LTC2942_PRESCALAR_M_32 | 0x28 |
| LTC2942_PRESCALAR_M_64 | 0x30 |
| LTC2942_PRESCALAR_M_128 | 0x31 |
| LTC2942_ALERT_MODE | 0x04 |
| LTC2942_CHARGE_COMPLETE_MODE | 0x02 |
| LTC2942_DISABLE_ALCC_PIN | 0x00 |
| LTC2942_SHUTDOWN_MODE | 0x01 |
*/
/*! @name Command Codes
@{ */
// Command Codes
#define LTC2942_AUTOMATIC_MODE 0xC0
#define LTC2942_MANUAL_VOLTAGE 0x80
#define LTC2942_MANUAL_TEMPERATURE 0x40
#define LTC2942_SLEEP_MODE 0x00
#define LTC2942_PRESCALAR_M_1 0x00
#define LTC2942_PRESCALAR_M_2 0x08
#define LTC2942_PRESCALAR_M_4 0x10
#define LTC2942_PRESCALAR_M_8 0x18
#define LTC2942_PRESCALAR_M_16 0x20
#define LTC2942_PRESCALAR_M_32 0x28
#define LTC2942_PRESCALAR_M_64 0x30
#define LTC2942_PRESCALAR_M_128 0x38
#define LTC2942_ALERT_MODE 0x04
#define LTC2942_CHARGE_COMPLETE_MODE 0x02
#define LTC2942_DISABLE_ALCC_PIN 0x00
#define LTC2942_SHUTDOWN_MODE 0x01
//! @}
/*!
| Conversion Constants | Value |
| :------------------------------------------------ | :------: |
| LTC2942_CHARGE_lsb | 0.085 mAh|
| LTC2942_VOLTAGE_lsb | 366.2 uV|
| LTC2942_TEMPERATURE_lsb | 0.586 C|
| LTC2942_FULLSCALE_VOLTAGE | 6 V|
| LTC2942_FULLSCALE_TEMPERATURE | 600 K|
*/
/*! @name Conversion Constants
@{ */
const float LTC2942_CHARGE_lsb = 0.085E-3;
const float LTC2942_VOLTAGE_lsb = .3662E-3;
const float LTC2942_TEMPERATURE_lsb = 0.25;
const float LTC2942_FULLSCALE_VOLTAGE = 6;
const float LTC2942_FULLSCALE_TEMPERATURE = 600;
//! @}
//! @}
//! Write an 8-bit code to the LTC2942.
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2942_write(uint8_t i2c_address, //!< Register address for the LTC2942
uint8_t adc_command, //!< The "command byte" for the LTC2942
uint8_t code //!< Value that will be written to the register.
);
//! Write a 16-bit code to the LTC2942.
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2942_write_16_bits(uint8_t i2c_address, //!< Register address for the LTC2942
uint8_t adc_command, //!< The "command byte" for the LTC2942
uint16_t code //!< Value that will be written to the register.
);
//! Reads an 8-bit adc_code from LTC2942
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2942_read(uint8_t i2c_address, //!< Register address for the LTC2942
uint8_t adc_command, //!< The "command byte" for the LTC2942
uint8_t *adc_code //!< Value that will be read from the register.
);
//! Reads a 16-bit adc_code from LTC2942
//! @return The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
int8_t LTC2942_read_16_bits(uint8_t i2c_address, //!< Register address for the LTC2942
uint8_t adc_command, //!< The "command byte" for the LTC2942
uint16_t *adc_code //!< Value that will be read from the register.
);
//! Calculate the LTC2942 charge in Coulombs
//! @return Returns the Coulombs of charge in the ACR register.
float LTC2942_code_to_coulombs(uint16_t adc_code, //!< The RAW ADC value
float resistor, //!< The sense resistor value
uint16_t prescalar //!< The prescalar value
);
//! Calculate the LTC2942 charge in mAh
//! @return Returns the Coulombs of charge in the ACR register.
float LTC2942_code_to_mAh(uint16_t adc_code, //!< The RAW ADC value
float resistor, //!< The sense resistor value
uint16_t prescalar //!< The prescalar value
);
//! Calculate the LTC2942 SENSE+ voltage
//! @return Returns the SENSE+ Voltage in Volts
float LTC2942_code_to_voltage(uint16_t adc_code //!< The RAW ADC value
);
//! Calculate the LTC2942 temperature
//! @return Returns the temperature in Kelvin
float LTC2942_code_to_kelvin_temperature(uint16_t adc_code //!< The RAW ADC value
);
//! Calculate the LTC2942 temperature
//! @return Returns the temperature in Celcius
float LTC2942_code_to_celcius_temperature(uint16_t adc_code //!< The RAW ADC value
);
#endif // LTC2942_H
Download LTC2942 - Linduino CPP File
/*!
LTC2942: Battery Gas Gauge with Temperature, Voltage Measurement.
LTC2941: Battery Gas Gauge with I2C Interface
@verbatim
@endverbatim
http://www.linear.com/product/LTC2942
http://www.linear.com/product/LTC2941
http://www.linear.com/product/LTC2942#demoboards
http://www.linear.com/product/LTC2941#demoboards
REVISION HISTORY
$Revision: 6595 $
$Date: 2017-02-27 15:04:18 -0800 (Mon, 27 Feb 2017) $
Copyright (c) 2013, Linear Technology Corp.(LTC)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of Linear Technology Corp.
The Linear Technology Linduino is not affiliated with the official Arduino team.
However, the Linduino is only possible because of the Arduino team's commitment
to the open-source community. Please, visit http://www.arduino.cc and
http://store.arduino.cc , and consider a purchase that will help fund their
ongoing work.
*/
//! @ingroup Power_Monitors
//! @{
//! @defgroup LTC2942 LTC2942: Battery Gas Gauge with Temperature, Voltage Measurement
//! @}
/*! @file
@ingroup LTC2942
Library for LTC2942 Battery Gas Gauge with Temperature, Voltage Measurement
*/
#include <Arduino.h>
#include <stdint.h>
#include "Linduino.h"
#include "LT_I2C.h"
#include "LTC2942.h"
#include <Wire.h>
// Write an 8-bit code to the LTC2942.
int8_t LTC2942_write(uint8_t i2c_address, uint8_t adc_command, uint8_t code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
int32_t ack;
ack = i2c_write_byte_data(i2c_address, adc_command, code);
return(ack);
}
// Write a 16-bit code to the LTC2942.
int8_t LTC2942_write_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
int8_t ack;
ack = i2c_write_word_data(i2c_address, adc_command, code);
return(ack);
}
// Reads an 8-bit adc_code from LTC2942
int8_t LTC2942_read(uint8_t i2c_address, uint8_t adc_command, uint8_t *adc_code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
int32_t ack;
ack = i2c_read_byte_data(i2c_address, adc_command, adc_code);
return(ack);
}
// Reads a 16-bit adc_code from LTC2942
int8_t LTC2942_read_16_bits(uint8_t i2c_address, uint8_t adc_command, uint16_t *adc_code)
// The function returns the state of the acknowledge bit after the I2C address write. 0=acknowledge, 1=no acknowledge.
{
int32_t ack;
ack = i2c_read_word_data(i2c_address, adc_command, adc_code);
return(ack);
}
float LTC2942_code_to_coulombs(uint16_t adc_code, float resistor, uint16_t prescalar)
// The function converts the 16-bit RAW adc_code to Coulombs
{
float coulomb_charge;
coulomb_charge = 1000*(float)(adc_code*LTC2942_CHARGE_lsb*prescalar*50E-3)/(resistor*128);
coulomb_charge = coulomb_charge*3.6f;
return(coulomb_charge);
}
float LTC2942_code_to_mAh(uint16_t adc_code, float resistor, uint16_t prescalar )
// The function converts the 16-bit RAW adc_code to mAh
{
float mAh_charge;
mAh_charge = 1000*(float)(adc_code*LTC2942_CHARGE_lsb*prescalar*50E-3)/(resistor*128);
return(mAh_charge);
}
float LTC2942_code_to_voltage(uint16_t adc_code)
// The function converts the 16-bit RAW adc_code to Volts
{
float voltage;
voltage = ((float)adc_code/(65535))*LTC2942_FULLSCALE_VOLTAGE;
return(voltage);
}
float LTC2942_code_to_kelvin_temperature(uint16_t adc_code)
// The function converts the 16-bit RAW adc_code to Kelvin
{
float temperature;
temperature = adc_code*((float)(LTC2942_FULLSCALE_TEMPERATURE)/65535);
return(temperature);
}
float LTC2942_code_to_celcius_temperature(uint16_t adc_code)
// The function converts the 16-bit RAW adc_code to Celcius
{
float temperature;
temperature = adc_code*((float)(LTC2942_FULLSCALE_TEMPERATURE)/65535) - 273.15;
return(temperature);
}
// Used to set and clear bits in a control register. bits_to_set will be bitwise OR'd with the register.
// bits_to_clear will be inverted and bitwise AND'd with the register so that every location with a 1 will result in a 0 in the register.
int8_t LTC2942_register_set_clear_bits(uint8_t i2c_address, uint8_t register_address, uint8_t bits_to_set, uint8_t bits_to_clear)
{
uint8_t register_data;
int8_t ack = 0;
ack |= LTC2942_read(i2c_address, register_address, ®ister_data);
register_data = register_data & (~bits_to_clear);
register_data = register_data | bits_to_set;
ack |= LTC2942_write(i2c_address, register_address, register_data);
return(ack);
}
Technical Support
- For immediate technical assistance, contact your local sales office or distributor or call 1-800-4-LINEAR (US customers only) or 408-432-1900.
- For less urgent requests, please complete our Technical Support Request Form. Please allow 2-3 business days for reply.
