Monitorización de consumo energético en CC con el sensor INA226

En el pasado, muchos proyectos de amperímetros se basaban ​​en sensores de corriente de efecto Hall como el ACS712,  en amplificadores de detección de corriente de lado alto como el MAX4080SASA o fabricados con amplificadores operacionales , lo cual tiene un pequeño inconveniente:  estos sistemas tienen una salida analógica que luego debe digitalizarse para procesarse en un sistema de adquisición de datos como Arduino.

Para intentar superar esos inconvenientes existe un CI muy interesante como el INA226, chip fabricado por Texas Instruments, que es un sensor de 36V, 16-bit, ultra-precise i2c output current/voltage/power monitor w/alert.

 El sensor INA226 tiene una salida digital e incorpora un ADC de 16 bits por lo que se obtiene una gran exactitud y precisión. Mide la corriente y el voltaje y calcula la potencia mientras Arduino se comunica con el chip, pudiendo presentar las medidas en una pantalla LCD y almacenarlas en una tarjeta micro SD. 

Este chip opera con un voltaje máximo de 36 voltios, mientras que la corriente está limitada solo por la derivación utilizada. Hay algunas bibliotecas para el chip INA226, peros se puede utilizar la biblioteca Korneliusz Jarzebski que me parece bastante completa incluso si tuviera que hacer algunos cambios en dos funciones.

Existen numerosas aplicaciones posibles para esta herramienta de monitorización: dispositivos alimentados por batería como scooters o bicicletas asistidas por pedaleo, paneles fotovoltaicos, etc.

En las mediciones de corriente con el shunt hay dos formas de insertarlo:

  • Tierra (lado bajo): la derivación está conectada entre la carga y la tierra.
  • Hacia la fuente de alimentación (lado alto): el shunt está conectado entre la fuente de alimentación y la carga.

El circuito integrado INA226, de Texas Instruments, es un dispositivo digital que mide la corriente con una derivación de lado alto o lado bajo y también mide el voltaje, calcula la potencia y proporciona una alarma multifuncional. El diagrama de bloques de dicho integrado es el siguiente:

INA226 - SBOS547A

La resolución de la tensión de derivación es de 2,5 m V con una escala completa de 32768×2,5 = 81,92 mV. Para la tensión VBUS, la resolución es de 1,25 mV con un fondo de escala teórico de 40,96 V, incluso si no se deben superar los 36 V. La resolución de la potencia es 25 veces mayor que la de la corriente, con un fondo de escala que depende del shunt utilizado. De modo que el sistema tiene una precisión de medición notable.

El ADC interno se basa en un convertidor delta-sigma de 16 bits (ΔΣ) con una frecuencia de muestreo típica de 500 kHz (± 30%), por lo que también es adecuado para corrientes que cambian rápidamente con el tiempo.El chip tiene 10 pines y dimensiones muy pequeñas, con una caja DGS (VSSOP).

El INA226 puede proporcionar una alerta de hardware o software si una variable, seleccionada por el usuario, ha superado un límite. El usuario puede seleccionar una de las cinco funciones disponibles para monitorear y / o establecer el bit de conversión lista.  Las cinco funciones de alerta que se pueden monitorear son:

  • Sobre-límite de voltaje de derivación (SOL): excede el umbral de corriente máximo;
  • Bajo límite de voltaje de derivación (SUL): excede el umbral de corriente mínimo;
  •  Límite de voltaje de bus (BOL): excede el umbral de voltaje máximo;
  • Límite inferior de voltaje de bus (BUL): superando el umbral de voltaje mínimo;
  •  Power Over-Limit (POL): superando el umbral de potencia máxima;

La salida de alerta es de colector abierto y se puede conectar fácilmente a un dispositivo de bloqueo.  Para simplificar, podemos leer la alerta de tipo de sobre-límite de voltaje de derivación (SOL) a través del software y presentarla en la pantalla. Gracias a este sensor pues podemos calcular la potencia con un Arduino presentando estas en una pantalla LCD almacenándolas en una tarjeta micro SD. 

