INA219 shunt resistor change to 0.01 ohm
Moderators: grovkillen, Stuntteam, TD-er
INA219 shunt resistor change to 0.01 ohm
Hi I have changed the adafruit INA219 board shunt resistor to 0.01 ohm (measuring solar panels that are rated max current 4A) . I am using build 148 on NODE mcu and now I get value of 1.040 volt when measuring approx 12v. Do I need to make some changes to ina219 plugin or can it be corrected by the " device formula" ??
Re: INA219 shunt resistor change to 0.01 ohm
Check the adafruit documentation, I think you can do either if you like. Would be nice if you modified the plugin to have a drop down for this....
Re: INA219 shunt resistor change to 0.01 ohm
Hi,
I modified some time ago INA219 plugin to be able to measure 16V and 30A with 2.5mohms external shunt and is working properly.
Below is the code I added in the plugin.
For 1 mohm you should follow the TI instructions how to calculate the calibration parameters and insert them in the plugin...
//**************************************************************************/
// Configures to INA219 to be able to measure up to 16V and 30A
//**************************************************************************/
void Plugin_027_setCalibration_16V_30A(void) {
ina219_calValue = 16384;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 1; // Current LSB = 1mA per bit (1/1 = 1)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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_2_80MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Setups the HW (defaults to 16V and 30A with 2.5mohms shunt for calibration values)
//**************************************************************************/
void Plugin_027_begin(void) {
// Plugin_027_INA219_address = Plugin_027_INA219_address; // INA219_ADDRESS;
ina219_currentDivider_mA = 1;
// Set chip to large range config values to start
Plugin_027_setCalibration_16V_30A();
}
I modified some time ago INA219 plugin to be able to measure 16V and 30A with 2.5mohms external shunt and is working properly.
Below is the code I added in the plugin.
For 1 mohm you should follow the TI instructions how to calculate the calibration parameters and insert them in the plugin...
//**************************************************************************/
// Configures to INA219 to be able to measure up to 16V and 30A
//**************************************************************************/
void Plugin_027_setCalibration_16V_30A(void) {
ina219_calValue = 16384;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 1; // Current LSB = 1mA per bit (1/1 = 1)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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_2_80MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Setups the HW (defaults to 16V and 30A with 2.5mohms shunt for calibration values)
//**************************************************************************/
void Plugin_027_begin(void) {
// Plugin_027_INA219_address = Plugin_027_INA219_address; // INA219_ADDRESS;
ina219_currentDivider_mA = 1;
// Set chip to large range config values to start
Plugin_027_setCalibration_16V_30A();
}
Re: INA219 shunt resistor change to 0.01 ohm
Thank you StefanD I will try to modified the plugin or change shunt resistor to 0.025ohm and use your modified example.
Re: INA219 shunt resistor change to 0.01 ohm
Hi,
Cant get the INA219 with modified 2.5mohms shunt resistor to work. I did use StefanD modified config and compiled new firmware to my NodeMCU unit. It shows 32.76 volts even when no (out side) voltage is connected to the INA219 unit. Any one any Idea what I am doing wrong or any suggestions how to get it to work?
Cant get the INA219 with modified 2.5mohms shunt resistor to work. I did use StefanD modified config and compiled new firmware to my NodeMCU unit. It shows 32.76 volts even when no (out side) voltage is connected to the INA219 unit. Any one any Idea what I am doing wrong or any suggestions how to get it to work?
- Attachments
-
- INA219 i2c scan.JPG (24.05 KiB) Viewed 23592 times
-
- INA219 device.JPG (44.99 KiB) Viewed 23592 times
Re: INA219 shunt resistor change to 0.01 ohm
Hi,
can you check if the plugin you load is the same like the one below?
//#######################################################################################################
//######################### Plugin 027: INA219 DC Voltage/Current sensor ################################
//#######################################################################################################
#define PLUGIN_027
#define PLUGIN_ID_027 27
#define PLUGIN_NAME_027 "Voltage & Current (DC) - INA219"
#define PLUGIN_VALUENAME1_027 "Voltage"
uint8_t Plugin_027_INA219_address = 0x40; // 0x40 /0x41 A0/0x44 A1/0x45 A0 and A1
//boolean Plugin_027_init = false;
#define INA219_READ (0x01)
#define INA219_REG_CONFIG (0x00)
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
#define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
#define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
#define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
#define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
#define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097
#define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
#define INA219_CONFIG_MODE_POWERDOWN (0x0000)
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
#define INA219_CONFIG_MODE_ADCOFF (0x0004)
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
#define INA219_REG_SHUNTVOLTAGE (0x01)
#define INA219_REG_BUSVOLTAGE (0x02)
#define INA219_REG_POWER (0x03)
#define INA219_REG_CURRENT (0x04)
#define INA219_REG_CALIBRATION (0x05)
uint8_t ina219_i2caddr;
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;
boolean Plugin_027(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_027;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].SendDataOption = false;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_027);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_027));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[3];
options[0] = F("Voltage");
options[1] = F("Current");
options[2] = F("Power");
int optionValues[3];
optionValues[0] = 0;
optionValues[1] = 1;
optionValues[2] = 2;
string += F("<TR><TD>Report:<TD><select name='plugin_026_value'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options2[4];
options2[0] = F("0x40");
options2[1] = F("0x41 -> A0");
options2[2] = F("0x44 -> A1");
options2[3] = F("0x45 -> A0+A1");
uint8_t optionValues2[4];
optionValues2[0] = 0x40;
optionValues2[1] = 0x41;
optionValues2[2] = 0x44;
optionValues2[3] = 0x45;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_027_adr'>");
for (byte x = 0; x < 4; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg("plugin_026_value");
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String plugin2 = WebServer.arg("plugin_027_adr");
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
// Plugin_027_init = false; // Force device setup next time??
success = true;
break;
}
case PLUGIN_INIT:
{
// boolean Plugin_027_init = true; // Force device setup??
Plugin_027_INA219_address = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
Plugin_027_begin();
success = true;
break;
}
case PLUGIN_READ:
{
// shuntvoltage = Plugin_027_getShuntVoltage_mV();
// busvoltage = Plugin_027_getBusVoltage_V();
// current_mA = Plugin_027_getCurrent_mA();
// loadvoltage = Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000);
ina219_i2caddr = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
Serial.println(ina219_i2caddr);
float value=0;
switch(Settings.TaskDevicePluginConfig[event->TaskIndex][0])
{
case 0:
{
value = Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000);
UserVar[event->BaseVarIndex] = value;
String log = F("INA 0x");
log += String(ina219_i2caddr,HEX);
log += F(" : Voltage: ");
log += value;
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}
case 1:
{
value = Plugin_027_getCurrent_mA()/1000;
UserVar[event->BaseVarIndex] = value;
String log = F("INA 0x");
log += String(ina219_i2caddr,HEX);
log += F(" : Current: ");
log += value;
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}
case 2:
{
value = (Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000)) * Plugin_027_getCurrent_mA() / 1000;
UserVar[event->BaseVarIndex] = value;
String log = F("INA 0x");
log += String(ina219_i2caddr,HEX);
log += F(" : Power: ");
log += value;
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}
}
}
}
return success;
}
//**************************************************************************/
// Sends a single command byte over I2C
//**************************************************************************/
void Plugin_027_wireWriteRegister (uint8_t reg, uint16_t value)
{
Wire.beginTransmission(Plugin_027_INA219_address);
Wire.write(reg); // Register
Wire.write((value >> 8) & 0xFF); // Upper 8-bits
Wire.write(value & 0xFF); // Lower 8-bits
Wire.endTransmission();
}
//**************************************************************************/
// Reads a 16 bit values over I2C
//**************************************************************************/
void Plugin_027_wireReadRegister(uint8_t reg, uint16_t *value)
{
Wire.beginTransmission(Plugin_027_INA219_address);
Wire.write(reg); // Register
Wire.endTransmission();
delay(1); // Max 12-bit conversion time is 586us per sample
Wire.requestFrom(Plugin_027_INA219_address, (uint8_t)2);
// Shift values to create properly formed integer
*value = ((Wire.read() << 8) | Wire.read());
}
//**************************************************************************/
// Configures to INA219 to be able to measure up to 32V and 2A
/**************************************************************************/
void Plugin_027_setCalibration_32V_2A(void)
{
ina219_calValue = 4027;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 10; // Current LSB = 100uA per bit (1000/100 = 10)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Configures to INA219 to be able to measure up to 32V and 1A
//**************************************************************************/
void Plugin_027_setCalibration_32V_1A(void)
{
ina219_calValue = 10240;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 25; // Current LSB = 40uA per bit (1000/40 = 25)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Configures to INA219 to be able to measure up to 16V and 30A
//**************************************************************************/
void Plugin_027_setCalibration_16V_30A(void) {
ina219_calValue = 16384;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 1; // Current LSB = 1mA per bit (1/1 = 1)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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_2_80MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Setups the HW (defaults to 16V and 30A with 2.5mohms shunt for calibration values)
//**************************************************************************/
void Plugin_027_begin(void) {
// Plugin_027_INA219_address = Plugin_027_INA219_address; // INA219_ADDRESS;
ina219_currentDivider_mA = 1;
// Set chip to large range config values to start
Plugin_027_setCalibration_16V_30A();
}
//**************************************************************************/
// Gets the raw bus voltage (16-bit signed integer, so +-32767)
//**************************************************************************/
int16_t Plugin_027_getBusVoltage_raw() {
uint16_t value;
Plugin_027_wireReadRegister(INA219_REG_BUSVOLTAGE, &value);
// Shift to the right 3 to drop CNVR and OVF and multiply by LSB
return (int16_t)((value >> 3) * 4);
}
//**************************************************************************/
// Gets the raw shunt voltage (16-bit signed integer, so +-32767)
//**************************************************************************/
int16_t Plugin_027_getShuntVoltage_raw() {
uint16_t value;
Plugin_027_wireReadRegister(INA219_REG_SHUNTVOLTAGE, &value);
return (int16_t)value;
}
//**************************************************************************/
// Gets the raw current value (16-bit signed integer, so +-32767)
//**************************************************************************/
int16_t Plugin_027_getCurrent_raw() {
uint16_t value;
// Sometimes a sharp load will reset the INA219, which will
// reset the cal register, meaning CURRENT and POWER will
// not be available ... avoid this by always setting a cal
// value even if it's an unfortunate extra step
Plugin_027_wireWriteRegister(INA219_REG_CALIBRATION, ina219_calValue);
// Now we can safely read the CURRENT register!
Plugin_027_wireReadRegister(INA219_REG_CURRENT, &value);
return (int16_t)value;
}
//**************************************************************************/
// Gets the shunt voltage in mV (so +-327mV)
//**************************************************************************/
float Plugin_027_getShuntVoltage_mV() {
int16_t value;
value = Plugin_027_getShuntVoltage_raw();
return value * 0.01;
}
//**************************************************************************/
// Gets the shunt voltage in volts
//**************************************************************************/
float Plugin_027_getBusVoltage_V() {
int16_t value = Plugin_027_getBusVoltage_raw();
return value * 0.001;
}
//**************************************************************************/
// Gets the current value in mA, taking into account the
// config settings and current LSB
//**************************************************************************/
float Plugin_027_getCurrent_mA() {
float valueDec = Plugin_027_getCurrent_raw();
valueDec /= ina219_currentDivider_mA;
return valueDec;
}
can you check if the plugin you load is the same like the one below?
//#######################################################################################################
//######################### Plugin 027: INA219 DC Voltage/Current sensor ################################
//#######################################################################################################
#define PLUGIN_027
#define PLUGIN_ID_027 27
#define PLUGIN_NAME_027 "Voltage & Current (DC) - INA219"
#define PLUGIN_VALUENAME1_027 "Voltage"
uint8_t Plugin_027_INA219_address = 0x40; // 0x40 /0x41 A0/0x44 A1/0x45 A0 and A1
//boolean Plugin_027_init = false;
#define INA219_READ (0x01)
#define INA219_REG_CONFIG (0x00)
#define INA219_CONFIG_RESET (0x8000) // Reset Bit
#define INA219_CONFIG_BVOLTAGERANGE_MASK (0x2000) // Bus Voltage Range Mask
#define INA219_CONFIG_BVOLTAGERANGE_16V (0x0000) // 0-16V Range
#define INA219_CONFIG_BVOLTAGERANGE_32V (0x2000) // 0-32V Range
#define INA219_CONFIG_GAIN_MASK (0x1800) // Gain Mask
#define INA219_CONFIG_GAIN_1_40MV (0x0000) // Gain 1, 40mV Range
#define INA219_CONFIG_GAIN_2_80MV (0x0800) // Gain 2, 80mV Range
#define INA219_CONFIG_GAIN_4_160MV (0x1000) // Gain 4, 160mV Range
#define INA219_CONFIG_GAIN_8_320MV (0x1800) // Gain 8, 320mV Range
#define INA219_CONFIG_BADCRES_MASK (0x0780) // Bus ADC Resolution Mask
#define INA219_CONFIG_BADCRES_9BIT (0x0080) // 9-bit bus res = 0..511
#define INA219_CONFIG_BADCRES_10BIT (0x0100) // 10-bit bus res = 0..1023
#define INA219_CONFIG_BADCRES_11BIT (0x0200) // 11-bit bus res = 0..2047
#define INA219_CONFIG_BADCRES_12BIT (0x0400) // 12-bit bus res = 0..4097
#define INA219_CONFIG_SADCRES_MASK (0x0078) // Shunt ADC Resolution and Averaging Mask
#define INA219_CONFIG_SADCRES_9BIT_1S_84US (0x0000) // 1 x 9-bit shunt sample
#define INA219_CONFIG_SADCRES_10BIT_1S_148US (0x0008) // 1 x 10-bit shunt sample
#define INA219_CONFIG_SADCRES_11BIT_1S_276US (0x0010) // 1 x 11-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_1S_532US (0x0018) // 1 x 12-bit shunt sample
#define INA219_CONFIG_SADCRES_12BIT_2S_1060US (0x0048) // 2 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_4S_2130US (0x0050) // 4 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_8S_4260US (0x0058) // 8 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_16S_8510US (0x0060) // 16 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_32S_17MS (0x0068) // 32 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_64S_34MS (0x0070) // 64 x 12-bit shunt samples averaged together
#define INA219_CONFIG_SADCRES_12BIT_128S_69MS (0x0078) // 128 x 12-bit shunt samples averaged together
#define INA219_CONFIG_MODE_MASK (0x0007) // Operating Mode Mask
#define INA219_CONFIG_MODE_POWERDOWN (0x0000)
#define INA219_CONFIG_MODE_SVOLT_TRIGGERED (0x0001)
#define INA219_CONFIG_MODE_BVOLT_TRIGGERED (0x0002)
#define INA219_CONFIG_MODE_SANDBVOLT_TRIGGERED (0x0003)
#define INA219_CONFIG_MODE_ADCOFF (0x0004)
#define INA219_CONFIG_MODE_SVOLT_CONTINUOUS (0x0005)
#define INA219_CONFIG_MODE_BVOLT_CONTINUOUS (0x0006)
#define INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS (0x0007)
#define INA219_REG_SHUNTVOLTAGE (0x01)
#define INA219_REG_BUSVOLTAGE (0x02)
#define INA219_REG_POWER (0x03)
#define INA219_REG_CURRENT (0x04)
#define INA219_REG_CALIBRATION (0x05)
uint8_t ina219_i2caddr;
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;
boolean Plugin_027(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_027;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].SendDataOption = false;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
break;
}
case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_027);
break;
}
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_027));
break;
}
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[3];
options[0] = F("Voltage");
options[1] = F("Current");
options[2] = F("Power");
int optionValues[3];
optionValues[0] = 0;
optionValues[1] = 1;
optionValues[2] = 2;
string += F("<TR><TD>Report:<TD><select name='plugin_026_value'>");
for (byte x = 0; x < 3; x++)
{
string += F("<option value='");
string += optionValues[x];
string += "'";
if (choice == optionValues[x])
string += F(" selected");
string += ">";
string += options[x];
string += F("</option>");
}
string += F("</select>");
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options2[4];
options2[0] = F("0x40");
options2[1] = F("0x41 -> A0");
options2[2] = F("0x44 -> A1");
options2[3] = F("0x45 -> A0+A1");
uint8_t optionValues2[4];
optionValues2[0] = 0x40;
optionValues2[1] = 0x41;
optionValues2[2] = 0x44;
optionValues2[3] = 0x45;
string += F("<TR><TD>I2C Address:<TD><select name='plugin_027_adr'>");
for (byte x = 0; x < 4; x++)
{
string += F("<option value='");
string += optionValues2[x];
string += "'";
if (choice2 == optionValues2[x])
string += F(" selected");
string += ">";
string += options2[x];
string += F("</option>");
}
string += F("</select>");
success = true;
break;
}
case PLUGIN_WEBFORM_SAVE:
{
String plugin1 = WebServer.arg("plugin_026_value");
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = plugin1.toInt();
String plugin2 = WebServer.arg("plugin_027_adr");
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = plugin2.toInt();
// Plugin_027_init = false; // Force device setup next time??
success = true;
break;
}
case PLUGIN_INIT:
{
// boolean Plugin_027_init = true; // Force device setup??
Plugin_027_INA219_address = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
Plugin_027_begin();
success = true;
break;
}
case PLUGIN_READ:
{
// shuntvoltage = Plugin_027_getShuntVoltage_mV();
// busvoltage = Plugin_027_getBusVoltage_V();
// current_mA = Plugin_027_getCurrent_mA();
// loadvoltage = Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000);
ina219_i2caddr = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
Serial.println(ina219_i2caddr);
float value=0;
switch(Settings.TaskDevicePluginConfig[event->TaskIndex][0])
{
case 0:
{
value = Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000);
UserVar[event->BaseVarIndex] = value;
String log = F("INA 0x");
log += String(ina219_i2caddr,HEX);
log += F(" : Voltage: ");
log += value;
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}
case 1:
{
value = Plugin_027_getCurrent_mA()/1000;
UserVar[event->BaseVarIndex] = value;
String log = F("INA 0x");
log += String(ina219_i2caddr,HEX);
log += F(" : Current: ");
log += value;
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}
case 2:
{
value = (Plugin_027_getBusVoltage_V() + (Plugin_027_getShuntVoltage_mV() / 1000)) * Plugin_027_getCurrent_mA() / 1000;
UserVar[event->BaseVarIndex] = value;
String log = F("INA 0x");
log += String(ina219_i2caddr,HEX);
log += F(" : Power: ");
log += value;
addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}
}
}
}
return success;
}
//**************************************************************************/
// Sends a single command byte over I2C
//**************************************************************************/
void Plugin_027_wireWriteRegister (uint8_t reg, uint16_t value)
{
Wire.beginTransmission(Plugin_027_INA219_address);
Wire.write(reg); // Register
Wire.write((value >> 8) & 0xFF); // Upper 8-bits
Wire.write(value & 0xFF); // Lower 8-bits
Wire.endTransmission();
}
//**************************************************************************/
// Reads a 16 bit values over I2C
//**************************************************************************/
void Plugin_027_wireReadRegister(uint8_t reg, uint16_t *value)
{
Wire.beginTransmission(Plugin_027_INA219_address);
Wire.write(reg); // Register
Wire.endTransmission();
delay(1); // Max 12-bit conversion time is 586us per sample
Wire.requestFrom(Plugin_027_INA219_address, (uint8_t)2);
// Shift values to create properly formed integer
*value = ((Wire.read() << 8) | Wire.read());
}
//**************************************************************************/
// Configures to INA219 to be able to measure up to 32V and 2A
/**************************************************************************/
void Plugin_027_setCalibration_32V_2A(void)
{
ina219_calValue = 4027;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 10; // Current LSB = 100uA per bit (1000/100 = 10)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Configures to INA219 to be able to measure up to 32V and 1A
//**************************************************************************/
void Plugin_027_setCalibration_32V_1A(void)
{
ina219_calValue = 10240;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 25; // Current LSB = 40uA per bit (1000/40 = 25)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Configures to INA219 to be able to measure up to 16V and 30A
//**************************************************************************/
void Plugin_027_setCalibration_16V_30A(void) {
ina219_calValue = 16384;
// Set multipliers to convert raw current/power values
ina219_currentDivider_mA = 1; // Current LSB = 1mA per bit (1/1 = 1)
// Set Calibration register to 'Cal' calculated above
Plugin_027_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_2_80MV |
INA219_CONFIG_BADCRES_12BIT |
INA219_CONFIG_SADCRES_12BIT_1S_532US |
INA219_CONFIG_MODE_SANDBVOLT_CONTINUOUS;
Plugin_027_wireWriteRegister(INA219_REG_CONFIG, config);
}
//**************************************************************************/
// Setups the HW (defaults to 16V and 30A with 2.5mohms shunt for calibration values)
//**************************************************************************/
void Plugin_027_begin(void) {
// Plugin_027_INA219_address = Plugin_027_INA219_address; // INA219_ADDRESS;
ina219_currentDivider_mA = 1;
// Set chip to large range config values to start
Plugin_027_setCalibration_16V_30A();
}
//**************************************************************************/
// Gets the raw bus voltage (16-bit signed integer, so +-32767)
//**************************************************************************/
int16_t Plugin_027_getBusVoltage_raw() {
uint16_t value;
Plugin_027_wireReadRegister(INA219_REG_BUSVOLTAGE, &value);
// Shift to the right 3 to drop CNVR and OVF and multiply by LSB
return (int16_t)((value >> 3) * 4);
}
//**************************************************************************/
// Gets the raw shunt voltage (16-bit signed integer, so +-32767)
//**************************************************************************/
int16_t Plugin_027_getShuntVoltage_raw() {
uint16_t value;
Plugin_027_wireReadRegister(INA219_REG_SHUNTVOLTAGE, &value);
return (int16_t)value;
}
//**************************************************************************/
// Gets the raw current value (16-bit signed integer, so +-32767)
//**************************************************************************/
int16_t Plugin_027_getCurrent_raw() {
uint16_t value;
// Sometimes a sharp load will reset the INA219, which will
// reset the cal register, meaning CURRENT and POWER will
// not be available ... avoid this by always setting a cal
// value even if it's an unfortunate extra step
Plugin_027_wireWriteRegister(INA219_REG_CALIBRATION, ina219_calValue);
// Now we can safely read the CURRENT register!
Plugin_027_wireReadRegister(INA219_REG_CURRENT, &value);
return (int16_t)value;
}
//**************************************************************************/
// Gets the shunt voltage in mV (so +-327mV)
//**************************************************************************/
float Plugin_027_getShuntVoltage_mV() {
int16_t value;
value = Plugin_027_getShuntVoltage_raw();
return value * 0.01;
}
//**************************************************************************/
// Gets the shunt voltage in volts
//**************************************************************************/
float Plugin_027_getBusVoltage_V() {
int16_t value = Plugin_027_getBusVoltage_raw();
return value * 0.001;
}
//**************************************************************************/
// Gets the current value in mA, taking into account the
// config settings and current LSB
//**************************************************************************/
float Plugin_027_getCurrent_mA() {
float valueDec = Plugin_027_getCurrent_raw();
valueDec /= ina219_currentDivider_mA;
return valueDec;
}
Re: INA219 shunt resistor change to 0.01 ohm
Thanks StefanD,
Now with your latest plugin that you posted it seems to be working at least with few led modules connect to 12v supply I get reasonable values. Hopefully I get this installed within next week to my summer place solar panel. So that it would work better than the "original INA219" (attached pictures show the measurements is now with the original INA219 unit)
Now with your latest plugin that you posted it seems to be working at least with few led modules connect to 12v supply I get reasonable values. Hopefully I get this installed within next week to my summer place solar panel. So that it would work better than the "original INA219" (attached pictures show the measurements is now with the original INA219 unit)
- Attachments
-
- Domoticz.JPG (42.92 KiB) Viewed 23561 times
Re: INA219 shunt resistor change to 0.01 ohm
Hi KKSU,
I am glad to hear that is working. Just an advice for you when you will install the INA sensor with the external shunt. Wires to the external shunt to be as short as possible, avoid grounding loops and if you use the same voltage to supply the module through a DC buck converter use separate wires for supply and for measuring. I got myself in trouble when I installed first time INA module.
I hope it helps
I am glad to hear that is working. Just an advice for you when you will install the INA sensor with the external shunt. Wires to the external shunt to be as short as possible, avoid grounding loops and if you use the same voltage to supply the module through a DC buck converter use separate wires for supply and for measuring. I got myself in trouble when I installed first time INA module.
I hope it helps
Re: INA219 shunt resistor change to 0.01 ohm
How big external shunts could actually be used? Would it be possible to go to 500A as 12V? This would make it possible to meassure current to all functions on my boat which would be rather cool
Re: INA219 shunt resistor change to 0.01 ohm
Hi,
there is no current limit in using external shunt , in your case let say a standard 500A/75mv. Calibration procedure should be calculated according with sensor TI manual and this plugin modified to include and use this calibration.
Best regards
there is no current limit in using external shunt , in your case let say a standard 500A/75mv. Calibration procedure should be calculated according with sensor TI manual and this plugin modified to include and use this calibration.
Best regards
Re: INA219 shunt resistor change to 0.01 ohm
Hello!
I have just receieved a 75mV, 50A external shunt and I'm also using 2 INA219 connected to the same wemos mini d1.
Can I use this above code along with the latest beta to get this working? I know that it wasn't long ago that a bug was fixed that lets you use more than one INA219 on the same ESP.
Also, can I use the exact same code as above since my shunt is also 75mV or do I need to make some calibrating since mine i for 50A?
,Olle
I have just receieved a 75mV, 50A external shunt and I'm also using 2 INA219 connected to the same wemos mini d1.
Can I use this above code along with the latest beta to get this working? I know that it wasn't long ago that a bug was fixed that lets you use more than one INA219 on the same ESP.
Also, can I use the exact same code as above since my shunt is also 75mV or do I need to make some calibrating since mine i for 50A?
,Olle
Re: INA219 shunt resistor change to 0.01 ohm
To set the proper range for the shunt, see page 5 of the datasheet: http://www.ti.com/lit/ds/symlink/ina219.pdf
You may have to convert the measured value and don't forget to remove the present shunt if there is one.
You may have to convert the measured value and don't forget to remove the present shunt if there is one.
Re: INA219 shunt resistor change to 0.01 ohm
Hi!
Thankyou for your answer!
Present resistor is removed but I'm clearly on deep water here since the only thing I find on page 5 that would be the formula on top of the page. I'm afraid I don't really understand what I need to do to get the right figure.
Also I'm really not sure what I need to alter in the plugin code. currentDivider seems important as well as calValue but again I'm really out of my league here. If it's not to much trouble would somebody care to help me a bit further? What I'm trying to measure is a 12V system with normal currents of 5-15 A but with possible peaks at 30-40 A. This is with a 50A/75mV shunt.
Thankyou for your answer!
Present resistor is removed but I'm clearly on deep water here since the only thing I find on page 5 that would be the formula on top of the page. I'm afraid I don't really understand what I need to do to get the right figure.
Also I'm really not sure what I need to alter in the plugin code. currentDivider seems important as well as calValue but again I'm really out of my league here. If it's not to much trouble would somebody care to help me a bit further? What I'm trying to measure is a 12V system with normal currents of 5-15 A but with possible peaks at 30-40 A. This is with a 50A/75mV shunt.
Re: INA219 shunt resistor change to 0.01 ohm
OK! I'm making some progress. Did manage to flash one of the older builds of ESPEasy MEGA and replaced the INA plugin code with the one in this thread and it's actually working Even though, the current reported is off by a factor of 2-ish. So any help I could get in configuring the plugin for my setup would be greatly appreciated
Re: INA219 shunt resistor change to 0.01 ohm
There are two options to approach this:
1)
You have to know the value of the original resistor and compare it with the new shunt.
50A/75 mV means the shunt resistance is R = U/I => R = 0.075/50 = 0.0015 Ohm.
Lets for example assume the original resistor was 0.01 Ohm and the max current was 3A.
This means the max voltage is then U=I*R => U = 0.01 * 3 = 0.03 V = 30 mV.
Then the voltage range is probably set at 30mV, which gives you a range of I = U/R => I = 0.03A / 0.0015Ohm = 20 A.
So you could add two of these shunts in parallel to be able to process 40A with a range of 0...30 mV
Ofcourse you also have to adjust the output reading then. The output should then be multiplied by ( 0.01 / 0.0015) = 6.67.
2) Make sure you set the range of the INA219 to cover the range 0 ... 75 mV, which is described on the datasheet.
This means you have to change the source, build a new version and also compute a correct factor to output the measured current as described above.
So 1) can be done with minimal effort and knowledge.
And maybe we should add some settings to allow to change the shunt and enter some output factor.
1)
You have to know the value of the original resistor and compare it with the new shunt.
50A/75 mV means the shunt resistance is R = U/I => R = 0.075/50 = 0.0015 Ohm.
Lets for example assume the original resistor was 0.01 Ohm and the max current was 3A.
This means the max voltage is then U=I*R => U = 0.01 * 3 = 0.03 V = 30 mV.
Then the voltage range is probably set at 30mV, which gives you a range of I = U/R => I = 0.03A / 0.0015Ohm = 20 A.
So you could add two of these shunts in parallel to be able to process 40A with a range of 0...30 mV
Ofcourse you also have to adjust the output reading then. The output should then be multiplied by ( 0.01 / 0.0015) = 6.67.
2) Make sure you set the range of the INA219 to cover the range 0 ... 75 mV, which is described on the datasheet.
This means you have to change the source, build a new version and also compute a correct factor to output the measured current as described above.
So 1) can be done with minimal effort and knowledge.
And maybe we should add some settings to allow to change the shunt and enter some output factor.
Re: INA219 shunt resistor change to 0.01 ohm
Thanks Td-er, I really value your input!
This thread describes a changed plugin that was made for 30A and 2.5 mohms. So using the same formula: 30*0.0025=0.075. The shunt in the changed plugin is also 75mV.
So after some trial and error and input from this page I got this numbers which gave me pretty accurate results.
https://stackoverflow.com/questions/397 ... alibration
MAX power (don't expect much above 25A) 25
Resistor 0,0015
LSB MIN 0,000763
LSB MAX 0,006104
Choosen LSB: 0,001
cal value= (0,04096/0,001) / 0,0015 = 27 306
Current divider= 1000 / 1000 = 1mA
Next step is to try these values in a newer version of the plugin where Td-er have made the necessary changes to use several INA219 on the same setup.
This thread describes a changed plugin that was made for 30A and 2.5 mohms. So using the same formula: 30*0.0025=0.075. The shunt in the changed plugin is also 75mV.
So after some trial and error and input from this page I got this numbers which gave me pretty accurate results.
https://stackoverflow.com/questions/397 ... alibration
MAX power (don't expect much above 25A) 25
Resistor 0,0015
LSB MIN 0,000763
LSB MAX 0,006104
Choosen LSB: 0,001
cal value= (0,04096/0,001) / 0,0015 = 27 306
Current divider= 1000 / 1000 = 1mA
Next step is to try these values in a newer version of the plugin where Td-er have made the necessary changes to use several INA219 on the same setup.
Who is online
Users browsing this forum: No registered users and 2 guests