Arduino sobre Ubuntu


Arduino IDE no se encuentra en los repositorios oficiales de Ubuntu, al menos en su última versión, por lo que tenemos que utilizar la web oficial del Proyecto para conseguir este IDE.

Actualmente existen dos versiones de Arduino IDE, una versión que corresponde a la rama 1.8.x y otra rama que corresponde con la versión 1.0.x. La diferencia entre ambas versiones radica en los modelos de placas que soportan: si descargamos la versión 1.8.x de Arduino IDE podemos cambiar en cualquier momento de placa y esta versión lo soportará ( si escogemos la versión 1.0.x hemos de cambiar el programa si cambiamos a una placa moderna, pues la rama 1.0.6 no soporta las placas de Arduino más modernas).

Una vez que hemos descargado el paquete de Arduino IDE desde aquí, descomprimimos el archivo comprimido en cualquier carpeta de nuestra home (mejor hacerlo ena Home y no en Descargas para evitar problemas cuando realizamos limpiezas en el futuro).

En el paquete que hemos descomprimido aparecerán varios archivos e incluso dos ejecutables, uno de ellos llamado Arduino-Builder, pero estos archivos ejecutables no seráa necesario para instalar Arduino IDE en nuestro Ubuntu

Una vez descomprimidos los archivos necesitaremos abrir una terminal en la carpeta donde están todos estos archivos, y desde la consola escribimos lo siguiente:

sudo chmod +x install.sh

Esta orden hará que el archivo de instalación pueda ejecutarse sin tener que ser root. Ahora ejecutamos en la terminal lo siguiente:

./install.sh

Puede que tenga problemas para ejecutar el instalable por los permisos, por lo que si fuese el caso solo tiene que escribir

sudo ./install.sh

Esto hará finalmente que comience la instalación de Arduino IDE en nuestro Ubuntu.

Tras seguir las instrucciones tendremos Arduino IDE instalado en nuestro Ubuntu y unacceso directo en nuestro escritorio. En este caso da igual la versión de Ubuntu que tengamos pues funciona con las últimas 10 versiones de Ubuntu que han sido lanzadas (versiones LTS incluidas).

Problemas con los puertos

Para los que esten aconstumbrados a usar el ide de Arduino sobre Windows , puede que les resulte extraño en la combinación Arduino-Ubuntu donde los puertos virtuales no se muestran del mismo modo, y con esto se desembocan en nuevos problemas, que como vamos a vers son facilmente resolubles.

COM1 es una designación de Windows (TM): se verá como/dev/ttyACM0,/dev/ttyUSB0 o similar en Linux.

El puerto atenuado tiende a significar que no ha configurado primero el tipo de placa: revise la configuración en arduino Menú Herramientas y configure la placa en ‘Uno’, también debería ver la habilitación de ‘puerto’ y el autocompletado.

puerto

El primer problema puede ser que el puerto Serial se encontraba deshabilitado, al momento de ingresar al IDE Arduino no detecta el puerto a pesar de encontrarse conectada la placa a la PC.Al acceder a  Herramientas/ Puerto Serial aparece como deshabilitado y esto NO permitirá que descarguemos nuestro código a la placa. Esto es debido a que el sistema no tiene permisos suficientes para poder establecer una comunicación a travez del puerto USB.

En linux, al conectar un USB le asigna un formato del tipo ttyACM0 o similar y esto se encuentra en la ubicación /dev.

Lo primero que tenemos que hacer es revisar como asigna el sistema operativo los puertos.Vamos abrir una terminal de ubuntu y antes de conectar el Arduino ejecutaremos el siguiente comando.

ls -l /dev | grep ACM

Si no hay ningún dispositivo conectado, no aparecerá ningún resultado. En caso contrario aparecerá asignado con algún nombre.

Ahora conectamos el arduino a la placa y ejecutamos el mismo comando.

Deberá aparecer una linea similar a

crw-rw—- 1 root dialout 166, 0 sep 25 14:42 ttyACM0

