Watimetro con Esp8266


Éste proyecto se aprovecha de que los contadores modernos  inteligentes  incluyen en el frontal un LED que parpadea cada 1kW consumido, de modo que conectando un par de  cables a dicho LED y montando una pequeño circuito   basada en el módulo Wifi ESP8266, podemos medir con bastante precisión el consumo producido.

Obviamente  no es  legal abrir el contador  inteligente de nuestra vivienda para soldar un para de  cables al LED del watimetro, básicamente porque el equipo no nos pertence  ya que las compañías suministradoras  lo suelen  ofrecer en modo alquiler , pero debe saber que  éste tipo de contadores  también lo podemos instalar en nustra vivienda  o local   en el cuadro de distribución de corriente alterna en un carril DIN, normalmente a a la salida del magneto-térmico general  que alimenta a todos los circuitos que haya instalados en  nuestra vivienda.

Por ejemplo el modulo  XCSOURCE® Medidor Energía KWH Kilovatio Hora LCD CA 50Hz Fase Simple Riel DIN 230V BI04   se puede comprar por unos 14€ en  Amazon siendo la instalación de riel DIN estándar de 35mm, y ademas cumpliendo con el estándar DIN EN 50023   y con el ancho del poste sencillo (módulo de 17.5mm), que cumple con el estándar DIN 43881.

El modulo en su configuración Estándar  tiene una ventana de visualización de 7+1 dígitos  (9999999.1kwh) mediante un LCD blanco y negro así, como también una salida con un led verde para el estado de suministro de energía y Rojo para la señal de impulso de energía  como el de los contadores «inteligentes».

Además , no necesitamos desmontar el modulo para capturar la salida del led de consumo pues tiene una salida SO Estándar donde  podemos conectar el circuito qeu vamos   a ver (respetando la polaridad)

Realmente como vemos en el esquema de conexiones de watimetro este  se alimenta por los terminales  1 y 4 (terminales de arriba)   y su salida ira a lo terminales 3 y 6  que conectaremos a la carga ( es decir el resto de circuitos de nuestro vivienda o local) , y resaltar que precisamente en lo terminales 20 (+) y 21(-)  tenemos la salida standar  SO   de pulsos de 50ms por 1wh

 

El circuito final que el autor propone para mejorar la visualizacion de watimetro  , cuenta de los siguiente elementos:

  • De  un ESP8266-12E como corazón del diseño
  • Una  pantalla OLED
  • Una conexión para programación via conversion usb-serie
  • Una fuente de almentacion de 3.3V
  • Un  circuito de  entrada procedente de la señal SO del watimetro
  • Una entrada adicional opcional para medir consumos individuales de una carga sin watimetro exterior

 

El circuito propuesto es el siguiente:

 

.

 

Hardware

  • ESP8266-12E
  • ACS712 Current Sensor
  • 0.96″ OLED Display
  • BT136 Triac
  • MOC3021 Opto-triac
  • MCT2E
  • LM11173.3V LDO Regulator
  • 5V SMPS Module

 

Software

 

Y a continuación el código fuente  Arduino  que deberíamos grabar en el el ESP8266

 

Codigo Arduino

/***********************************************************************************/
/* This is an simple application to illustrate IoT Home Automation. /
/ This is an example for our Monochrome OLEDs based on SSD1306 drivers /
/ Pick one up today in the adafruit shop! /
/ ——> http://www.adafruit.com/category/63_98 /
/ This example is for a 128×64 size display using I2C to communicate /
/ 3 pins are required to interface (2 I2C and one reset) /
/ Adafruit invests time and resources providing this open source code, /
/ please support Adafruit and open-source hardware by purchasing /
/ products from Adafruit! /
/ Written by Limor Fried/Ladyada for Adafruit Industries. /
/ BSD license, check license.txt for more information /
/ All text above, and the splash screen must be included in any redistribution /
/************************************************************************************/
<Wire.h>
<Adafruit_GFX.h>
<Adafruit_SSD1306.h>
<ESP8266WiFi.h>
/ Local DNS Server used for redirecting all requests to the configuration portal /
/ Local WebServer used to serve the configuration portal /
<WiFiManager.h> / https://github.com/tzapu/WiFiManager WiFi Configuration Magic */

