Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 187 additions & 20 deletions Adafruit_INA219.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,13 @@ void Adafruit_INA219::wireReadRegister(uint8_t reg, uint16_t *value)
each unit of power corresponds to 2mW. Counter overflow
occurs at 3.2A.

@param triggered : a boolean to configure INA219 in triggered (true)
or continuous (false) mode. Optional with default value false

@note These calculations assume a 0.1 ohm resistor is present
*/
/**************************************************************************/
void Adafruit_INA219::setCalibration_32V_2A(void)
void Adafruit_INA219::setCalibration_32V_2A(bool triggered)
{
// By default we use a pretty huge range for the input voltage,
// which probably isn't the most appropriate choice for system
Expand Down Expand Up @@ -165,11 +168,22 @@ void Adafruit_INA219::setCalibration_32V_2A(void)
wireWriteRegister(INA219_REG_CALIBRATION, ina219_calValue);

// Set Config register to take into account the settings above
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
uint16_t config;

if (triggered) {
config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_128S_69MS |
INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED;
} else {
config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
}

wireWriteRegister(INA219_REG_CONFIG, config);
}

Expand All @@ -180,10 +194,13 @@ void Adafruit_INA219::setCalibration_32V_2A(void)
unit of power corresponds to 800�W. Counter overflow occurs at
1.3A.

@param triggered : a boolean to configure INA219 in triggered (true)
or continuous (false) mode. Optional with default value false

@note These calculations assume a 0.1 ohm resistor is present
*/
/**************************************************************************/
void Adafruit_INA219::setCalibration_32V_1A(void)
void Adafruit_INA219::setCalibration_32V_1A(bool triggered)
{
// By default we use a pretty huge range for the input voltage,
// which probably isn't the most appropriate choice for system
Expand Down Expand Up @@ -258,22 +275,38 @@ void Adafruit_INA219::setCalibration_32V_1A(void)
wireWriteRegister(INA219_REG_CALIBRATION, ina219_calValue);

// Set Config register to take into account the settings above
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
uint16_t config;

if (triggered) {
config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_128S_69MS |
INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED;
} else {
config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_8_320MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
}

wireWriteRegister(INA219_REG_CONFIG, config);
}

