INA219 DC Current & Voltage Measurement

Monitor DC voltage and current up to +26 VDC and 3.2 A.

Based on the INA219.

Measures up to +/- 3.2 amps (resolution is 0.8 mA at this amplitude)

By changing the gain, the resulution can be 0.1 mA for +/- 400 mA

When connecting to noisy loads such as a DC motor, add a large capacitor to decouple the motor from the power supply and use a snubber diode to protect against inductive spikes.

WARNING: take precautions to protect against inductive spikes.   When switching inductive loads, the instantaneous voltage levels may greatly exceed steady-state levels due to inductive kickback, causing chip damage.

Use a INA226 to monitor the power of a circuit up to 36 V and 3.2 A.  

Other higher voltage current sensing options

NOTE: The INA219 is connected in-line between the power source and the load.  


#include "Particle.h"

/////////////////////////////////////////////////////////////////////////
// Adafruit AF_INA219 FeatherWing
// Measures DC current & voltage
// Install particle library "adafruit-af_ina219"
//#include <Wire.h>
#include "adafruit-ina219.h"
Adafruit_INA219 af_ina219;
struct INA_219_t{
  const unsigned long TIMER_INTERVAL_SAMPLE_US = 1000;
  unsigned long timerLastSample = 0;
  float mAh = 0.0;
  unsigned long samples = 0;
  const unsigned long TIMER_INTERVAL_PUBLISH_MS = 3600000;  // 1 hr = 3600000
  unsigned long timerLastPublish = 0;
} ina219;
/////////////////////////////////////////////////////////////////////////
// Battery charging status 
// Source: https://github.com/rickkas7/DiagnosticsHelperRK
#include "DiagnosticsHelperRK.h"
#if PLATFORM_ID == PLATFORM_BORON
    #define PWR -1 // to avoid compile error on Boron
#endif
/////////////////////////////////////////////////////////////////////////

void setup() {
  
  Serial.begin(9600);
  waitFor(Serial.isConnected, 30000);
  delay(1000);
  Serial.printlnf("System version: %s", System.version().c_str());
  Serial.printlnf("Free RAM %d", System.freeMemory());

  // By default, the range is the max of 32 V @ 2 A
  af_ina219.begin();
  // To set range to 32 V @ 1 A to improve precision:
  //af_ina219.setCalibration_32V_1A();
  // To set range to 16V @ 400 mA:
  //af_ina219.setCalibration_16V_400mA();

  Serial.println("Setup complete");
  ina219.timerLastPublish = millis();
  ina219.timerLastSample = micros();
} // setup()


void loop() {

  ReadINA219();

} // loop()


void ReadINA219() {
  // Read AF_INA219 current every ms (1 kHz) and calculate the
  // mAh value, and add this to the cumulative stored in mAh.
  // Every hour publish the mAh and reset mAh (mAh = 0). 
  // Only read the INA219 if NOT connected to USB.

  // Read INA219 every 1000 us (1 ms)
  if (ina219.timerLastSample > micros())  ina219.timerLastSample = micros();
  if ((micros() - ina219.timerLastSample) > ina219.TIMER_INTERVAL_SAMPLE_US) {
    if (ConnectedToBattOnly() == true) {
      float mA = af_ina219.getCurrent_mA();
      float hr = ina219.TIMER_INTERVAL_SAMPLE_US/3600.0/1000.0/1000.0;
      ina219.mAh += mA * hr;
      ina219.samples++;
    } else {
    }
    ina219.timerLastSample = micros();
  }

  // Every hour publish the cumulative mAh value & reset mAh.
  if (ina219.timerLastPublish > millis())  ina219.timerLastPublish = millis();
  if ((millis() - ina219.timerLastPublish) > ina219.TIMER_INTERVAL_PUBLISH_MS) {
    float bus_mV = af_ina219.getBusVoltage_V()*1000.0; // voltage between GND and V- (supply voltage - shunt voltage)
    float shunt_mV = af_ina219.getShuntVoltage_mV();   // voltage between V- and V+  (measured voltage drop across shunt resistor)
    float load_mV = bus_mV + shunt_mV;
    //float batt_V = analogRead(BATT) * 0.0011224;  // Not Boron
    Serial.printlnf("%0.4f mAh, %u samples, load_mV %0.1f V", ina219.mAh, ina219.samples, load_mV);
    if (ConnectedToBattOnly())
      Particle.publish("mAh", String::format("%0.4f mAh over 1 hr for %u samples", ina219.mAh, ina219.samples), PRIVATE);
    else
      Particle.publish("mAh", String::format("USB pwr"), PRIVATE);
    ina219.mAh = 0;
    ina219.samples = 0;
    ina219.timerLastPublish = millis();
  }

} // ReadINA219()


bool ConnectedToBattOnly() {
  if (PLATFORM_ID == PLATFORM_ARGON || PLATFORM_ID == PLATFORM_XENON) {       
      pinMode(PWR, INPUT);
      byte pwr = digitalRead(PWR);    // PWR: 0=no USB power, 1=USB powered
      // NOTE:  Need to test with VIN power
      if (pwr == 0)
        return true;
      else
        return false;          
  } else if (PLATFORM_ID == PLATFORM_BORON) {
    // DiagnosticsHelper works on Boron LTE (the Argon and Xenon don’t have a PMIC chip)
    int powerSource = DiagnosticsHelper::getValue(DIAG_ID_SYSTEM_POWER_SOURCE);
    if (powerSource == 5)
      return true;
    else
      return false;
  }    
  return false;
} // ConnectedToBattOnly()
			

https://www.adafruit.com/product/3650

INA219 60V 5A max

+36V at up to 15A Continuous on high or low side with INA260

NI voltage, current, power measurement tutorial

 


Do you need help developing or customizing a IoT product for your needs?   Send me an email requesting a free one hour phone / web share consultation.  

 

The information presented on this website is for the author's use only.   Use of this information by anyone other than the author is offered as guidelines and non-professional advice only.   No liability is assumed by the author or this web site.