Skip to content

Commit 1de7e0c

Browse files
authored
Update Ina219 to support both side current flow readings (#616)
1 parent b666b7c commit 1de7e0c

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

devices/Ina219/Ina219.cs

+36-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class Ina219 : IDisposable
2727
// along with any conversions.
2828
private static int s_readDelays(Ina219AdcResolutionOrSamples adc)
2929
{
30-
switch(adc)
30+
switch (adc)
3131
{
3232
case Ina219AdcResolutionOrSamples.Adc9Bit: return 84;
3333
case Ina219AdcResolutionOrSamples.Adc10Bit: return 148;
@@ -50,6 +50,7 @@ private static int s_readDelays(Ina219AdcResolutionOrSamples adc)
5050
private Ina219AdcResolutionOrSamples _busAdcResSamp;
5151
private Ina219AdcResolutionOrSamples _shuntAdcResSamp;
5252
private float _currentLsb;
53+
private bool _mathOverflowFlag = false;
5354

5455
/// <summary>
5556
/// Construct an Ina219 device using an I2cDevice
@@ -238,21 +239,40 @@ public void Dispose()
238239
}
239240
}
240241

242+
/// <summary>
243+
/// Get overflow result of last conversion
244+
/// </summary>
245+
/// <remarks>
246+
/// The Math Overflow Flag (OVF) is set when the Power or Current calculations are out of range.
247+
/// It indicates that current and power data may be meaningless.
248+
/// </remarks>
249+
[Telemetry]
250+
public bool MathOverflowFlag { get => _mathOverflowFlag; }
251+
241252
/// <summary>
242253
/// Read the measured shunt voltage.
243254
/// </summary>
244255
/// <returns>The shunt potential difference</returns>
245256
// read the shunt voltage. LSB = 10uV then convert to Volts
246257
[Telemetry("ShuntVoltage")]
247-
public ElectricPotential ReadShuntVoltage() => ElectricPotential.FromVolts(ReadRegister(Ina219Register.ShuntVoltage, s_readDelays(_shuntAdcResSamp)) * 10.0 / 1000000.0);
258+
public ElectricPotential ReadShuntVoltage() => ElectricPotential.FromVolts(ConvertFrom16BitTwosComplement(ReadRegister(Ina219Register.ShuntVoltage, s_readDelays(_shuntAdcResSamp))) / (1000000.0 / 10.0));
248259

249260
/// <summary>
250261
/// Read the measured Bus voltage.
251262
/// </summary>
263+
/// <remarks>
264+
/// Will set _mathOverflowFlag according to result
265+
/// _mathOverflowFlag can use to check if values in Power/Current registers are valid
266+
/// </remarks>
252267
/// <returns>The Bus potential (voltage)</returns>
253268
// read the bus voltage. LSB = 4mV then convert to Volts
254269
[Telemetry("BusVoltage")]
255-
public ElectricPotential ReadBusVoltage() => ElectricPotential.FromVolts(((short)ReadRegister(Ina219Register.BusVoltage, s_readDelays(_busAdcResSamp)) >> 3) * 4 / 1000.0);
270+
public ElectricPotential ReadBusVoltage()
271+
{
272+
ushort busvoltage = ReadRegister(Ina219Register.BusVoltage, s_readDelays(_busAdcResSamp));
273+
_mathOverflowFlag = (busvoltage & 1) != 0 ? true : false;
274+
return ElectricPotential.FromVolts(((short)busvoltage >> 3) * 4 / 1000.0);
275+
}
256276

257277
/// <summary>
258278
/// Read the calculated current through the INA219.
@@ -270,7 +290,7 @@ public ElectricCurrent ReadCurrent()
270290
// whenever needed.
271291
SetCalibration(_calibrationValue, _currentLsb);
272292

273-
return ElectricCurrent.FromAmperes(ReadRegister(Ina219Register.Current, s_readDelays(_shuntAdcResSamp)) * _currentLsb);
293+
return ElectricCurrent.FromAmperes(ConvertFrom16BitTwosComplement(ReadRegister(Ina219Register.Current, s_readDelays(_shuntAdcResSamp))) * _currentLsb);
274294
}
275295

276296
/// <summary>
@@ -337,5 +357,17 @@ private void WriteRegister(Ina219Register register, ushort value)
337357
// write the value to the register via the I2c Bus.
338358
_i2cDevice.Write(buffer);
339359
}
360+
361+
/// <summary>
362+
/// Convert from 2's complement format
363+
/// </summary>
364+
/// <param name="twosComp">The value to be writtent to the register.</param>
365+
/// <returns>Siged short integer representing decoded value.</returns>
366+
private short ConvertFrom16BitTwosComplement(ushort twosComp)
367+
{
368+
// convert from 2's cpmplement 24 bit to int (32 bit)
369+
short normalValue = ((twosComp & 0x8000) != 0) ? (short)(0 - ((twosComp ^ 0xffff) + 1)) : (short)twosComp;
370+
return normalValue;
371+
}
340372
}
341373
}

devices/Ina219/samples/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@
3030
while (true)
3131
{
3232
// write out the current values from the INA219 device.
33-
Debug.WriteLine($"Bus Voltage {device.ReadBusVoltage().Volts} Shunt Voltage {device.ReadShuntVoltage().Millivolts}mV Current {device.ReadCurrent().Value} Power {device.ReadPower().Watts}");
33+
Debug.WriteLine($"Bus Voltage {device.ReadBusVoltage().Volts} Shunt Voltage {device.ReadShuntVoltage().Millivolts}mV Current {device.ReadCurrent().Value} Power {device.ReadPower().Watts} [OVF = {device.MathOverflowFlag}]");
3434
Thread.Sleep(1000);
3535
}

0 commit comments

Comments
 (0)