Este chip funciona con un voltaje máximo de 36 voltios, mientras que la corriente está limitada solo por la derivación utilizada. La resolución del voltaje de derivación es de 2.5 m V con una escala total de 32768×2.5 = 81.92mV. 

El dispositivo tiene dos pines de dirección, A0 y A1. La siguiente tabla enumera las conexiones de clavijas para cada una de las 16 direcciones posibles.

A1A0Dirección del esclavoA1A0Dirección del esclavo
GNDGND1000000SDAGND1001000
GNDVS1000001SDAVS1001001
GNDSDA1000010SDASDA1001010
GNDSCL1000011SDASCL1001011
VSGND1000100SCLGND1001100
VSVS1000101SCLVS1001101
VSSDA1000110SCLSDA1001110
VSSCL1000111SCLSCL1001111

El módulo monta dos resistencias pull-down (R2 y R3), por lo que la dirección es 0x40 si no conectamos los jumpers colocados en el lado opuesto al de los componentes (ver figura 2 a la derecha).Con la resistencia de derivación de 0.1 W (R100), montada en el módulo, hay una resolución de corriente de 2.5 m V / 0.1 = 0.025 mA, una escala completa de 81.92mV / 0.1 W = 819.2 mA y una resolución de potencia de 0.025 mA * 25 = 0,625 mW. 

Una opción muy aconsejable es montar un shunt externo para corrientes altas, desoldando el interno e insertar un filtro RC,

Pantalla LCD

LCDfunciónArduinoLCDfunciónArduino 
14Línea de bus de datos D7A35 5R / W – Lectura / EscrituraGnd
13Línea de bus de datos D6A24 4RS – Registrarse SeleccionarD7
12Línea de bus de datos D5D43VEE
11Línea de bus de datos D4D52VCC ( + 5V)VCC
6 6E – Habilitar señalD61VSS (GND)Gnd

El Ci se puede complementar con una pantalla LCD común de dos líneas de 16 caracteres con controlador compatible con Hitachi HD44780 y una retroiluminada equipada con diodos LED de alta eficiencia que consume alrededor de 20 mA, que puede reducierse a 10 mA con una resistencia externa en serie con la iluminaciona. Las conexiones con Arduino Nano son las siguientes:

El módulo micro SD

La siguiente tabla muestra las conexiones y pines dedicados a la microSD:

J2Módulo SDArduino
6 6CSD10
5 5SCKD13
4 4MOSID11
3MISOD12
2VCC+5 V
1GNDGND

Cálculos para la derivación utilizada

Podemos usar cualquier SHUNT de potencia. Como ejemplo el ICE 680R. Este shunt tiene una salida de 100 mV con una corriente de 25 A, por lo que Rs = 0.1 / 25 = 0.004 Ω.
Desoldand la derivación de 0.1 Ω, montada en el módulo INA226, y soldarmos un conensador de 1 MF y dos resistencias de filtro. Este recurso permite el filtrado RC, como sugiere el fabricante del chip.

Con el voltaje de derivación a escala completa en mente, la corriente máxima medible ahora se convierte en:Ifs = 81,92 mV / 4 mΩ = 20,48 A

La resolución actual será: 20,48 / 32768 = 0,625 mA.

La función de calibración tiene como parámetros de entrada la resistencia en derivación y la corriente máxima, en nuestro caso: rShunt = 0.004 Ω e iMaxExpected = 20.48 A.

Calculo de varias variables:

  • currentLSB = iMaxExpected / 32768 = 20,48 / 32768 = 0,625 [mA]
  • alibrationValue = 0,00512 / currentLSB / rShunt = 0,00512 / 0,000625 / 0,004 = 2,048
  •    powerLSB = currentLSB * 25 = 0.000625 * 25 = 15.625 [mW]

Otro dato para pasar al programa es el umbral actual de la función setShuntVoltageLimit .Si establecemos el límite superior del instrumento en 20 A, podemos calcular:setShuntVoltageLimit = 0,004 Ω * 20 A = 0,08 V

El montaje del circuito final