VOLTAGE_DIVIDER 10.0f
REF_VOLT 0.9f
RESOLUTION 1024
WATTS_THRES 25.0
AC_VOLT 230.0
VPP_RMS 0.3535
BASE_PRICE 125
UNITS_UPL_FREQ 30 /* In 2Sec /
THEFT_THRESHOLD 15
VperAmp 0.1f / See AC712 Datasheet */
TRUE 1
FALSE 0
OLED_RESET 4
SSD1306_LCDHEIGHT 64
Adafruit_SSD1306 display(OLED_RESET);

const char* ssid = «IotEM»; /* Device SSID /
String apiKey = «GBH1K3293KFNO8WY»; / Replace with your thingspeak API key /
const char server = «api.thingspeak.com»;

/* Create an instance of the client */
WiFiClient client;
WiFiManager wifiManager;

/* Port Pin Definition */
int InVolPin = A0;
int LoadPin = 14;
int PulsePin = 12;
struct {
unsigned char LdCon: 1;
unsigned char Units:1;
} Flags;

double Voltage, VRMS, AmpsRMS, Watts;
volatile byte interruptCounter = 0;
int Pulses = 0;
int PrevUnits = 0;
int PrevMUnits = 0;
int Units, MeasUnits;

#if (SSD1306_LCDHEIGHT != 64)
(«Height incorrect, please fix Adafruit_SSD1306.h!»);
#endif

LoadOn() digitalWrite(LoadPin, 1)
LoadOff() digitalWrite(LoadPin, 0);

static void DispInfo (void);
static void DispStat (void);
static void SendUnits (void);
static void SendTheftInfo (void) ;
static void SendSMS (int8_t Type);
static void DisplayUnits(void);
static void TheftOccurred (void);

ADC_MODE(ADC_TOUT);

void setup(void) {
Wire.begin(0,2);
Serial.begin(9600);
pinMode(InVolPin, INPUT);
pinMode(LoadPin, OUTPUT);
pinMode(PulsePin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PulsePin), handleInterrupt, FALLING);
Flags.LdCon = FALSE;

display.display();
delay(500);
LoadOn();
ConnectAP();
DisplayUnits();
}