/**************************************************************************/
/*!
@brief set device to alibration which uses the highest precision for
current measurement (0.1mA), at the expense of
@brief set device to calibration which uses the highest precision for
current measurement (0.05mA), at the expense of
only supporting 16V at 400mA max.

@param triggered : a boolean to configure INA219 in triggered (true)
or continuous (false) mode. Optional with default value false

@note These calculations assume a 0.1 ohm resistor is present
*/
/**************************************************************************/
void Adafruit_INA219::setCalibration_16V_400mA(void) {
void Adafruit_INA219::setCalibration_16V_400mA(bool triggered) {

// Calibration which uses the highest precision for
// current measurement (0.1mA), at the expense of
Expand Down Expand Up @@ -349,11 +382,125 @@ void Adafruit_INA219::setCalibration_16V_400mA(void) {
wireWriteRegister(INA219_REG_CALIBRATION, ina219_calValue);

// Set Config register to take into account the settings above
uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
uint16_t config;

if (triggered) {
config = INA219_CONFIG_BVOLTAGERANGE_16V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_128S_69MS |
INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED;
} else {
config = INA219_CONFIG_BVOLTAGERANGE_16V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
}
wireWriteRegister(INA219_REG_CONFIG, config);
}

/**************************************************************************/
/*!
@brief set device to calibration which uses the highest precision for
current measurement (0.1mA), Gain 1 and 32V max bus voltage

@param triggered : a boolean to configure INA219 in triggered (true)
or continuous (false) mode. Optional with default value false

@note These calculations assume a 0.1 ohm resistor is present
*/
/**************************************************************************/
void Adafruit_INA219::setCalibration_32V_400mA(bool triggered) {

// Calibration which uses the highest precision for
// current measurement (0.1mA)

// VBUS_MAX = 32V
// VSHUNT_MAX = 0.04 (Assumes Gain 1, 40mV)
// RSHUNT = 0.1 (Resistor value in ohms)

// 1. Determine max possible current
// MaxPossible_I = VSHUNT_MAX / RSHUNT
// MaxPossible_I = 0.4A

// 2. Determine max expected current
// MaxExpected_I = 0.4A

// 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)
// MinimumLSB = MaxExpected_I/32767
// MinimumLSB = 0.0000122 (12uA per bit)
// MaximumLSB = MaxExpected_I/4096
// MaximumLSB = 0.0000977 (98uA per bit)

// 4. Choose an LSB between the min and max values
// (Preferrably a roundish number close to MinLSB)
// CurrentLSB = 0.00005 (50uA per bit)

// 5. Compute the calibration register
// Cal = trunc (0.04096 / (Current_LSB * RSHUNT))
// Cal = 8192 (0x2000)

ina219_calValue = 8192;

// 6. Calculate the power LSB
// PowerLSB = 20 * CurrentLSB
// PowerLSB = 0.001 (1mW per bit)

// 7. Compute the maximum current and shunt voltage values before overflow
//
// Max_Current = Current_LSB * 32767
// Max_Current = 1.63835A before overflow
//
// If Max_Current > Max_Possible_I then
// Max_Current_Before_Overflow = MaxPossible_I
// Else
// Max_Current_Before_Overflow = Max_Current
// End If
//
// Max_Current_Before_Overflow = MaxPossible_I
// Max_Current_Before_Overflow = 0.4
//
// Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT
// Max_ShuntVoltage = 0.04V
//
// If Max_ShuntVoltage >= VSHUNT_MAX
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
// Else
// Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage
// End If
//
// Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX
// Max_ShuntVoltage_Before_Overflow = 0.04V

// 8. Compute the Maximum Power
// MaximumPower = Max_Current_Before_Overflow * VBUS_MAX
// MaximumPower = 0.4 * 32V
// MaximumPower = 12.8W

// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 20; // Current LSB = 50uA per bit (1000/50 = 20)
ina219_powerMultiplier_mW = 1.0f; // Power LSB = 1mW per bit

// Set Calibration register to 'Cal' calculated above
wireWriteRegister(INA219_REG_CALIBRATION, ina219_calValue);

// Set Config register to take into account the settings above
uint16_t config;

if (triggered) {
config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_128S_69MS |
INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED;
} else {
config = INA219_CONFIG_BVOLTAGERANGE_32V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
}
wireWriteRegister(INA219_REG_CONFIG, config);
}

Expand Down Expand Up @@ -517,3 +664,23 @@ float Adafruit_INA219::getPower_mW() {
valueDec *= ina219_powerMultiplier_mW;
return valueDec;
}

/**************************************************************************/
/*!
@brief Enter the Power Down mode
using 1 uA instead of 1 mA current in continous mode.
Just call your calibration routine to turn it on again
@return void

*/
void Adafruit_INA219::enterPowerSave() {

uint16_t config = INA219_CONFIG_BVOLTAGERANGE_16V |
INA219_CONFIG_GAIN_1_40MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_POWERDOWN;

wireWriteRegister(INA219_REG_CONFIG, config);

}
8 changes: 5 additions & 3 deletions Adafruit_INA219.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,15 @@ class Adafruit_INA219{
Adafruit_INA219(uint8_t addr = INA219_ADDRESS);
void begin(void);
void begin(TwoWire *theWire);
void setCalibration_32V_2A(void);
void setCalibration_32V_1A(void);
void setCalibration_16V_400mA(void);
void setCalibration_32V_2A(bool triggered = false);
void setCalibration_32V_1A(bool triggered = false);
void setCalibration_16V_400mA(bool triggered = false);
void setCalibration_32V_400mA(bool triggered = false);
float getBusVoltage_V(void);
float getShuntVoltage_mV(void);
float getCurrent_mA(void);
float getPower_mW(void);
void enterPowerSave(void);

private:
TwoWire *_i2c;
Expand Down
66 changes: 66 additions & 0 deletions examples/getcurrent_asynchronous/getcurrent_asynchronous.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/* The difference with getcurrent example is that
* INA219 will not be constantly measuring values but only when triggered by calling the configuration function
* hence it will be measuring for 69 ms every 2 seconds (delay(200) + delay(1800) in this example)
* During the 1800 ms timelap the INA219 is put to power dowm using enterPowerSave()
* It would be particularly helpfull if you put the MCU in sleep mode during this period so both MCU and INA219 would consumme close to 0.
*/

#include <Wire.h>
#include <Adafruit_INA219.h>

Adafruit_INA219 ina219;


void setup(void)
{
Serial.begin(115200);
while (!Serial) {
// will pause Zero, Leonardo, etc until serial console opens
delay(1);
}

uint32_t currentFrequency;

Serial.println("Hello!");

// Initialize the INA219.
// By default the initialization will use the largest range (32V, 2A). However
// you can call a setCalibration function to change this range (see comments).
ina219.begin();

Serial.println("Measuring voltage and current with INA219 ...");
}

void loop(void)
{
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float power_mW = 0;

// Configuring the INA (in trigger mode) will trigger measurement. Use the appropriate calibration function
ina219.setCalibration_32V_2A(true);
//ina219.setCalibration_32V_1A(true);
//ina219.setCalibration_16V_400mA(true);

// Some time to do the measurement (more than 69 ms)
delay(200);

shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage + (shuntvoltage / 1000);

Serial.print("Bus Voltage: "); Serial.print(busvoltage); Serial.println(" V");
Serial.print("Shunt Voltage: "); Serial.print(shuntvoltage); Serial.println(" mV");
Serial.print("Load Voltage: "); Serial.print(loadvoltage); Serial.println(" V");
Serial.print("Current: "); Serial.print(current_mA); Serial.println(" mA");
Serial.print("Power: "); Serial.print(power_mW); Serial.println(" mW");
Serial.println("");

// Now INA219 is sleeping, using a couple of uA instead of 1mA
ina219.enterPowerSave();
delay(1800);
}