En este caso dice que solo el usuario root puede acceder al puerto.

Por lo tanto procedemos a brindarle permisos para los usuarios normales del sistema, ejecutamos e lo siguiente:

sudo chmod 777 /dev/ttyACM0

Donde ttyACM0 es el nombre que nos dio en el primer comando, este puede ser ttyACM1. Al ejecutar este comando les pedirá la contraseña del sistema. Para asegurarnos que ha cambiado los permisos ejecutamos de nuevo:

ls -l /dev | grep ACM

El resultado debe ser similar a:

crwxrwxrwx 1 root dialout 166, 0 sep 25 14:42 ttyACM0

El cambio que notaremos esta en las primeras letras del mensaje de respuesta:

Antes: crw-rw—- 1 root dialout 166, 0 sep 25 14:42 ttyACM0

Ahora: crwxrwxrwx 1 root dialout 166, 0 sep 25 14:42 ttyACM0

Esto ya indica que los demas usuarios tienen acceso al puerto ttyACM0 y por tanto no deberia dar problemas el ide de Arduino para reconocer la placa por el puerto.

Comando dmesg

En el caso de que pueda intentar iniciar sesión en Tools-> Port si existe un puerto que no sea /dev/ttyS0. Intente jugar con estas opciones. Finalmente, buscando en dmesg también puede averiguar qué puerto se ha ubicado para arduino.

Finalmente, otro enfoque es desconectar su arduino, volver a enchufarlo y escribir el siguiente comando:

dmesg | tail

Para registrar el último evento como el que ocurre cuando arduino se conecta a un puerto usb. El comando anterior le mostrará el puerto correcto.

Para obtener mejores resultados, puede usar lo siguiente:

  dmesg | tail -f

Y conecte y desconecte continuamente el arduino del puerto usp hasta que vea cualquier mensaje relacionado con arduino. El parámetro -f permite mostrar en tiempo real los nuevos registros.

Si todo va mal

Si su cuenta de usuario probablemente no tiene permiso para usar el puerto serie y no consigue resolver el problema hay aun dos formas de abordar esto:

  • Más fácil, pero no aconsejable: Ejecute Arduino IDE como root (por ejemplo, inicie desde la línea de comando usando Sudo).
  • La segunda forma más recomendable de hacerlo es agregar su usuario al grupo dialout, que tiene permiso para usar el puerto serie. Use el comando Sudo adduser $USER dialout. Sin embargo, deberá cerrar sesión y volver a iniciarla para que surta efecto (o intente esto ). Para enumerar grupos de usuarios actuales, use groups o id -Gn.

Una vez hecho esto, cuando seleccione el puerto serie correcto (como otros han mencionado, tal vez /dev/ttyUSB0), debería poder escribir, permitiéndole programar el Arduino.

sudo chmod a+rw /dev/ttyACM0  

o

sudo chmod a+rw /dev/ttyUSB0

Espero que se ha de utilidad este post, si tienen algún comentario o duda pueden dejarlo en los comentarios.

Aplicaciones del SCT-013


 El sensor SCT-013 es un sensor de corriente no invasivo cuya principal utilidad es medir la intensidad en corriente alterna que atraviesa un conductor sin necesidad de interconectarlo en serie. Podemos emplear estos sensores con un microcontrolador como Arduino para medir la intensidad o potencia consumida por una carga.

Una de las ventajas más interesantes es su precio, pero sin duda  otra facilidad innegable es que no tenemos que manipular el cable ya que se trata de un sensor de corriente alterna no invasivo.

La precisión del sensor puede ser de 1-2%, pero para ello es muy importante que el núcleo ferromagnético se cierre adecuadamente. Hasta un pequeño hueco de aire puede introducir desviaciones del 10%.

Como desventaja, al ser una carga inductiva, el SCT-013 introduce una variación del ángulo de fase cuyo valor es función de la carga que lo atraviesa, pudiendo llegar a ser de hasta 3º.

SCT-013 principio de funcionamiento