void loop() {
static unsigned long i = 0, j = 0, l = 0;
VRMS = getVPP() * VPP_RMS;
AmpsRMS = VRMS / VperAmp;
Watts = AmpsRMS * AC_VOLT;
if (Watts >= WATTS_THRES)
Flags.LdCon = TRUE;
else
Flags.LdCon = FALSE;
#ifdef DEBUG
Serial.print(Watts);
Serial.print(AmpsRMS);
Serial.println(» Amps RMS»);
#endif
if (Flags.LdCon) {
#ifdef DEBUG
Serial.println(MeasUnits);
Serial.println(Pulses);
Serial.println(l);
#endif
if (MeasUnits == Pulses)
if(++l > THEFT_THRESHOLD) TheftOccurred();
}
if (i++ >= UNITS_UPL_FREQ) { /* End of Day /
Units = Pulses – PrevUnits;
PrevUnits = Pulses;
SendUnits();
i = 0;
}
if (interruptCounter > 0) {
interruptCounter–;
Pulses++;
MeasUnits = Pulses;
l = 0;
#ifdef DEBUG
Serial.print(«Total Units: «);
Serial.println(Pulses);
#endif
DisplayUnits();
}
delay(1000);
}
void handleInterrupt() {
interruptCounter++;
}
static void TheftOccurred(void) {
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(3);
display.setTextColor(WHITE);
display.print(«!THEFT!»);
display.display();
SendTheftInfo();
delay(5000);
LoadOff();
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print(» Contact CESCOM»);
display.display();
delay(2000);
ESP.deepSleep(0, WAKE_RF_DEFAULT); / RIP /
for(;;);
}
void DisplayUnits(void) {
display.clearDisplay();
display.setCursor(0,0);
display.setTextSize(3);
display.setTextColor(WHITE);
display.print(Pulses);
display.setCursor(90,13);
display.setTextSize(2);
display.setTextColor(WHITE);
display.print(«Kwh»);
display.display();
}
void ConnectAP(void) {
#ifdef DEBUG
Serial.print(«Connecting Wifi: «);
Serial.println(ssid);
#endif
display.clearDisplay(); / For Display /
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println(«Connecting»);
display.display();
wifiManager.autoConnect(ssid);
#ifdef DEBUG
Serial.println(«»);
Serial.println(«WiFi connected»);
Serial.println(«IP address: «);
IPAddress ip = WiFi.localIP();
Serial.println(ip);
#endif
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println(«Connected»);
display.display();
delay(1000);
}
void SendTheftInfo(void) {
if (client.connect(server,80)) {
String postStr = apiKey;
postStr +=»&field2=»;
postStr += String(1);
postStr += «\r\n\r\n»;
client.print(«POST /update HTTP/1.1\n»);
client.print(«Host: api.thingspeak.com\n»);
client.print(«Connection: close\n»);
client.print(«X-THINGSPEAKAPIKEY: «+apiKey+»\n»);
client.print(«Content-Type: application/x-www-form-urlencoded\n»);
client.print(«Content-Length: «);
client.print(postStr.length());
client.print(«\n\n»);
client.print(postStr);
}
client.stop();
}
void SendUnits(void) {
if (client.connect(server,80)) {
String postStr = apiKey;
postStr +=»&field1=»;
postStr += String(Units);
postStr += «\r\n\r\n»;
client.print(«POST /update HTTP/1.1\n»);
client.print(«Host: api.thingspeak.com\n»);
client.print(«Connection: close\n»);
client.print(«X-THINGSPEAKAPIKEY: «+apiKey+»\n»);
client.print(«Content-Type: application/x-www-form-urlencoded\n»);
client.print(«Content-Length: «);
client.print(postStr.length());
client.print(«\n\n»);
client.print(postStr);
}
client.stop();
}
float getVPP() {
float result;
int readValue; //value read from the sensor
int maxValue = 0; // store max value here
int minValue = 1024; // store min value here
uint32_t start_time = millis();
while((millis()-start_time) < 1000) //sample for 1 Sec
{
readValue = analogRead(InVolPin);
// see if you have a new maxValue
if (readValue > maxValue)
{
/record the maximum sensor value/
maxValue = readValue;
}
if (readValue < minValue)
{
/record the minimum sensor value*/
minValue = readValue;
}
}
// Subtract min from max
result = (((maxValue – minValue) * REF_VOLT) / RESOLUTION) * VOLTAGE_DIVIDER ;
return result;
}

 

Y por cierto para los incredulos en el siguiente video podemos ver el circuito en funcionamiento

 

Fabricación casera de placas mediante láser


Hay muchas, muchas maneras de hacer una placa de circuito impreso o  en ingles «PCB»(printed circuit board)  . Sin embargo, incluso con la práctica, la calidad del resultado varía mucho con el proceso y el equipo utilizado.

Antiguamente  el diseño se calcaba en un papel de acetato y se usaba placas fotosensibles exponiéndolas a una luz intensa,  pero modernamente se  imprime el diseño con una impresora láser  con tóner negro, o bien se fotocopia el mismo en un papel grueso.

Una vez tenemos la plantilla recortaremos la fotocopia como se indica en la imagen,de esta forma, podremos pegar los bordes a la placa.

recortes.png

Antes de transferir el diseño se recomienda proceder al limpiado de la placa por ejemplo usando lana de acero y acetona (este proceso debe ser llevado lo mejor posible, ya que si la placa no queda bien limpia nunca fijara el tóner el la misma). Al terminar de limpiar secaremos la placa con un paño limpio y volveremos a limpiarla sin poner mas los dedos sobre el cobre, ya que estos dejan grasa:la limpieza de la placa solo será efectiva cuando esta quede brillante y con rayones en circulo para que agarre mejor el tóner.

