Categories
Statistics
Flag Counter
Since 08.08.2014
Counts only, if "DNT = disabled".

Your IP is 44.213.60.33
ec2-44-213-60-33.compute-1.a
Info
Valid HTML 4.01 Transitional Creative Commons Lizenzvertrag
rss
เราจะทำแบบวิศวกรผู้ยิ่งใหญ่
We love the King
23. July 2024
Your valuable opinion :
2 stars

Avg. 2.27 from 11 votes.



Amy Winehouse, 14.09.1983 - 23.07.2011
Arduino-Shield-PINGUMOD.php    15066 Bytes    06-06-2024 18:44:02


Arduino/Genuino (Uno) .:. P,U,I - Monitor


Shield "Pingumod", based on the INA260 from TI



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.


Arduino Shield Pingumod

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 :

		
// CALIBRATION VALUES :-)
float VoltOffset = 0.0 ;
float CurrentOffset = 0.0012 ;
		




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"





Pingumod Option 'F'
The character in the top left corner ...
Pingumod Option 'F'
... indicates the mode of operation.

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 ?

 
t1 = 6585 d

t2 = 279 ms

★ ★ ★  Copyright © 2006 - 2024 by changpuak.ch  ★ ★ ★

Impressum