Un factor importante dentro de los transformadores de corriente es el número de espiras o número de vueltas que da el cable al núcleo ferromagnético. Conociendo estos datos y la corriente que circula por uno de los devanados podemos calcular la corriente por el otro devanado.

Esto es debido a que guardan la siguiente relación:

\frac{N_p}{N_s}=\frac{I_s}{I_p}=\frac{V_p}{V_s}

A esta fórmula se le llama relación de transformación porque relaciona el número de espiras del primario (Np), del secundario (Ns), las intensidades del primario (Ip), del secundario (Is), el voltaje del primario (Vp) y del secundario (Vs).

En el caso del sensor de corriente alterna SCT-013 el devanado primario es el cable del aparato que queremos medir y el número de vueltas sería uno. El devanado secundario tiene 2.000 vueltas.

Si aplicamos la relación de transformación a esta situación y suponiendo que queremos medir una intensidad de 10 Amperios, el resultado sería el siguiente.

\frac{N_p}{N_s}=\frac{I_s}{I_p}\Rightarrow I_s=\frac{N_p\times I_p}{N_s}=\frac{1\times 10}{2000}=0,005 A

Como se puede comprobar se produce una transformación de energía pues hemos bajado de 10 A (imposible de medir esta corriente con Arduino) hasta los 0,005 A

Ahora nos faltaría conocer cómo medir la intensidad con Arduino a través de una resistencia de carga o resistencia burden (su función es convertir la corriente en un voltaje limitado que podamos medir, por ejemplo, con Arduino.).

Pero antes de meternos en ello, vamos a ver los tipos de sensores de corriente alterna SCT-013 que podemos encontrar.

Podemos comprar diferentes tipos de sensores de corriente alterna SCT-013 que se pueden organizar en dos grupos. Los que proporcionan una corriente o los que proporcionan un voltaje. La gran diferencia entre ellos es que en los primeros no viene incluida una resistencia de carga y en los segundos sí. Solo el SCT-013-000 es que nos proporciona una corriente y no tiene resistencia de carga. pudiendo medir una corriente de entre 50 mA y 100 A.

El resto de la familia de sensores SCT-013 si que tienen incluida la resistencia de carga. Podemos encontrar varios modelos pero todos tienen un voltaje de salida entre 0V y 1V y por tanto elegir uno u otro sensor SCT-013 dependerá de las necesidades según la intensidad de corriente del circuito a medir.

Con Arduino y otra placas como NodeMCU, solo podemos medir voltajes. Si además ese voltaje varía entre un mínimo y un máximo, solo podremos hacerlo a través de una entrada analógica. Por otro lado, en estos cálculos debemos conocer el consumo aproximado del aparato que vamos a medir. Esto nos permitirá ajustar la precisión. El SCT-013-000 puede medir desde 50 mA hasta los 100 A. El objetivo de calcular la resistencia de carga es obtener un valor de resistencia que nos permita leer el voltaje de la corriente que pasa por el sensor SCT-013-000. Debemos de conseguir la máxima resolución posible y para ello debemos conocer la potencia aproximada del aparato o electrodoméstico que vamos a medir.

El consumo aproximado en vatios deberemos sacarlo de las características técnicas del electrodoméstico o aparato que quiera medir. Como ejemplo hagamos los calculos para una carga de 1kw :

  • Calculo de la corriente :Para una carga de 1kw hacemos los cálculos para 1.000W y un voltaje típico, 220V, calculamos la corriente.
P=V\times I_{RMS}\Rightarrow I_{RMS}=\frac{P}{V}=\frac{1000}{220}=4,54A
  • Convertir la corriente máxima eficaz en corriente de pico.La corriente que hemos obtenido en el paso anterior es corriente eficaz. Ahora hay que convertirla en corriente de pico con la siguiente fórmula.
I_{RMS}=\frac{I_{pico}}{\sqrt{2}}\Rightarrow I_{pico}=I_{RMS}\times \sqrt{2}=4,54\times \sqrt{2}=6,42A
  • Calcular la corriente de pico en el devanado secundario. Con la fórmula de relación de transformación que hemos visto antes, podemos calcular la corriente de pico en el devanado secundario.
