- Hits: 34737
You can measure DC Voltage, Current and Power in a voltage range from 0V to 26V. This circuit use a high-side current shunt and power monitor with an I2C interface INA209 from Texas Instruments and an Arduino UNO as microcontroller. The values are shown on a 2x16 LCD display.
Hardware description
All the measurements are made by Texas Instruments INA209, it's a high-side current shunt and power monitor with an I2C interface. The INA209 monitors both shunt drop and shunt bus voltage. A programmable calibration value, combined with an internal multiplier, enables direct readouts in amperes. The INA209 also includes an analog comparator and a programmable 12 bit digital-to-analog converter (DAC) that combine to provide the fastest possible responses to current overload conditions. The INA209 senses across shunts on buses that can vary from 0V to 26V.
INA209 Features
- Senses BUS Voltage from 0V to +26V
- Reports Current, Voltage, Power and stores Peaks
- Triple Watchdog Limit:
- Lower Warning with Delay
- Upper Over-Limit, No Delay
- Fast Analog Critical
- High Accuracy: 1% Max Over Temp
For more details see Texas Instruments INA209 datasheet.
The comunication between INA209 and Arduino occurs through the I2C bus. Arduino controls all function of INA209 and reads the value measured from the dedicated registers. You can read the INA209 status or set the configuration parameters.
In this version of firmware I designed only the basic functions for continuos measurements of instantaneous Voltage, Current and Power but you can control all function of INA209 with my library as described on page INA209 Arduino Library.
The Voltage, Current and Power values are are shown on a 16x2 LCD display connected to digital pin of Arduino. LCD display is a standard 16x2 character model YM1602C and is connected to Arduino digital pins 12, 11, 5, 4, 3, 2. The contrast is regulated by a 10k trimmer and the backlight is software controlled by Arduino PWM digital output on pin 6.
The figure below shown the block diagram of DC Power Monitor.
In this version of firmware I designed only the basic function for continuos measurements of instantaneous Voltage, Current and Power but you can control all function of INA209 with my library as described on page INA209 Arduino Library.
Circuit schematics
Technical specifications
General features |
|
Averaging results | 2 ÷ 128 samples |
Voltage Measurement | |
Digits |
5 |
Full-Scale range |
0 ÷ 26 V |
Resolution |
4mV |
Measurement error |
± 0.5% max |
Measurement error over temperature |
± 1% max |
Current Measurement | |
Digits |
5 |
Full-Scale range |
0 ÷ 6 A |
Resolution |
1mA |
Measurement error |
± 0.5% max |
Measurement error over temperature | ± 1% max |
Power Measurement | |
Digits | 6 |
Full-Scale range | 0 ÷ 156 W |
Resolution | 4mW |
Measurement error | ± 1% max |
Measurement error over temperature | ± 2% max |
Firmware
The most important part of the firmware is the INA209 library I have written and you can see it on page INA209 Arduino Library. The library is used for control all functions of INA209 through the I2C bus. The measured value are read from INA209 using a simple and intuitive function call and you don't need to know how I2C works.
/* DC Power Monitor by ADPSLAB Created 12 Sep. 2012 (Rev. 1.0) Copyright (c) 2012 Antonio Dambrosio (This email address is being protected from spambots. You need JavaScript enabled to view it.). All rights reserved. This sketch is for control a Texas Instruments INA209 chip through I2C bus and shown on a LCD Display 2x16 character these values: Voltage measurement in a range from 0 to +26V with 4mV resolution; Current measurement in a range from 0 to 6A with mA resolution; Power measurement with 4mW resolution. See the schematics on: https://www.adpslab.com/en/electronics/arduino/22-dc-power-monitor-with-ina209-and-arduino */ #include <Wire.h> //I2C library #include <INA209.h> //INA209 library #include <LiquidCrystal.h> //LCD library LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // initialize the LCD library with the numbers of the interface pins #define BACKLIGHT_PIN 6 // define PIN for PWM Backlight control INA209 ina209a(0x40); // creation of an instance of the INA209 class called ina209a with I2C slave address = 0x40 int intro = 0; // costant value for intro message void setup() { analogWrite(BACKLIGHT_PIN, 240); lcd.begin(16, 2); // set up the LCD's number of columns and rows Serial.begin(9600); // setup serial Wire.begin(); // join i2c bus // ------------- General Configuration --------- /* Configuration Register 00h (Read/Write) Default settings -> writeCfgReg(14751) Bus Voltage Range = 32V PGA (Shunt Voltage Only) = +/- 320mV BADC Bus ADC Resolution/Averaging = 12bit SADC Shunt ADC Resolution/Averaging = 12bit Operating Mode = Shunt and Bus, Continuos */ // ina209a.writeCfgReg(14751); // Default settings no averaging // ina209a.writeCfgReg(15839); // 8 averaging samples bus and shunt ina209a.writeCfgReg(16247); // 64 averaging samples bus and shunt // -------------- Calibration ------------------ /* Calibration Register 16h (Read/Write) This register sets the current that corresponds to a full-scale drop across the shunt. Full-scale range and the LSB of the current and power measurement depend on the value entered in this register. See the Programming the INA209 Power Measurement Engine section of INA209 datasheet. In this example: Vbus_max = 32V Vshunt_max = 0,32V Rshunt = 0,05 Ohm -> Max Expected Current = +/- 6A Current LSB = 200uA Calibration Reg = 4096 Power LSB = 4mW Max Power = 204,8W */ ina209a.writeCal(4096); // ---------- WARNING WATCHDOG REGISTERS ------- /* These registers set warning limits that trigger flags in the Status Register and activate the Warning pin. */ ina209a.writeShuntVolPwrn(30000); // set Shunt Voltage Positive Warning limit to 30000 (= 300mV) ina209a.writeShuntVolNwrn(-500); // set Shunt Voltage Negative Warning limit to -500 (= -5mV) ina209a.writePowerWrn(10000); // set Power Warning limit ina209a.writeBusOVwrn(52000); // set Bus Over-Voltage Warning limit, if you want a limit of 26V you have to set 26000*2 = 52000 ina209a.writeBusUVwrn(10000); // set Bus Under-Voltage Warning limit, if you want a limit of 5V you have to set 5000*2 = 10000 // ---------- OVER-LIMIT/CRITICAL WATCHDOG REGISTERS ---------------- /* These registers set the over-limit and critical DAC limits that trigger flags to be set in the Status Register and activate the Overlimit pin or the Critical pin. */ ina209a.writePowerOL(12000); // set Power Over-Limit ina209a.writeBusOVOL(60000); // set Bus Over-Voltage Over-Limit, if you want a limit of 30V you have to set 30000*2 = 60000 (see the datasheet for other functions) ina209a.writeBusUVOL(6000); // set Bus Under-Voltage Over-Limit, if you want a limit of 3V you have to set 3000*2 = 6000 ina209a.writeCrShuntPV(51200); // set Critical DAC+ Register (Critical Shunt Positive Voltage). No sign bit (sets a positive limit only). At full-scale range = 255mV; LSB = 1mV; 8-bit. // if you want a limit of +200mV you have to set 200*256 = 51200; // this register control GPIO PIN, see the datasheet. ina209a.writeCrShuntNV(51200); // set Critical DAC– Register (Critical Shunt Negative Voltage). No sign bit (sets negative limit only). At full-scale range = –255mV; LSB = 1mV; 8-bit. // if you want a limit of -200mV you have to set 200*256 = 51200; // this register control DAC Comparator output filter, see the datasheet. } void loop() { if (intro == 0) { // Intro message lcd.home (); lcd.setCursor(4, 0); lcd.print ("ADPSLAB"); lcd.setCursor(0, 1); lcd.print ("DC Power Monitor"); delay (3000); lcd.clear (); intro = 1; } lcd.setCursor(0, 0); // set the cursor to (0 at first line) lcd.print (msg2dot3(ina209a.busVol())); // show Voltage measured lcd.print (" V"); lcd.setCursor(8, 0); lcd.print (msg2dot3(current_mA(200))); // show Current measured lcd.print (" A"); lcd.setCursor(0, 1); lcd.print ("); lcd.print (msg3dot3(power_mW(4))); // show Power measured lcd.print (" W>"); lcd.setCursor(7, 1); } int current_mA (int current_LSB) { // set Current in mA, current_mA = ina209a.current() * current_LSB (uA) / 1000 int y = 1000 / current_LSB; int x = ina209a.current() / y; return x; } long power_mW (int power_LSB) { // set Power in mW, power_mW = ina209a.power() * power_LSB (mW) long x = ina209a.power() * power_LSB; return x; } String msg2dot3 (int xvalue) { // format integer to string 2.3 character String strvalue = 0; if (xvalue >= 0){ strvalue = String (xvalue); switch (strvalue.length()) { case 1: strvalue = String (" .00" + strvalue.substring(0)); break; case 2: strvalue = String (" .0" + strvalue.substring(0)); break; case 3: strvalue = String (" ." + strvalue.substring(0)); break; case 4: strvalue = String (" " + strvalue.substring(0,1) + "." + strvalue.substring(1)); break; case 5: strvalue = String (strvalue.substring(0,2) + "." + strvalue.substring(2)); break; default: strvalue = String ("error"); } } else { strvalue = String (abs(xvalue)); switch (strvalue.length()) { case 1: strvalue = String (" -.00" + strvalue.substring(0)); break; case 2: strvalue = String (" -.0" + strvalue.substring(0)); break; case 3: strvalue = String (" -." + strvalue.substring(0)); break; case 4: strvalue = String ("-" + strvalue.substring(0,1) + "." + strvalue.substring(1)); break; case 5: strvalue = String (strvalue.substring(0,2) + "." + strvalue.substring(2) + "-"); break; default: strvalue = String ("error"); } } return strvalue; } String msg3dot3 (long pvalue) { // format long integer to string 3.3 character String strvalue = 0; strvalue = String (pvalue); switch (strvalue.length()) { case 1: strvalue = String (" .00" + strvalue.substring(0)); break; case 2: strvalue = String (" .0" + strvalue.substring(0)); break; case 3: strvalue = String (" ." + strvalue.substring(0)); break; case 4: strvalue = String (" " + strvalue.substring(0,1) + "." + strvalue.substring(1)); break; case 5: strvalue = String (" " +strvalue.substring(0,2) + "." + strvalue.substring(2)); break; case 6: strvalue = String (" " +strvalue.substring(0,3) + "." + strvalue.substring(3)); break; default: strvalue = String ("error"); } return strvalue; }
Download the library files and Arduino sketch file.
Tests on prototype board
The figure below shown the circuit on a prototype board. In this version Arduino, INA209 and LCD Display are powered by USB supply. The power supply under test are connected on the bananas connector on the left of photo.
The video below shown some tests on a prototype board.