This is a shield to constantly measure Current, Voltage and Power used by a load. It was developped
for physics classroom use. But it mayst be also connected to the Envico Logging System.
Maximum Voltage is 36 V. Maximum Current is 9.999 A. An internal beeper can alarm (the teacher)
on various over-the-limit conditions.
The INA260 has a very high input impedance. We added a 68 kΩ later, as a pull-down resistor in
order to avoid voltage drifting under no connection situations.
✈ The INA 260 by Texas Instruments - circut description
"The INA260 is a digital-output, current, power, and
voltage monitor with an I2C and SMBus™ compatible
interface with an integrated precision shunt resistor. It
enables high-accuracy current and power
measurements and over-current detection at
common-mode voltages that can vary from 0 V to 36
V, independent of the supply voltage. The device is a
bidirectional, low- or high-side, current-shunt monitor
that measures current flowing through the internal
current-sensing resistor. The integration of the
precision current-sensing resistor provides
calibration-equivalent measurement accuracy with
ultra-low temperature drift performance and ensures
that an optimized Kelvin layout for the sensing
resistor is always obtained." Says the Datasheet.
Inside the INA260. Drawing courtesy of Texas Instruments
Even so it can be used on low- or high-side, we use the high-side variant here, as this is the preciser way to use it.
As we use only one device, the address is fixed to 0x40. (A0 and A1 = GND). Also onboard is an 24C01 (128 Bytes EEPROM).
This is used to hold sensor information for Envico. The address is 0x50. The device can be powered via the Envico DSUB-9 connector
or via a power-supply (approx. 9 V, 100 mA).
We calculate the Power, as it turned out, that the current measurement is sometimes off by 1 ... 2 mA. And so
would the power reading be larger than zero, even if no load is connected.
For "calibration" we introduced an offset :
Inside the case. Very straightforward design. Arduino UNO is under the pcb.
✈ Downloads
✈ Arduino Sketch - The Code
Double click on code to select ...
/* //////////////////////////////////////////////////////////////////
ARDUINO/Genuino Project "Pingumod", a P-U-I Monitor (INA260)
https://www.changpuak.ch/electronics/Arduino-Project-PINGUMOD.php
Software Version 1.0
14.02.2020 by ALEXANDER SSE FRANK
USES LIBRARY FROM Matthew Brush <mbrush@codebrainz.ca>, (C) 2018
https://github.com/codebrainz/ina260
////////////////////////////////////////////////////////////////// */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
#include <INA260.h>
static INA260 ina260(0);
double value = 0.0 ;
// DISPLAY
#define OLED_MOSI A0
#define OLED_CLK 2
#define OLED_DC A2
#define OLED_CS A3
#define OLED_RESET A1
// GERNERAL I/O
#define BEEP 12
#define ALARM 9
#define GPIO 13
#define ENVICO 11
#define ALERT 10
#define EEPROM_24C01_I2CADDR 0x50
Adafruit_SH1106 display(OLED_MOSI,OLED_CLK,OLED_DC,OLED_RESET,OLED_CS);
#if (SH1106_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SH1106.h!");
#endif
float Volt = 5.021 ; // UNIT IS V
float Current = 1.601 ; // UNIT IS A
float Power = abs(Volt * Current) ; // UNIT IS W
boolean Measure = false ;
// CALIBRATION VALUES :-)
float VoltOffset = 0.0 ;
float CurrentOffset = 0.0012 ;
// /////////////////////////////////////////////////////////////////////
// SUBROUTINES DISPLAY.
// /////////////////////////////////////////////////////////////////////
void DisplayValue(float WERT)
{
if(WERT > 9999.9 ) WERT = 999.999 ; // CATCH COM ERROR
if(WERT >= 0.0) display.print(" ") ; // MINUSZEICHEN
if(abs(WERT) < 100.00) display.print(" ") ; //
if(abs(WERT) < 9.9999) display.print(" ") ; //
display.print(WERT,3) ;
}
void UpDateDisplay()
{
display.clearDisplay();
display.setTextColor(WHITE) ;
display.setTextSize(2) ;
// VOLTAGE
display.setCursor(0,0) ;
DisplayValue(Volt) ;
display.print(" V") ;
// CURRENT
display.setCursor(0,24) ;
DisplayValue(Current) ;
display.print(" A") ;
// POWER
Power = abs(Volt * Current) ;
display.setCursor(0,48) ;
DisplayValue(Power) ;
display.print(" W") ;
// ////////////////////////////////////////
// OPTION "F" ONLY
// ////////////////////////////////////////
boolean S6 = digitalRead(6) ;
boolean S7 = digitalRead(7) ;
display.setCursor(0,0) ;
if(!S6) display.print("R") ;
if(!S7) display.print("Z") ;
if(S6 && S7) display.print("S") ;
display.display() ;
}
// /////////////////////////////////////////////////////////////////////
// SUBROUTINES INA 260
// /////////////////////////////////////////////////////////////////////
void UpdateINA260()
{
// CURRENT
ina260.readCurrentRegisterInAmps(value) ;
Current = value + CurrentOffset ;
// VOLTAGE
ina260.readBusVoltageRegisterInVolts(value) ;
Volt = value + VoltOffset ;
// POWER
// ina260.readPowerRegisterInWatts(value) ;
// Power = value ;
}
// /////////////////////////////////////////////////////////////////////
// SOME DEBUG ROUTINES ...
// /////////////////////////////////////////////////////////////////////
void UpDateSerial()
{
Serial.print(Volt, 4) ;
Serial.print(" ") ;
Serial.print(Current, 4) ;
Serial.print(" ") ;
Serial.println(Power, 4) ;
}
void SerialHexOutput(byte value)
{
Serial.print("0x");
if (value < 0x10) Serial.print("0");
Serial.println(value,HEX);
}
void setup()
{
Serial.begin(115200);
// DEFINE GENERAL I/O
pinMode(BEEP, OUTPUT) ; // THE BEEPER
digitalWrite(BEEP, LOW) ; // OFF
pinMode(ALERT, INPUT_PULLUP) ; // FROM INA260, NOT USED
pinMode(ALARM, OUTPUT) ; // ENVICO, NOT USED
digitalWrite(ALARM, LOW) ; // OFF
pinMode(GPIO, INPUT_PULLUP) ; // ENVICO, NOT USED
pinMode(ENVICO, INPUT) ; // ENVICO PRESENCE INDICATOR
pinMode(6, INPUT_PULLUP) ; // OPTION "F"
pinMode(7, INPUT_PULLUP) ; // OPTION "F"
// INIT OLED
display.begin(SH1106_SWITCHCAPVCC);
// SHOW STARTUP SCREEN
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("**** PINGUMOD ****");
display.drawLine(0, 12, 128, 12, WHITE);
display.setTextSize(1);
display.setCursor(0,21);
display.println("A P-U-I MONITOR");
display.setCursor(0,33);
display.println("FOR LABORATORY USE.");
display.setCursor(0,45);
display.println("(C) ETH QUANTUMOPTICS");
display.setCursor(0,57);
display.println("BUILT 14.02.2020");
display.display();
delay(999) ;
// SHOW TOLERANCES SCREEN
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("**** PINGUMOD ****");
display.drawLine(0, 12, 128, 12, WHITE);
display.setTextSize(1);
display.setCursor(0,21);
display.println("A P-U-I MONITOR");
display.setCursor(0,33);
display.println("TOLERANCE < 0.1 %");
display.setCursor(0,45);
display.println("SYSTEM ERROR < 0.15 %");
display.setCursor(0,57);
display.println("TEMP.COEFF.: 10 PPM/K");
display.display();
// INIT INA260
ina260.begin() ;
INA260::ConfigurationRegister configReg = {0};
// average 64 samples for each reading
configReg.avg = INA260::AVG_128 ;
// allow 2.116ms for the ADC sampling of the bus voltage
configReg.vbusct = INA260::VBUSCT_8_244MS ;
// allow 2.116ms also for the ADC sampling of the current
configReg.ishct = INA260::ISHCT_8_244MS ;
// continuously sample voltage and current (this is default)
configReg.mode = INA260::MODE_ISH_VBUS_CONTINUOUS ;
// write the configuration register to the INA260 over I2C
ina260.writeConfigurationRegister(configReg) ;
delay(999) ;
}
void loop()
{
UpdateINA260() ;
UpDateDisplay() ;
UpDateSerial() ;
delay(299) ;
}
// /////////////////////////////////////////////////////////////
// END OF FILE.
// /////////////////////////////////////////////////////////////
The device in action.
✈ First derivative : Option "F"
Option "F" allows for more advanced features like (selective) counting mAh, kWh, ...
You mayst want to use a timer interrupt to poll the status of pins 6 and 7. The time interval
mayst be calculated using the millis() function.
✈ Share your thoughts
The webmaster does not read these comments regularely. Urgent questions should be send via email.
Ads or links to completely uncorrelated things will be removed.
Your Browser says that you allow tracking. Mayst we suggest that you check that DNT thing ?