\frac{N_p}{N_s}=\frac{I_s}{I_p}\Rightarrow I_s=\frac{N_p\times I_p}{N_s}=\frac{1\times 6,42}{2000}=0,00321 A
  • Maximizar la resolución con el máximo valor de la entrada analógica.En este punto entra en juego la placa que estés utilizando ya que depende de cada placa la referencia interna de la entrada analógica. Esta referencia se llama AREF y nos informa del voltaje máximo que podemos medir en una entrada analógica. Por ejemplo, NodeMCU y Arduino MKR1000 utilizan 3,3V y Arduino UNO utiliza 5V. En este ejemplo vamos a utilizar el AREF de Arduino UNO, 5V. La idea es aplicar la Ley de Ohm pero utilizando la mitad de voltaje. Lo que hemos hecho en los pasos anteriores es calcular la corriente de pico lo que significa que todavía tenemos una onda sinusoidal que varía de positivo a negativo. El objetivo es ajustar la resistencia para que se cumpla la Ley de Ohm y tengamos un voltaje entre 2,5V y -2,5V ya que la corriente la tenemos fija. Por eso, como veremos ahora en la fórmula, debemos dividir AREF entre dos.
R_{carga}=\frac{\frac{AREF}{2}}{I_{pico}}=\frac{\frac{5}{2}}{0,00321}=778\Omega
  • Obteniendo un valor coherente para la resistencia de carga.El valor que nos ha dado para la resistencia de carga es de 778Ω. Este valor no es un valor que podamos encontrar fácilmente. Por eso debemos utilizar varias resistencias en serie que sean más comunes para conseguir un valor aproximado .También se podría hacer con resistencias en paralelo: por ejemplo, podemos poner en serie dos resistencias de 330Ω y una de 100Ω. Esto nos daría un valor de 760Ω más o menos aproximado al que habíamos calculado. Siempre que lo hagas quédate por debajo del valor calculado. Esto evitará que nos salgamos del límite de voltaje establecido por AREF ya que podemos llegar a dañar la placa de desarrollo con el sensor SCT-013.

RESUMEN: Excepto el modelo SCT-013-100, todos los demás modelos tienen una resistencia de burden interna para que la salida sea una señal de tensión de 1V, por lo tanto si elegimos el adecuado ni siquiera tendremos que preocuparnos por ello. Únicamente en el caso del SCT-013-100, carece de resistencia burden interna, por lo que la salida es una señal de ±50mA aunque a efectos prácticos una resistencia de 33Ω en paralelo con el sensor será suficiente.

Offset

En la resistencia de carga vamos a tener un voltaje que varía de 2,5V a -2,5V que sigue siendo una señal sinusoidal por lo que el problema que existe es que ni Arduino ni NodeMCU leen voltajes negativos. Así que tenemos que modificar la señal para que pase a estar en el rango de 0V a 5V.

Eso se hace añadiendo un offset en DC a nuestra señal bastando con sumar 2,5V y estaría resuelto. Esto lo haremos a través de un circuito conocido como circuito offset en DC que básicamente consiste en poner un divisor de tensión y un condensador. El condensador tiene que ser de 10μF y unos pocos cientos de voltios. Esto hace que la reactancia sea baja y la corriente alterna evite la resistencia.

El valor de las resistencias del divisor de tensión puede ser 10kΩ siempre y cuando lo alimentemos a través de la red eléctrica. Si su dispositivo va a funcionar con pilas utilize unas resistencias de 470kΩ para que el consumo sea mínimo.

El circuito

Con todo lo que hemos visto, ya podemos montar el circuito eléctrico donde conectemos el SCT-013 y Arduino.