En el instante que se retira la plancha de la placa, después de 1 o 2 minutos de calor intenso, a veces mas, se coloca la placa en un recipiente con agua para que el papel no tire (suelte) el tóner hacia arriba al enfriarse y se fije a la placa, esta debe mantenerse en el agua durante unos 5 minutos.

Una vez limpia la placa colocaremos la plantilla con el lado de la tinta hacia el cobre y con la plancha a tope de calor, se le aplica a la placa  Es importante insistir con el calor por toda la placa y con vapor humedeciendo el papel para que no se queme pero sin empaparlo. Si se llegase a empapar, cortar la llave de vapor y dar calor seco unos instantes.

Después de haber esperado 5 o 10 minutos en el agua, sacamos la placa y vamos frotando con los dedos para quitarle el papel que no nos sirve, intentando quitarlo todo, hasta que quede una capa muy fina de papel que se retira con un cepillo de dientes que ya no tengan en uso, con cuidado de no partir el tóner que define las pistas.

placa

Una vez repasadas todas las pistas de la placa con un marcador permanente (tipo edding 3000 o superior), se espera un par de minutos para que este fije y seque. Mientras tanto, podemos ir preparando el ácido para atacar la placa consistente en una   mezcla de  2 partes de agua fuerte con 4 de agua oxigenada 110 vol. y 1 de agua ( Atención : sobra decir que se debe tener un cuidado extremo usando guantes y gafas de protección  para  evitar contactos accidentales  en la piel  o en los ojos) .

Una vez tengamos la disolución do meteremos la placa en este . Ahora debemos estar mas atentos, pues si el ácido resultara fuerte podría diluir el tóner. Lo ideal es que cuando coloque la placa en disolución, el cobre coja un color rojizo y empiece a burbujear..

placa2

 

Una vez se saque la placa del ácido hay que enjuagarla con abundante agua para que el acido no  siga atacando el cobre  por lo que conviene secarla con un trapo limpio. Una vez seca, se empapara el toner con acetona y se rascara con un cepillo de dientes o con la lana de acero, eliminando así todo el tóner de la placa y ya solo quedaría hacer los taladros para los componentes con una broca de 1mm.

 

¿Le parece  interesante el proceso de fabricación casera de PCB’s anterior? Pues afortunadamente, los nuevos y mejorados métodos de transferencia de Gerber se han ideado en los últimos años gracias a los hackers en todo el mundo.

Uno de esos hackers, [Henner] está trabajando en un proyecto llamado LDGraphy en un intento de traer el grabado de alta resolución a las masas.

LDGraphy es un dispositivo de láser de litografía que hace uso de un láser y un Beaglebone verde para grabar el diseño en el tablero. La mejor parte es que toda la lista de materiales se dice que cuesta menos de $ 100,o  que hace que sea asequible para las personas con un presupuesto ajustado.

El sistema está diseñado alrededor de un láser de 500 mW y un escáner de espejo de polígono destinado a una impresora láser. La placa con fotorresistencia se acciona linealmente en el eje X utilizando un motor paso a paso y el rayo láser que es rebotado del espejo hexagonal giratorio es responsable del eje Y.

El código de tiempo crítico para la Unidad Programable en Tiempo Real (PRU) del procesador AM335X está escrito en  ensamblador  para la conmutación rápida del láser. El recinto es, naturalmente, un caso de acrílico de corte por láser y está hecho en el espacio de hackers local de [Henner].

[Henner] ha estado trabajando duro calibrando su diseño y compensando las inexactitudes de los componentes utilizados. En el vídeo de demostración a continuación presenta una versión de trabajo con una resolución de 6 mils que es maravilloso teniendo en cuenta el costo de la máquina.

 

Este  proyecto es totalmente Open Source, toda la documentación y código fuente están disponibles en GitHub con un coste total de apenas 100 dólares utilizando mucho material recuperado

 

Esta no es la primera vez que hemos visto un DIY láser PCB exposer, por supuesto, pero es uno de los mejores documentados.