Are you sure that the value in decimal of your calibration_register is equal to 5,120,000?
Could you please add one more public method in the ina219 .h and .cpp files?
- Added calibrationRegisterValue() Method in .h file:
class Adafruit_INA219 {
public:
Adafruit_INA219(uint8_t addr = INA219_ADDRESS);
~Adafruit_INA219();
bool begin(TwoWire *theWire = &Wire);
void setCalibration_32V_2A();
void setCalibration_32V_1A();
void setCalibration_16V_400mA();
float getBusVoltage_V();
float getShuntVoltage_mV();
float getCurrent_mA();
float getPower_mW();
void powerSave(bool on);
bool success();
int16_t publicGetBusVoltageRaw();
int16_t publicGetShuntVoltageRaw();
int16_t publicGetCurrentRaw();
int16_t publicGetPowerRaw();
uint16_t calibrationRegisterValue();
private:
Adafruit_I2CDevice *i2c_dev = NULL;
bool _success;
uint8_t ina219_i2caddr = -1;
uint32_t ina219_calValue;
// The following multipliers are used to convert raw current and power
// values to mA and mW, taking into account the current config settings
uint32_t ina219_currentDivider_mA;
float ina219_powerMultiplier_mW;
void init();
void customInit();
int16_t getBusVoltage_raw();
int16_t getShuntVoltage_raw();
int16_t getCurrent_raw();
int16_t getPower_raw();
};
- At the very end of your .cpp file add this
uint16_t Adafruit_INA219::calibrationRegisterValue(){
uint16_t value;
Adafruit_BusIO_Register calibrationRegister = Adafruit_BusIO_Register(i2c_dev, INA219_REG_CALIBRATION, 2, MSBFIRST);
_success = calibrationRegister.read(&value);
return value;
}
And you can try with this code to see the calibration_register value:
#include <Wire.h>
#include <Adafruit_INA219.h>
Adafruit_INA219 ina219;
uint16_t busVoltageRaw;
uint16_t shuntVoltageRaw;
uint16_t currentRaw;
uint16_t powerRaw;
uint16_t calibrationRegister;
char s1[10];
char s2[10];
char s3[10];
char s4[10];
char s5[20];
void setup(void)
{
Serial.begin(115200);
while (!Serial) {
// will pause Zero, Leonardo, etc until serial console opens
delay(1);
}
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).
if (! ina219.begin()) {
Serial.println("Failed to find INA219 chip");
while (1) { delay(10); }
}
// To use a slightly lower 32V, 1A range (higher precision on amps):
//ina219.setCalibration_32V_1A();
// Or to use a lower 16V, 400mA range (higher precision on volts and amps):
//ina219.setCalibration_16V_400mA();
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;
calibrationRegister = ina219.calibrationRegisterValue();
shuntvoltage = ina219.getShuntVoltage_mV();
busvoltage = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
power_mW = ina219.getPower_mW();
loadvoltage = busvoltage - (shuntvoltage / 1000);
busVoltageRaw = ina219.publicGetBusVoltageRaw();
shuntVoltageRaw = ina219.publicGetShuntVoltageRaw();
currentRaw = ina219.publicGetCurrentRaw();
powerRaw = ina219.publicGetPowerRaw();
sprintf(s1, "%04X", busVoltageRaw);
sprintf(s2, "%04X", shuntVoltageRaw);
sprintf(s3, "%04X", currentRaw);
sprintf(s4, "%04X", powerRaw);
sprintf(s5, "%04X", calibrationRegister);
Serial.println("********************************************************************");
Serial.print("Calibration Register Value: 0x"); Serial.println(s5);
Serial.print("Bus Voltage register: 0x"); Serial.println(s1);
Serial.print("Shunt Voltage register: 0x"); Serial.println(s2);
Serial.print("Current register: 0x"); Serial.println(s3);
Serial.print("Power register: 0x"); Serial.println(s4);
Serial.println("");
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("");
delay(2000);
}
My output is (with Vbus = 2.76, RL = 39 Ohms and Rshunt= 100mOhms):
You can se the value of the cal_register which is 0x1A36 = 6710 in decimal as I mentioned in #post7
I was asking about the value stored in your calibration_register because the INA219's registers are 16-bit length and the maximum value you can store in the register is maxValue = 2^16 = 65536 (0-65535).
If you want to measure a maxCurrent of 3.5A with a Rshunt of 10mOhms then:
Current_LSB = maximum_expected_current/2^15
= 3.5A/2^15
= 106.8115234uA (per bit)
The value of the cal_register must be:
Cal = trunc(0.04096/(Current_LSB * Rshunt))
= trunc( 0.04096/(106.8115234uA * 10mOhm)
= 38347 (and NOT 5,120,000)
What is difference between max possible current and max expected current ?
I honestly don't know how they came to that conclusion that MaxExpected_I = 2.0A, sorry
Oh, and since you are modifying the library, it is recommended that you modify the getCurrent_mA() method to (yes, it is a hardcoded way but...):
float Adafruit_INA219::getCurrent_mA() {
int16_t valueDec = getCurrent_raw();
float Current_LSB = 3.5/pow(2,15);
float current = valueDec * Current_LSB * 1000.0;
return current;
}
//In this case, 3.5/pow(2,15) is your Current_LSB Value. here I'm assuming
// you didn't round that value.
// 3.5 is the value of your max current you want to measure
and the getPower_mW() method:
float Adafruit_INA219::getPower_mW() {
uint16_t powerRaw = getPower_raw();
float Current_LSB = 3.5/pow(2,15);
float powerLSB = 20.0 * Current_LSB;
float power = powerRaw * powerLSB * 1000.0;
return power;
}