Antes de ver como conectar los componentes vamos a echar un vistazo al conector que viene incluido en toda la familia SCT-013. Se trata del típico conector de audio que tenemos en todos los auriculares, conocido como jack. Cada tipo de jack hembra es diferente. Deberemos investigar como se hacen las conexiones o bien cortar el cable; encontrará dos cables, uno rojo y otro blanco. Estos colores pueden variar dependiendo del fabricante y del modelo.

En el siguiente esquema vemos el montaje del circuito de offset y la resistencia de carga con un sensor SCR-013-000. Obviamente si usamos otro sensor podemos eliminar la resistencia de carga , y por tanto haciendo mas sencillo el circuito al estar dicha resistencia integrada y calibrada en el propio sensor

SCT-013 ARDUINO-UNO

Por último vamos a ver cómo tenemos que abrazar los cables de alta tensión con el sensor de corriente alterna SCT-013. No vale de cualquier forma, hay que hacerlo de una manera determinada ya que de lo contrario, no estaremos midiendo correctamente el consumo.

Lo más importante es que tenemos que abrazar solo uno de estos cables, en caso contrario la medición será cero. Esto es debido a que por uno de los cables la corriente fluye en un sentido y por el otro cable fluye en sentido contrario. Si abrazamos los dos cables un flujo magnético compensará al otro flujo magnético y se anulará.

Es importante utilizar cables de buena calidad. Por tu seguridad y para conseguir una buena precisión.

Seguramente encuentre tres cables cuando quites la funda que cubre todo. Los colores de la fase suelen ser azul o negro y para el neutro marrón. En uno de estos cables es donde tienes que abrazar el sensor SCT-013(no el de masa) . El tercer cable suele ser de color verde y amarillo y sirve para la toma de tierra por lo que no daría ninguna lectura en caso de abrazar este cable.

Calibración del sensor de corriente alterna SCT-013

Debemos partir del concepto de que nuestros aparatos no son perfectos. Es imposible fabricar cualquier cosa con absoluta precisión. Hay una relación directamente proporcional (incluso exponencial) entre precisión y precio. Cuanto más preciso más caro es el aparato.

Hay tres factores importantes a tener en cuenta y que influyen en la precisión (fuente Open Energy Monitor):

  • La relación de transferencia del transformador
  • El valor de la resistencia de carga y su tolerancia
  • La precisión del ADC a la hora de medir el voltaje en la resistencia de carga

La idea es empezar con la teórica y luego corregir ese valor con la fase experimental. Mucho ojo en la parte experimental. Vamos a trabajar con alto voltaje y puede ser muy peligroso. SI NO ESTÁ SEGURO NO HAGA LA PARTE EXPERIMENTAL.

Proceso de calibración

El proceso de calibración es sencillo. Solo tenemos que aplicar la siguiente fórmula.

F_{calibracion}=\frac{\frac{I_{2RMS}}{I_{1RMS}}}{R_{carga}}

Lo que hacemos es calcular el factor de calibración dividiendo el factor de transformación (corriente máxima eficaz dividida entre la corriente mínima eficaz) entre la resistencia de carga.

El valor que nos da sería el valor que tenemos que poner en el sketch del SCT-013. Si sustituimos los valores para la resistencia de carga que hemos calculado quedaría de la siguiente manera.

F_{calibracion}=\frac{\frac{I_{2RMS}}{I_{1RMS}}}{R_{carga}}=\frac{\frac{100}{0.05}}{760}=2,63

Este sería el valor teórico. Ya tendríamos algo por donde empezar. Para asegurarnos de que realmente este factor de calibración es bueno sería interesante conectar un aparato del cual sepamos su consumo aproximado.Por ejemplo, podemos utilizar una bombilla incandescente. Se recomienda una con bastante potencia para no perder resolución. El sensor SCT-013 nos dará una resolución de 2 decimales por lo tanto, si queremos calibrar bien este sensor debemos utilizar un aparato que consuma más de 20W.

