Consumo eléctrico
Se trata de medir el consumo eléctrico en vatios del domicilio. Se hace una medida cada minuto que se envía a una página en PHP que almacena los datos y otra que los muestra en una gráfica.
Se usa:
-Un módulo ESP8266-12 soldado a una placa adaptadora y un regulador de 3,3 voltios ( AMS1117)
-Un sensor SCT013. El de 30A, no el 100A.
-Tres resistencia de 27k, 1k8 y 56 ohmios.
-Un condensador de 10µF (y otro de 100µF para estabilizar voltaje)
Con este circuito
En la unión del cable amarillo del sensor y la resistencia de 56 ohmios aparece una tensión alterna proporcional al consumo.
El ESP8266 mide esa tensión muchas veces por su terminal analógico quedándose solo con el valor positivo más alto. Este valor se multiplica por un factor para obtener el consumo en vatios. Para obtener este factor, es necesario hacer una medición conectando una carga resistiva a un enchufe y medir su consumo con un amperímetro. No vale fiarse si tenemos por ejemplo una estufa de 1000w, ese valor puede variar bastante de la realidad. Ponemos nuestro sensor SCT013 cogiendo un solo hilo eléctrico y los valores que nos de los multiplicamos por un factor x para que coincidan con los medidos por el amperímetro (multiplicados por 250v) o vatímetro.
Seguidamente vemos el código generado en el IDE de Arduino para pasarlo al esp8266. Cada minuto el programa hace 200 capturas cuatro veces en el pin analógico y se queda con la más alta tras una media. Seguidamente conecta con el host que esta alojado en mi NAS domestico y le pasa el valor medido a un scrip procesar.php
Si no tenemos NAS, los valores podrían alojarse en un servidor externo que soporte php.
En el ino de Arduino se ha incluido la libreria ArduinoOTA.h, esto nos permite actualizar el programa alojado en el esp8266 via wifi sin conectarnos fisicamente por serial con el (muy cómodo).
El script procesar.php captura el valor enviado por consumo.ino y lo pasa a vatios multiplicandolo por 9,8 (que he calculado anteriormente con mediciones comparadas con un watimetro o un amperimetro). Este valor lo guarda en un fichero (datosSCT13.txt) en el propio NAS para usarlo en una gráfica. El fichero se borra aprox. a las 00 horas de cada día, pero antes se guarda la media de consumo de ese día en otro fichero mediadiaria.txt y que con mediadiaria.php nos permite hacer otra gráfica de consumos diarios.
<?
//Joaquín Paredes 2017
//www.jopapa.me
//procesar.php
//Si faltan 6' para las 00h, borra el fichero
$localtime = localtime(); //pone tiempo en array
$hora=($localtime[2]); //la hora en posición 2 del array
$minuto=($localtime[1]);
if ($hora==23){
if ($minuto <= 59 and $minuto >58) { //echo "Borrar fichero antes de las 12 de la noche"
$ydata = str_getcsv(file_get_contents('datosSCT13.txt')); //convierte a array el fichero .txt
$cuenta = count($ydata); //cuenta # de datos
$media_dia=0;
for ($i = 0; $i <= $cuenta-2 ; $i++) { //Se calcula la media del dia
$media_dia=$media_dia+$ydata[$i];
}
$media_dia=($media_dia/($cuenta-1));
$media_dia=round($media_dia);
$file=fopen("mediadiaria.txt","a"); //Abre el fichero para guardar la media diaria
fputs($file, $media_dia); //vamos añadiendo el contenido mas una coma
fputs($file, ",");
fclose($file);
unlink('datosSCT13.txt'); //Borra los datos diarios
}
}
$wa = $_GET['datavalor']; //captura el valor enviado por esp8266
$wa=($wa-215); //480mV voltaje referencia 27k+1k8 sobre 3,3v Restar valor para dejar a cero sin carga
if ($wa < 0){
$wa=0;
}
$wa=($wa*9.8); //Pasa a watios multiplicando x ??
//$wa=$wa;
$wa=round($wa);
$file=fopen("datosSCT13.txt","a"); //Abre el fichero de datos.txt
fputs($file, $wa); //vamos añadiendo el contenido mas una coma
fputs($file, ",");
//fputs($file,"\n"); //salto de linea ¿QUITAR????
fclose($file);
?>
Por último, con consumo.php creamos la gráfica con los valores que tenemos en cada momento, un valor cada minuto y durante las 24 horas de cada día. La gráfica se genera con la libreria gratuita jpgraph y haciendo una llamada con nuestro navegador a este consumo.php donde este alojado.
<?
//Joaquín Paredes 2017
//www.jopapa.me
//consumo.php
// content="text/plain; charset=utf-8"
require_once ('../jpgraph.php');
require_once ('../jpgraph_line.php');
$ydata = str_getcsv(file_get_contents('datosSCT13.txt')); //convierte a array el fichero amperios
//$ydata2 = array(1,56,150,49,38,);
//Valor actual consumo y la media
$cuenta = count($ydata);
$nada=$ydata[$cuenta-2];
$media=0;
for ($i = 0; $i <= $cuenta-2 ; $i++) {
$media=$media+$ydata[$i];
}
$media=($media/($cuenta-1));
$media=round($media);
$nada=round($nada);
$nada2="Consumo actual: " . "$nada" . " Watios. " . "Con una media de " . "$media";
//las marcas del eje x cada minuto
$datax=array("00",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"1",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"2",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"3",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"4",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"5",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"6",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"7",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"8",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"9",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"10",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"11",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"12",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"13",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"14",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"15",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"16",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"17",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"18",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"19",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"20",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"21",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"22",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"23",".",".",".",".",".",".",".",".",".",".",".",".",".",".","¼",".",".",".",".",".",".",".",".",".",".",".",".",".",".","½",
".",".",".",".",".",".",".",".",".",".",".",".",".",".","¾",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".", );
$graph = new Graph(1880,500); //ancho y alto
$graph->SetScale("textlin");
// Crea la linea plot de $ydata
$lineplot=new LinePlot($ydata);
//$lineplot->SetStepStyle(); //línea de gráfica en escalones
$lineplot->SetWeight( 2 ); // línea de gráfica "normal"
$graph->Add($lineplot); // Add the plot to the graph
$graph->img->SetMargin(40,20,20,40);
$graph->title->Set("Consumo eléctrico desde las 00 horas medido cada 5 minutos");
$graph->yaxis->title->Set("Watios");
$graph->xaxis->title->Set("Horas");
$graph->xaxis->SetTickLabels($datax);
$t1 = new Text($nada2); //Etiqueta para mostrar último valor de watios y media
$t1->SetPos(0.025,0.01);
$t1->SetOrientation("h");
$t1->SetFont(FF_FONT2,FS_BOLD);
$t1->SetBox("white","black","gray");
$t1->SetColor("black");
$graph->AddText($t1);
// Display the graph
$graph->Stroke();
?>
Ya se que el circuito y parte de la programación es nivel amateur, ¡¡pero funciona!!
Aquí un imagen de un día completo de julio/2016 cuando estaba en pruebas con muestras cada 5'. Ahora es cada minuto.
Pulsar botón derecho para ver imagenes al completo.
//Medidor de consumo eléctrico
//Joaquín Paredes 2017
//www.jopapa.me
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
const char* ssid = "Jopapa";
const char* password = "xxxxxxxxxxxxx";
const char* host = "192.168.1.xxx";
unsigned int valor; unsigned int valorT;
byte i,e;
unsigned int media;
const int analogInPin = A0;
unsigned long previousMillis = 0;
const long interval = 60000; // intervalo de un minuto 60000
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
IPAddress ip(192, 168, 1, 70);
IPAddress gateway(192,168,1,1);
IPAddress subnet (255,255,255,0);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
WiFi.config(ip,gateway,subnet);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle();
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) { //Llama cada minuto
previousMillis = currentMillis;
media=0;
for (e=0; e<=4; e++){ //Tomar 4 valores y hacer media
valor=0;
for (i=0; i<=185; i++){ //hace 200 capturas de A0 y no pasar de 200!!!!!
valorT = (unsigned int) analogRead(A0);
if(valor < valorT){
valor=valorT;
}
}
media= media +valor;
}
valor=media/5;
// Serial.println(media);
Serial.println(valor);
if (valor < 0){ //En valores negativos evita mostrar consumo negativo
valor=0;
}
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
// Creamos una URL
String url = "";
url +="/consumovatios/src/consumo/procesar.php?";
url += "datavalor=";
url += valor;
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
Serial.println();
Serial.println("closing connection");
}
}
<?
//Joaquín Paredes 2017
//www.jopapa.me
//consumodiario.php
// content="text/plain; charset=utf-8"
require_once ('../jpgraph.php');
require_once ('../jpgraph_line.php');
$ydata = str_getcsv(file_get_contents('mediadiaria.txt')); //convierte a array el fichero mediadiaria.txt
//Valor actual consumo y la media
//$cuenta = count($ydata);
//$nada=$ydata[$cuenta-2];
//$media=0;
//for ($i = 0; $i <= $cuenta-2 ; $i++) {
// $media=$media+$ydata[$i];
//}
//$media=($media/($cuenta-1));
//$media=round($media);
//$nada=round($nada);
//$nada2="Consumo actual: " . "$nada" . " Watios. " . "Con una media de " . "$media";
//$nada2="Medias diarias";
//las marcas del eje x cada 5'
$datax=array("Ene",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Feb",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Mar",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Abr",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"May",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Jun",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Jul",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Ago",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Sep",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Oct",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Nov",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",
"Dic",".",".",".",".",".",".",".",".",".",".",".",".",".","|",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".",".", );
// Create the graph. These two calls are always required
$graph = new Graph(1880,500);
$graph->SetScale("textlin");
// Crea la linea plot de $ydata
$lineplot=new LinePlot($ydata);
//$lineplot->SetStepStyle(); //línea de gráfica en escalones
$lineplot->SetWeight( 2 ); // línea de gráfica "normal"
$graph->Add($lineplot); // Add the plot to the graph
////////////////////////////////// Crea la linea plot de $ydata2
//$lineplot2=new LinePlot($ydata2);
//$lineplot2->SetStepStyle();
//$graph->Add($lineplot2);
$graph->img->SetMargin(40,20,20,40);
$graph->title->Set("Media de consumo eléctrico diario");
//$graph->xaxis->SetPos("min");
$graph->yaxis->title->Set("Watios");
$graph->xaxis->title->Set("Dias");
$graph->xaxis->SetTickLabels($datax);
/*
$t1 = new Text($nada2); //Etiqueta para mostrar último valor de watios y media
$t1->SetPos(0.025,0.01);
$t1->SetOrientation("h");
$t1->SetFont(FF_FONT2,FS_BOLD);
$t1->SetBox("white","black","gray");
$t1->SetColor("black");
$graph->AddText($t1);
*/
// Display the graph
$graph->Stroke();
?>
Y consumodiario.php para gráficas por días
Y consumos diarios de varios meses