Podemos usar un Arduino Nano, pero por supuesto se puedne usar otras placas Arduino, como Arduino Uno o Arduino Pro, (pero esta placa es muy compacta, completa con un adaptador USB y se puede montar en un prototipo de pcb pretaladrado).

Arduino Nano tiene su propio regulador de 5V, un Low DropOut tipo AMS1117, pero podemos alimentar el sistema con un LM7805 común, esto se debe a que el primero acepta un voltaje de entrada máximo de 15V contra los 35V del segundo. Si tenemos que alimentar ArduINA226 con el voltaje que tengo que monitorear, es mejor tener valores compatibles. Ademas otra razón es la luz de fondo de la pantalla. El consumo de todo el sistema ronda los 45 mA. El diodo Schottky D1, que tiene una caída de solo 0,2 V, se utiliza para evitar conflictos entre la fuente de alimentación externa y la fuente de alimentación USB.

La figura siguiente muestra el diagrama de cableado :

Lista de componentes

componentedescripcióncomponentedescripción
C1, C2, C4100 nF 50V, condensador cerámicoR4Resistencia de 100 ohmios , ± 5%, 0.5 W
C310 MF 50V, condensador electrolíticoU1Tablero Arduino Nano
C41 MF 25V, condensador cerámicoU2LM7805, regulador de 5V
D11N5819, diodo SchottkyU3Módulo INA226
Rp1Recortadora resistiva de 22k WmonitorLCD de 2 filas x 16 columnas
R1, R210 ohmios , ± 5%, resistencia de 0.25 Wmódulo SDTarjeta micro SD con niveles de 5V
R34.7 kohmios , ± 5%, resistencia de 0.25 WSw1Pulsador normalmente abierto (NO)

Nota : el prefijo de capacidad ‘M’ significa microfaradio (1e-6 F)

 

Cambios en la biblioteca INA226.cpp

Hay algunas bibliotecas para el chip INA226, siendo la biblioteca Korneliusz Jarzebski bastante completa cmbiando la función de calibración porque la corriente de derivación era incorrecta. La función setShuntVoltageLimit también estaba mal.

 

Aquí están las funciones modificadas, para reemplazar las originales:

bool INA226::calibrate(float rShunt, float iMaxExpected){ // MODIFIED by GCAR
    uint16_t calibrationValue;
    float iMaxPossible;
    iMaxPossible = vShuntMax / rShunt;
    currentLSB = iMaxExpected / 32768;// calculate current resolution
    powerLSB = currentLSB * 25;// power resolution
    calibrationValue = (uint16_t)((0.00512) / (currentLSB * rShunt));
    writeRegister16(INA226_REG_CALIBRATION, calibrationValue);
    return true;
}

void INA226::setShuntVoltageLimit(float voltage){// MODIFIED by GCAR
    uint16_t value = voltage/2.5e-6;
    writeRegister16(INA226_REG_ALERTLIMIT, value);
}


El programa

El programa requiere solo dos parámetros que son: rShunt e iMaxExpected . Si desea utilizar una alerta, debe decidir qué señal le interesa. Si elige la corriente máxima, le interesara el voltaje de derivación máximo y el uso las funciones enableShuntOverLimitAlert y setShuntVoltageLimit . 

En el caso de un sistema alimentado por baterías de iones de litio o plomo, sería más útil comprobar la tensión mínima de VBUS con las funciones enableBusUnderLimitAlert y setBusVoltageLimit .

Si no hemos insertado la tarjeta SD o si no es válida, aparecerá el mensaje «¡SD no presente!» 

.Al final de la función setup (), el programa imprime «Push to Start» y espera a que se presione el botón SS, si el SD está presente, comienza a adquirir las medidas en archivo, de lo contrario las imprime solo en la pantalla .

En cuanto a la pantalla LCD, dos filas y 16 columnas son suficientes, por lo que debe administrar bien sus impresiones. Teniendo en cuenta la resolución de las variables a imprimir, estos son sus formatos:

  •  Voltaje del bus: V = xx.xxx (8 caracteres)
  • Corriente de derivación: I = xx.xxx (8 caracteres)
  • Potencia del bus: W = xxx.xx (8 caracteres impresos)