A efectos prácticos tenemos que medir la corriente real con la corriente que está dando el sensor SCT-013 para lo cual podemos usar diferentes métodos.

  • Midiendo el voltaje de la red eléctrica :Para medir el voltaje necesitarás un multímetro. Lo primero es configurar el aparato correctamente. Tienes que seleccionar voltaje en alterna y el rango correspondiente a 220V. Además tienes que conectar el cable rojo (suele ser de este color) en voltios y el cable negro en COM. Una vez configurado debes meter las dos puntas en un enchufe. Cada una en un agujero. Da lo mismo en que agujero metas la punta. La diferencia es que te dará o positivo o negativo. Esto te dará un valor de voltaje y es el que tienes que apuntar y actualizar en el sketch.Las mediciones en este punto dependen mucho de la calidad del multímetro. Este es otro caso claro donde el precio tiene que ver mucho con la precisión.
  • Midiendo la corriente alterna con el multímetro: La corriente es algo más complicado ya que tenemos que cortar el cable y poner el mutímetro en serie con el cable, como si fuera una resistencia. En estos casos es interesante tener una clema, bornera o ficha de empalme. Eso sí, que soporte la corriente que va a pasar por la bornera. No pongas una de electrónica porque puedes dañar la instalación. Antes de nada vamos a ver cómo configurar el multímetro para medir una corriente alterna. Es diferente a la configuración de voltaje en alterna. Es importante que también tengas conectado el sensor de corriente alterna SCT-013 para poder comparar una medida y otra. Cuando mido con el multímetro obtengo el siguiente resultado. ida de 0,33A. Si hacemos los cálculos para obtener la potencia se obtiene lo siguiente P=V x I=230v x 0,33a=75,9w. Con los datos obtenidos anteriormente donde teníamos una potencia de unos 120W, comprobamos que este factor de calibración hay que ajustarlo. Por lo tanto, el factor de calibración está mal. Hay que corregirlo. Pero ahora que tenemos los datos experimentales resulta sencillo. Si el valor obtenido a través del sensor de corriente alterna SCT-013 es mayor, baja el factor de corrección. Ajusta dicho valor hasta conseguir un dato aproximado al que has obtenido en el multímetro. Solo es cuestión de ir modificando y cargando el código en la placa hasta que tener un valor correcto. No te olvides de modificar también el valor del voltaje obtenido. Al final con un factor de calibración de 1.6 y un voltaje de 230V consigo ajustarme a la corriente que nos mostraba el multímetro.

Código final para obtener la potencia con el sensor SCT-013

Gracias a Emonlib no tenemos que hacer cálculos complejos pues podemos ayudarnos en esta tarea de una librería. En concreto vamos a utilizar Emonlib creado por el proyecto Open Energy Monitor. Open Energy Monitor es un proyecto que nos proporciona diferente hardware para medir el consumo en multitud de dispositivos y aparatos. Han creado sus propias placas compatibles con Arduino. Para inlcuir esta libreria Abra el gestor de librería y busque Emonlib. También puede descargarlo desde el repositorio en GitHub.Con unas pocas líneas de código obtendremos de una forma muy sencilla la potencia que está consumiendo el aparato. Lo primero es el voltaje de tu red eléctrica.

En la función setup() iniciamos la comunicación serie para poder mostrar los datos a través del monitor serie.

Luego iniciamos el objeto que hemos creado de la clase EnergyMonitor con la función current(pinAnalogico, factorCalibracion). Esta función admite dos parámetros:

  • pinAnalogico: es el pin analógico donde hemos conectado el sensor de corriente alterna SCT-013.
  • factorCalibracion: es un valor que tenemos que calcular para corregir errores de diferentes tipos como la tolerancia de la resistencia de carga o del propio sensor SCT-013.

El pin analógico no tiene duda. Según el esquema mostrado más arriba vamos a utilizar el A0 así que pasamos como argumento un 0. El factor de corrección de momento lo dejamos a 2,6. En el siguiente apartado veremos como se calcula.

Por último en la función loop() obtenemos la corriente eficaz llamando a la función calcIrms(numMuestras). Esta función admite un parámetro:

  • numMuestras: indica cuantas muestras tiene que tomar para calcular la corriente eficaz.

El número de muestras es importante. Como hemos estado hablando a lo largo de todo este artículo, estamos trabajando con una señal sinusoidal. Esto quiere decir que tiene ciclos que se van repitiendo en el tiempo.

El número de muestras indica el número de veces que se va a leer la señal para obtener el valor de la corriente eficaz. Es interesante que estas muestras sean en ciclos completos. Según la velocidad de acceso a los pines analógicos con Arduino UNO, aproximadamente podemos medir 106 muestras en cada ciclo. Si está utilizando otro microcontrolador este valor puede variar.

Si queremos medir 14 ciclos (un valor recomendado por el proyecto Open Energy Monitor), tendremos que medir 14\times 106 = 1484 muestras . De aquí viene el valor que se pasa a la función calcIrms().

Por último mostramos toda esta información a través del monitor serie.

// Include Emon Library
#include "EmonLib.h"
 
// Crear una instancia EnergyMonitor
EnergyMonitor energyMonitor;
 
// Voltaje de nuestra red eléctrica
float voltajeRed = 230.0;
 
void setup()
{
  Serial.begin(9600);
 
  // Iniciamos la clase indicando
  // Número de pin: donde tenemos conectado el SCT-013
  // Valor de calibración: valor obtenido de la calibración teórica
  energyMonitor.current(0, 1.6);
}
 
void loop()
{
  // Obtenemos el valor de la corriente eficaz
  // Pasamos el número de muestras que queremos tomar
  double Irms = energyMonitor.calcIrms(1484);
 
  // Calculamos la potencia aparente
  double potencia =  Irms * voltajeRed;
 
  // Mostramos la información por el monitor serie
  Serial.print("Potencia = ");
  Serial.print(potencia);
  Serial.print("    Irms = ");
  Serial.println(Irms);
}

Si no deseamos usar la librería también podemos realizar los cálculos internos nosotros mismos, si bien el código ahora ya no queda tan claro como la version anterior:

const float FACTOR = 30; //30A/1V

const float VMIN = 1.08;
const float VMAX = 3.92;

const float ADCV = 5.0;  //Para Vcc
//const float ADCV = 1.1; //Para referencia interna  


void setup()
{
   Serial.begin(9600);
   //analogReference(INTERNAL);
}

void printMeasure(String prefix, float value, String postfix)
{
   Serial.print(prefix);
   Serial.print(value, 3);
   Serial.println(postfix);
}

void loop()
{
   float currentRMS = getCorriente();
   float power = 230.0 * currentRMS;

   printMeasure("Irms: ", currentRMS, "A ,");
   printMeasure("Potencia: ", power, "W");
   delay(1000);
}

float getCorriente()
{
   float voltage;
   float corriente;
   float sum = 0;
   long tiempo = millis();
   int counter = 0;

   while (millis() - tiempo < 500)
   {
      voltage = analogRead(A0) * ADCV / 1023.0;
      corriente = fmap(voltage, VMIN, VMAX, -FACTOR, FACTOR);

      sum += sq(corriente);
      counter = counter + 1;
      delay(1);
   }

   corriente = sqrt(sum / counter);
   return(corriente);
}

// cambio de escala entre floats
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Mejora

Añadir un ADC con entrada diferencial, nos permite realizar mediciones de tensiones positivas y negativas, como el ADS1115. Esta es la opción que vamos a comentar como mejora.

  •  Este convertidor analógico digital tiene una resolución de 16 bits y una interfaz I2C para un control cómodo.
  • El módulo es adecuado para todos los microcontroladores actuales con 2.0V – 5.5V, el uso con Raspberry es posible sin problemas.
  • La frecuencia de muestro del módulo es programable hasta 860/s.
  • Gracias a la PGA interna, es posible amplificar hasta 16 veces la señal analógica.

Ajustando la ganancia del ADS1115 a 2.048V estaremos dentro del rango de ±1.414V. En el caso de un sensor de 30A tendremos una precisión de 1.87mA, y 6,25 mA para un sensor de 100A.