Entonces, en la primera línea veremosel voltaje y la potencia, separados por un espacio y en la segunda la corriente y el número de muestras guardadas en SD (si está insertada), de esta manera:V = xx.xxx W = xxx.xxI = xx.xxx N = xxxxx

Si se produce la alerta cuando se excede el límite máximo de corriente (SOL, sobre límite de voltaje de derivación), aparecerá la impresión «ALERTA SOL» en la segunda línea, en lugar del valor actual y en la primera el voltaje de derivación:Derivación V = xx.xxxxxALERTA SOL

/ * Programar ArduINA226 a corriente, voltaje y potencia
 con módulo Arduino Nano e INA226
utiliza la biblioteca Korneliusz Jarzebski para INA226 (modificado)
guardar las mediciones en SD si está presente
Giovanni Carrera, 14/03/2020
 * /

#include <SPI.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <SD.h>
#include <INA226.h>
// Pines de LCD
#define rs 7
#define en 6
#define d4 5
#define d5 4
#define d6 A2
#define d7 A3
#define SSbutton 2
#define SD_CS 10
// inicializar la biblioteca asociando cualquier pin de interfaz LCD necesario
LiquidCrystal lcd (rs, en, d4, d5, d6, d7);
INA226 ina;


char bline [17] = ""; // línea en blanco
const int deltat = 500; // período de muestreo en milisegundos
cmilli largo sin firmar, pmilli;
boolean SDOk = verdadero, FileHeader = verdadero, ACQ = falso;
unsigned int ns = 0;

void setup () {
  // configura el número de columnas y filas de la LCD:
  lcd. comienzo (16, 2);
  pinMode (SSbutton, INPUT); // Botón de inicio / parada
  pinMode (SD_CS, SALIDA); // Selección de chip SD
  // La dirección INA226 predeterminada es 0x40
  ina.begin (0x40);
  lcd.print ("ArduINA226");
  lcd.setCursor (0, 1); // imprime en la segunda fila
  lcd.print ("Monitor de energía");
  // Configurar INA226
  ina.configure (INA226_AVERAGES_1, INA226_BUS_CONV_TIME_1100US, INA226_SHUNT_CONV_TIME_1100US, INA226_MODE_SHUNT_BUS_CONT);
  // Calibrar INA226. Rshunt = 0,004 ohmios, corriente máxima esperada = 20,48 A
  ina.calibrate (0,004, 20,48);
  ina.enableShuntOverLimitAlert (); // habilita la alerta de sobretensión de derivación, corriente por encima del límite
  ina.setShuntVoltageLimit (0.08); // límite de corriente = 20 A para 0,004 ohmios
  ina.setAlertLatch (verdadero);
  if (! SD.begin (SD_CS)) {
    LCDprintLine ("¡SD no está presente!", 1);
    delay (5000);
    SDOk = false;
  }
  LCDprintLine ("Pulsar para iniciar", 1);
  while (digitalRead (SSbutton) == HIGH) {}; // esperar el inicio
  if (SDOk) ACQ = true;
}