Si usáis un SCT-013-100 con salida de ±50mA, tendremos que añadir una resistencia burden externa de 33Ω y subir la ganancia del ADS1115 a 4.096V para cumplir con el rango de ±2.33V.

Si no queréis usar un ADC externo, podéis usar la solución más convencional, que es añadir un circuito que nos permita añadir un offset central como vimos al principio del post.

Si habéis usado el montaje con un SCT-013 con salida de ±1V RMS y ADS1115, el código necesario es similar al que vimos en la entrada sobre el ADS1115. Necesitarémios la librería de Adafruit para el ADS1115.

Para que el ADS1115 muestree a una velocidad superior, deberemos modificar la siguiente línea del fichero ‘Adafruit_ADS1015.h’

#define ADS1115_CONVERSIONDELAY

Por,

#define ADS1115_CONVERSIONDELAY

Con esto conseguiremos bajar el tiempo de muestreo de unos 8-9 ms (unos 100 Hz) a 1.8 aprox (unos 500 Hz). Con eso nos alejamos de la frecuencia de Nyquist, y mejoramos el comportamiento de la medición.

#include <Wire.h>
#include <Adafruit_ADS1015.h>
 
Adafruit_ADS1115 ads;
  
const float FACTOR = 30; //30A/1V

const float multiplier = 0.0625F;
 
void setup()
{
  Serial.begin(9600);
 
  ads.setGain(GAIN_TWO);        // ±2.048V  1 bit = 0.0625mV
  ads.begin();
}

void printMeasure(String prefix, float value, String postfix)
{
 Serial.print(prefix);
 Serial.print(value, 3);
 Serial.println(postfix);
}
 
void loop()
{
 float currentRMS = getCorriente();
 float power = 230.0 * currentRMS;
 
 printMeasure("Irms: ", currentRMS, "A ,");
 printMeasure("Potencia: ", power, "W");
 delay(1000);
}
 
float getCorriente()
{
 float voltage;
 float corriente;
 float sum = 0;
 long tiempo = millis();
 int counter = 0;
 
 while (millis() - tiempo < 1000)
 {
   voltage = ads.readADC_Differential_0_1() * multiplier;
   corriente = voltage * FACTOR;
   corriente /= 1000.0;
 
   sum += sq(corriente);
   counter = counter + 1;
  }
 
 corriente = sqrt(sum / counter);
 return(corriente);
}

Otra versión es emplear el máximo y el mínimo de la medición, y calcular la medición a partir del valor de pico. Los resultados deberían ser similares a los vistos en el ejemplo con la suma al cuadrado. Para ello, podéis sustituir la función por la siguiente.

float getCorriente()
{
 long tiempo = millis();
 long rawAdc = ads.readADC_Differential_0_1();
 long minRaw = rawAdc;
 long maxRaw = rawAdc;
 while (millis() - tiempo < 1000)
 {
   rawAdc = ads.readADC_Differential_0_1();
   maxRaw = maxRaw > rawAdc ? maxRaw : rawAdc;
   minRaw = minRaw < rawAdc ? minRaw : rawAdc;
 }

  maxRaw = maxRaw > -minRaw ? maxRaw : -minRaw;
  float voltagePeak = maxRaw * multiplier / 1000;
  float voltageRMS = voltagePeak * 0.70710678118;
  float currentRMS = voltageRMS * FACTOR;
  return(currentRMS);
}

Otros sensores diferentes al SCT-013

Aunque depende mucho de las necesidades del aparato que quieras medir, estos sensores invasivos (debes alterar el cable que conecta el aparato) pueden ser una buena alternativa.

  • Interruptor Sonoff WiFi y medidor de corriente de Itead
  • ACS712
  • Pololu ACS714

Cualquiera de estos sensores puede hacer la misma función. Solo tendrás que elegir aquel que se amolde mejor a las necesidades de corriente.

Fuentes: https://adafruit.com, http:// opennergymonitor.com, http:// luisllamas.es,http:// programarfacil.es

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