void loop () {
  cmilli = milis ();
  si (cmilli - pmilli> deltat) {
    pmilli = cmilli;
    voltios flotantes = ina.readBusVoltage ();
    corriente flotante = ina.readShuntCurrent ();
    LCDprintLine ("V =", 0); // imprimir voltaje del bus
    lcd.print (voltios, 3); 
    float power = ina.readBusPower (); // INA calcula la potencia
// potencia flotante = voltios * corriente; // Arduino calcula la potencia
    lcd.print ("W ="); // potencia de impresión
    lcd.print (potencia, 4);
    flotar Vshunt = ina.readShuntVoltage ();
    String dataString = String (voltios, 3) + ',' + String (actual, 4) + ',' + String (potencia, 4) + ',' + String (Vshunt, 6);
    si (ACQ) {
      Archivo dataFile = SD.open ("powerlog.csv", FILE_WRITE);     
      if (dataFile) {
        if (FileHeader) {// imprimir el encabezado del archivo
          dataFile.print ("Deltat [ms] =");
          dataFile.println (deltat);
          dataFile.println ("Vbus [V], Ishu [A], P [W], Vshu [V]");
          FileHeader = false;
        }
        dataFile.println (dataString);
        ns ++; // número de muestras adquiridas
        dataFile.close ();
        if (digitalRead (SSbutton) == LOW && ns> = 10) {// detente después de al menos 10 muestras
          ACQ = false; // detener la adquisición
          LCDprintLine (Cadena (ns), 1);
          lcd.print ("muestras");
          delay (5000);        
        }
      } else {
        LCDprintLine ("¡No se puede abrir el archivo!", 1);
        ACQ = false;
        delay (5000);
      }
    }
    if (ina.isAlert ()) {
      LCDprintLine ("Shunt V =", 0);
      lcd.print (Vshunt, 5);
      LCDprintLine ("ALERTA SOL", 1);
    }
    else {
      LCDprintLine ("I =", 1);
      lcd.print (actual, 3);
      if(ACQ) {
        dataString = "N =" + String (ns);
        lcd.print (dataString); // número de impresión de la muestra adquirida
      }     
    }
  }
}
/ ************************** Funciones ********************* **** /
void LCDprintLine (texto de cadena, línea de bytes) {
   lcd.setCursor (0, línea);
   lcd.print (bline); // borra la segunda fila
   lcd.setCursor (0, línea);
   lcd.print (texto); // imprimir texto
}

El sistema puede funcionar incluso con periodos delta muy pequeños, pero la visualización, las impresiones y la escritura en archivo llevan algo de tiempo: si queremos reducirlo, por ejemplo a 100 ms, las medidas deben mostrarse cada 5 muestras. 

También se pueden implementar algunos circuitos de hardware, como usar la salida de alerta para desconectar la fuente de alimentación a la carga a través de un relé estático o electromecánico o para hacer un sonido de timbre a través de Arduino.

ArduINa226, si se ha insertado una tarjeta micro SD, transfiere las medidas al archivo «powerlog.csv».La adquisición comienza presionando el botón ‘SS’ (Start / Stop) que también sirve para finalizar la grabación después de al menos diez muestras.

Las dos primeras líneas contienen el período de muestreo deltat en milisegundos y los nombres de las señales, como se ve en el siguiente ejemplo:Deltat [ms] = 500Vbus [V], Ishu [A], P [W], Vshu [V]10.021,0.0950,0.9531,0.00037510.023,0.0944,0.9531,0.00037710.023,0.0944,0.9531,0.000375……Los datos se agregan al archivo que no se sobrescribe.

Calculo de la potencia

La energía suministrada por la fuente es la integral de la potencia a lo largo del tiempo. El sistema más simple para hacer la integral definida de una función, aunque de manera bastante aproximada, es el de los trapezoides. La curva de potencia se aproxima en muchos trapecios, de los cuales es fácil calcular el área, para dos puntos tenemos:

La integral será igual a la suma de las áreas individuales. 

Este método dará mejores resultados para intervalos de tiempo más pequeños, en nuestro caso:

(t2-t1) = deltat yf (t) es la potencia P (t), entonces

E2 = deltat * (P1 + P2) / 2 + E1 [J]

Donde P1 y P2 son las potencias en dos instantes sucesivos t1, t2 y E1, E2 las energías respectivas expresadas en W × s = julios , que se pueden expresar fácilmente en vatios hora [Wh] dividiendo los julios por 3600

Para calcular la energía con Arduino:

watthour = watthour + (potencia + ppotencia) /2.0*deltath; // entero para trapezoides

ppower = potencia; // luego actualiza el poderDonde potencia es la potencia actual , ppower la del instante anterior ydeltath = deltat / 3.6e6; // período de muestreo en horas (deltat en [ms])

Al principio, debe restablecer la variable watthour  pero el autor no agregoesta función porque no tenía más espacio en la pantalla y preferio calcular la energía en el PC con algoritmos de integración más sofisticados.

Fuente :http://ardupiclab.blogspot.com/2020/03/the-arduina226-power-monitor.html

Deja una respuesta