jueves, 14 de julio de 2016

Monitorización de temperatura, humedad y sensación térmica



Con un WeMos D1 mini V2 (3,66 euros) y una shield DHT11 (2,29 euros) vamos a monitorizar la  temperatura, humedad y sensación térmica de donde se encuentre instalado y funcionando el WeMos.




Los datos se subirán cada diez segundos al sitio emoncms.org y allí crearemos las gráficas para visualizarlas en el smartphone u ordenador.




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*****************************************************************************
 * ***************************************************************************
 *  Fecha: 14/07/2016       Autor: AntonioBG
 *  Material: Wemos mini D1 V2 + shield DHT11
 * 
 * 
 * Conexión:  
 *    Por defecto la shield ya tiene la conexion al pin D4   
*          
 * LICENCIA DE USO GNU GPL, si mejoras el programa o añades funcionalidades,
 * por favor, compártelo!
 ***************************************************************************
 ****************************************************************************/
#include <ESP8266WiFi.h>
#include "DHT.h"
#include "EmonLib.h"  

const char* ssid = "xxxxxxxxxxxxxx";
const char* password = "xxxxxxxxxxxxxxx";
const char* host = "emoncms.org";
const char* apikey = "xxxxxxxxxxxxxxxxxxxxx";

int node = 1; //numero del nodo

  #define DHTPIN D4     // pin de conexion
  #define DHTTYPE DHT11   // DHT 11
  //#define DHTTYPE DHT22   // DHT 22  (AM2302)
  //#define DHTTYPE DHT21   // DHT 21 (AM2301)
  float h; //declara humedad
  float t; //temperatura
  float hic; //sensacion termica
  DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void loop() {
  delay(5000);
  
   h = dht.readHumidity();
   t = dht.readTemperature(); //temperatura en celsius
   hic = dht.computeHeatIndex(t, h); //computa el índice de calor
   
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("connection failed");
    return;
  }

  delay(1000);    

  if (client.connect(host, httpPort)) {
    Serial.println("Conectando...");
    client.print("GET /api/post?apikey=");
    client.print(apikey);
    client.print("&node=");
    client.print(node);
    client.print("&json={Humedad");
    client.print(":");
    client.print(h);    
    client.print(",Temp_dht:");
    client.print(t);
    client.print(",Sensacion_terminca:");
    client.print(hic);
    client.println("} HTTP/1.1");
    client.println("Host:emoncms.org");
    client.println("User-Agent: Arduino-ethernet");
    client.println("Connection: close");
    client.println();

  } 
  
  delay(4000);
  
  Serial.println();
  Serial.println("closing connection");
}

jueves, 7 de julio de 2016

Monitorización equipo de energía solar

El brico trata de realizar la monitorización online de un sistema de energía solar fotovoltaico, en este caso emplearemos un monitor de baterías Victron BMV-700 y Arduino.


En la imagen del BMV-700 podrás ver que se suministra con un shunt para intercalar en el cableado de las baterías, medirá la intensidad en dirección a las baterías como la intensidad que suministren éstas.
Materiales empleados:
  • Arduino-UNO + Fuente de alimentación
  •  Ethernet shield
  • Termistor NTC-MF52-103  
  • Pinza amperimétrica SCT-013-000 (100A) 
  • Un módulo relé, viene optoacoplado y con dos leds, uno rojo de alimentación y otro verde de estado.
  • Un Modulo Bidireccional I2c CII Convertidor Nivel Logico 5v-3.3v
  • Una pequeña caja estanca para meterlo todo. 
 Así quedaría la pantalla de visualización de datos:
En éste caso, el programa subirá 24 relativos al buffer del dispositivo BMV, muchos de ellos actualmente no los estoy usando, pero quizás mañana si.

El programa también está programado para el uso de dos equipos híbridos tipo Voltronic o PIP, normalmente el equipo esclavo se encontrará apagado, y sólo se encenderá cuando alcance o supere el nivel establecido en la variable WtEsclavo, para ello soldaremos unos pequeños hilos que irán desde el relé hasta las patillas del interruptor del híbrido, el interruptor lo colocaremos en la posición apagado para que sea el relé quien abra o cierre el contacto. Se utilizará el pin 7.

El BMV se conectará mediante el cable Tx al Rx de Arduino y compartirán también GND.
 Por seguridad he instalado  entre el BMV y el arduino un Modulo Bidireccional I2c CII Convertidor Nivel Logico 5v-3.3 para separar las tensión de ambos, aunque en este caso no es necesario por no compartir el pin power, nunca esta de más un poco de protección.





He utilizado un Arduino-Uno al que he añadido una shield ethetnet








En el parámetro "emon1.current(0, 56.606);// Pinza amperimetrica:( input pin, calibration)" deberás cambiar los valores para la calibración de la pinza.





El relé utilizado es igual que el de la imagen, ya viene provisto de optoacloplador y un par de led, alimentación rojo y estado en verde.



Una vez tengas instalado el sistema, deberás registrarte en emoncms.org. cuando entres en tu perfil podrás visualizar la api key que tendrás que cambiarla por la que está escrita en el programa, lo datos comenzarán a subirse  al sitio web, podrás visualizar los inputs que llegan al portal y decidir cuales vas a convertir en feed, para finalmente configurar la interfaz grafica haciendo uso de los feeds. Encontrarás más información en la documentación API https://emoncms.org/site/api

En el próximo brico y a partir de este sistema realizaré un sistema de derivación de excedentes, el proyecto consistirá en montar en una cajita estanca un WeMos que recoja información del sistema y realice derivación a cargas resistivas mientras no se produzca consumo en las baterías.

Aquí tienes disponible el código para Arduino.


  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
/*****************************************************************************
 * ***************************************************************************
 *  Fecha: 05/07/2016       Autor: AntonioBG 
 *  Material: Arduino + ethernet shield + thermistor NTC-MF52-103 + 
 *  relé + pinza amperimetrica SCT-013-000
 *  
 *  Objetivo: 
 * -Primero.- Monitorización online del monitor de baterías, subiendo 
 *  los datos a emoncms.org
 * -Segundo.- Mantener apagado el híbrido esclavo tipo Voltronic, 
 *  cuando la pinza amperimetrica detecte menos de lo establecido 
 *  en el parámetro "WtEsclavo" y enciende el híbrido si detecta más carga de 
 *  la indicada.
 *  
 * Conexión:   
 * -Pin digital 7, conexión al relé actuador del híbrido.
 * -Pin analógico A1, conexión del thermistor.
 * -Pin analógico A0, pinza amperimétrica no invasiva, he empleado el modelo 
 *  100A aunque recomiendo el de 30A que ofrece mejor resolución.
 * -El monitor BMV de Victron es de 3,3v y Arduino de 5v, la conexión será 
 *  del monitor pin Tx a Rx de Arduino, y GND de ambos, por seguridad y aunque no 
 *  sea necesario, he instalado un módulo "I2c CII Convertidor Nivel Logico 5v-3.3v 
 *  Modulo Bidireccional".
 *                 
 * LICENCIA DE USO GNU GPL, si mejoras el programa o añades funcionalidades,
 * por favor, compártelo!
 */
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Ethernet.h>
#include "EmonLib.h"                   
#include <math.h>

  byte mac[] = {0x50, 0xA1, 0xDA, 0x00, 0x39, 0xE5};
  IPAddress ip(192, 168, 1, 201); //IP estática
  IPAddress subnet(255, 255, 255, 0);
  IPAddress DNS(8, 8, 8, 8);
  IPAddress gw(192, 168, 1, 1); // Puerta de enlace
  
  EthernetClient clientEmon;
  EnergyMonitor emon1;
  SoftwareSerial Victron(0,1); // (RX, TX) RX se ecuentra establecido en el 0
  #define P(str) (strcpy_P(p_buffer, PSTR(str)), p_buffer)
  char c;
  String V_buffer;  // Buffer para datos del monitor Victron
  String E_buffer;  // Buffer para datos de ethernet shield
  
  float I; // I Intensidad instantanea
  float V; // V Vo
/*****************************************************************************
 * ***************************************************************************
 *  Fecha: 05/07/2016       Autor: AntonioBG 
 *  Material: Arduino + ethernet shield + thermistor NTC-MF52-103 + 
 *  relé + pinza amperimetrica SCT-013-000
 *  
 *  Objetivo: 
 * -Primero.- Monitorización online del monitor de baterías, subiendo 
 *  los datos a emoncms.org
 * -Segundo.- Mantener apagado el híbrido esclavo tipo Voltronic, 
 *  cuando la pinza amperimetrica detecte menos de lo establecido 
 *  en el parámetro "WtEsclavo" y enciende el híbrido si detecta más carga de 
 *  la indicada.
 *  
 * Conexión:   
 * -Pin digital 7, conexión al relé actuador del híbrido.
 * -Pin analógico A1, conexión del thermistor.
 * -Pin analógico A0, pinza amperimétrica no invasiva, he empleado el modelo 
 *  100A aunque recomiendo el de 30A que ofrece mejor resolución.
 * -El monitor BMV de Victron es de 3,3v y Arduino de 5v, la conexión será 
 *  del monitor pin Tx a Rx de Arduino, y GND de ambos, por seguridad y aunque no 
 *  sea necesario, he instalado un módulo "I2c CII Convertidor Nivel Logico 5v-3.3v 
 *  Modulo Bidireccional".
 *                 
 * LICENCIA DE USO GNU GPL, si mejoras el programa o añades funcionalidades,
 * por favor, compártelo!
 */
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Ethernet.h>
#include "EmonLib.h"                   
#include <math.h>

  byte mac[] = {0x50, 0xA1, 0xDA, 0x00, 0x39, 0xE5};
  IPAddress ip(192, 168, 1, 201); //IP estática
  IPAddress subnet(255, 255, 255, 0);
  IPAddress DNS(8, 8, 8, 8);
  IPAddress gw(192, 168, 1, 1); // Puerta de enlace
  
  EthernetClient clientEmon;
  EnergyMonitor emon1;
  SoftwareSerial Victron(0,1); // (RX, TX) RX se ecuentra establecido en el 0
  char p_buffer[80];
  #define P(str) (strcpy_P(p_buffer, PSTR(str)), p_buffer)
  char c;
  String V_buffer;  // Buffer para datos del monitor Victron
  String E_buffer;  // Buffer para datos de ethernet shield
  
  int P; //P potencia instantanea     
  float SOC;// SOC estado de carga
  float TTG;// TTG time to go
  float CE;// Consumo Amp/h
  int H1;//Profundidad descarga máxima
  int H2;//Profundidad ultima descarga
  int H3;//Profundidad de la descarga media
  int H4;//Numero de ciclos de carga
  int H5;//Numero de descargas completas
  float H6;//Horas acumuladas amperaje
  float H7;//Minimo voltaje bateria
  float H8;//Maximo voltage bateria
  float H9;//Tiempo desde ultima descarga
  int H10;//Numero de sincronizaciones automaticas
  int H11;//Numero de alarmas voltaje bajo
  int H12;//Numero de alarmas voltaje alto
  int H17;//Cantidad energia descargada
  float H18;//Cantidad de energia cargada
  int Alarm_high_voltage;
  int Alarm_low_voltage;
  int Alarm_low_soc;
  String Alarm; 
  String Relay;  

  double Irms; //Calculo pinza amp
  int WtEsclavo = 9; // W Establece los amperios a los que se activa el hibrido esclavo
  int ReleHibrido = 7; // Pin para arrancar el hibrido paralelo
  
char serverEmon[] = "emoncms.org";     
String apikey = "XXXXa0XXXXX1dXXXX96e8XXXXX4b2XXX";  //api key, regístrate en emoncms.org e introduce tu api key
int node = 0; //if 0, not used, puede tener más nodos
unsigned long lastConnectionTime = 0;          // ultima vez que conectó en milisegundos
boolean lastConnected = false;                 // estado de la conexión última vez a través delloop
const unsigned long postingInterval = 10*1000;  // establece en milisegundos el delay en actualizaciones

void setup() {
  Serial.begin(19200);
  Serial.println("Emoncms client starting...");
  Ethernet.begin(mac, ip, DNS, gw, subnet);
    emon1.current(0, 56.606);// Pinza amperimetrica:( input pin, calibration)//
  pinMode(ReleHibrido, OUTPUT);
}

// <-- Inicio loop
void loop() { 
  
// <-- Victron 
  if (Victron.available()) {
 
    if (V_buffer.length() <80) {
      V_buffer += c;
    }
 
    if (c == '\n') {  // New line.
      
      if (V_buffer.startsWith("I")) {//Corriente bateria
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        I = (float) temp_int/1000;}
       if (V_buffer.startsWith("P")) {//Potencia instantanea
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        P = (int) temp_int;}   
      if (V_buffer.startsWith("CE")) {//Consumido kwh
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        CE = (float) temp_int/1000;}
       if (V_buffer.startsWith("TTG")) {//Time to go
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        TTG = (float) temp_int/60;}
      if (V_buffer.startsWith("H1")) {//Profundidad descarga máxima
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H1 = (int) temp_int/10;}  
      if (V_buffer.startsWith("H2")) {//Profundidad ultima descarga
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H2 = (int) temp_int/10;}  
      if (V_buffer.startsWith("H3")) {//Profundidad de la descarga media
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H3 = (int) temp_int;}  
      if (V_buffer.startsWith("H4")) {//Numero de ciclos de carga
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H4 = (int) temp_int;}    
      if (V_buffer.startsWith("H5")) {//Numero de descargas completas
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H5 = (int) temp_int;}    
      if (V_buffer.startsWith("H6")) {//Horas acumuladas amperaje
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H6 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H7")) {//Minimo voltaje bateria
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H7 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H8")) {//Maximo voltage bateria
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H8 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H9")) {//Tiempo desde ultima descarga
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H9 = (float) temp_int/86400;}
      if (V_buffer.startsWith("H10")) {//Numero de sincronizaciones automaticas
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H10 = (int) temp_int;}
      if (V_buffer.startsWith("H11")) {//Numero de alarmas voltaje bajo
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H11 = (int) temp_int;} 
      if (V_buffer.startsWith("H12")) {//Numero de alarmas voltaje alto
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H12 = (int) temp_int;} 
      if (V_buffer.startsWith("H17")) {//Cantidad energia descargada
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H17 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H18")) {//Cantidad de energia cargada
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H18 = (float) temp_int/1000;}
      if (V_buffer.startsWith("Alarm")) {
        Alarm = V_buffer.substring(V_buffer.indexOf("\t")+1);
        Alarm.trim();}     
      if (V_buffer.startsWith("Relay")) {
        Relay = V_buffer.substring(V_buffer.indexOf("\t")+1);
        Relay.trim();}     
      if (V_buffer.startsWith("AR")) {
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        if (bitRead(temp_int,0)) {
          Alarm_low_voltage = 1;}
        else {Alarm_low_voltage = 0;}
        if (bitRead(temp_int,1)) {
          Alarm_high_voltage = 1;}
          else {Alarm_high_voltage = 0;}
        if (bitRead(temp_int,2)) {Alarm_low_soc = 1;}
        else {Alarm_low_soc = 0;}
      }
      V_buffer="";
    }
  }
// Victron -->
  if (!clientEmon.connected() && lastConnected) {
    Serial.println();
    Serial.println("Desconectando...");
    clientEmon.stop();
  }
  if(!clientEmon.connected() && (millis() - lastConnectionTime > postingInterval)) {
    // <-- Pinza amperimetrica 
    Irms = emon1.calcIrms(1480);  // Calculate Irms only
    // <-- Activa esclavo
    if (Irms >= WtEsclavo){
      digitalWrite(ReleHibrido,LOW);// Activa el hibrido esclavo
    } else {
      digitalWrite(ReleHibrido,HIGH);
      }
    // Activa esclavo -->
    
    sendData();
  }
  lastConnected = clientEmon.connected();
}
//  Fin Loop -->

// <-- Devuelve grados celsius
double Thermister(int RawADC) {  
double Temp;
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
Temp = Temp - 273.15;// Converierte de Kelvin a Celsius
//Para convertir Celsius a Farenheith esriba en esta linea: Temp = (Temp * 9.0)/ 5.0 + 32.0; 
return Temp;
} 
//  Devuelve grados celsius --> 

// <-- Envía datos a emoncms 
void sendData() {
  if (clientEmon.connect(serverEmon, 80)) {
    Serial.println("Connecting...");
    clientEmon.print("GET /api/post?apikey=");
    clientEmon.print(apikey);
    if (node > 0) {
      clientEmon.print("&node=");
      clientEmon.print(node);
    }
    clientEmon.print("&json={");
    clientEmon.print(",Potencia:");
    clientEmon.print(P);
    clientEmon.print(",SOC:");
    clientEmon.print(SOC);
    clientEmon.print(",TTG:");
    clientEmon.print(TTG);
    clientEmon.print(",CE:");
    clientEmon.print(CE);
    clientEmon.print(",H1:");
    clientEmon.print(H1);
    clientEmon.print(",H2:");
    clientEmon.print(H2);
    clientEmon.print(",H3:");
    clientEmon.print(H3);
    clientEmon.print(",H4:");
    clientEmon.print(H4);
    clientEmon.print(",H5:");
    clientEmon.print(H5);
    clientEmon.print(",H6:");
    clientEmon.print(H6);
    clientEmon.print(",H7:");
    clientEmon.print(H7);
    clientEmon.print(",H8:");
    clientEmon.print(H8);
    clientEmon.print(",H9:");
    clientEmon.print(H9);
    clientEmon.print(",H10:");
    clientEmon.print(H10);
    clientEmon.print(",H11:");
    clientEmon.print(H11);
    clientEmon.print(",H12:");
    clientEmon.print(H12);
    clientEmon.print(",H17:");
    clientEmon.print(H17);
    clientEmon.print(",H18:");
    clientEmon.print(H18);
    clientEmon.print(",Alarm_high_voltage:");
    clientEmon.print(Alarm_high_voltage);
    clientEmon.print(",Alarm_low_voltage:");
    clientEmon.print(Alarm_low_voltage);
    clientEmon.print(",Alarm_low_soc:");
    clientEmon.print(Alarm_low_soc);
    clientEmon.print(",Alarm:");
    clientEmon.print(Alarm);
    clientEmon.print(",Relay:");
    clientEmon.print(Relay);
    // <-- Thermister
    int val=analogRead(A1);//Lee el valor del pin analogo 0 y lo mantiene como val
    double temp=Thermister(val);//Realiza la conversión del valor analogo a grados Celsius
    clientEmon.print(",Temp:");
    clientEmon.print(temp);
    Serial.println("temp: ");//Escribe la temperatura en el monitor serial debug
    Serial.println(temp);//Escribe la temperatura en el monitor serial debug
    // Thermister -->
    // <-- Pinza amp
    clientEmon.print(",Consumo_W_Hibrid:");
    clientEmon.print(Irms*230); // Potencia W aparente
    clientEmon.print(",Consumo_I:");
    clientEmon.print(Irms); // Irms
    // Pinza amp -->
    clientEmon.println("} HTTP/1.1");
    clientEmon.println("Host:emoncms.org");
    clientEmon.println("User-Agent: Arduino-ethernet");
    clientEmon.println("Connection: close");
    clientEmon.println();

    lastConnectionTime = millis();
  } 
  else {
    // Si no puede establecer conexión:
    Serial.println("Conexion fallida");
    Serial.println("Desconectando...");
    clientEmon.stop();
  }
}
//  Envía datos a emoncms -->
ltaje instananeo
  float TTG;// TTG time to go
  float CE;// Consumo Amp/h
  int H1;//Profundidad descarga máxima
  int H2;//Profundidad ultima descarga
  int H3;//Profundidad de la descarga media
  int H4;//Numero de ciclos de carga
  int H5;//Numero de descargas completas
  float H6;//Horas acumuladas amperaje
  float H7;//Minimo voltaje bateria
  float H8;//Maximo voltage bateria
  float H9;//Tiempo desde ultima descarga
  int H10;//Numero de sincronizaciones automaticas
  int H11;//Numero de alarmas voltaje bajo
  int H12;//Numero de alarmas voltaje alto
  int H17;//Cantidad energia descargada
  float H18;//Cantidad de energia cargada
  int Alarm_high_voltage;
  int Alarm_low_voltage;
  int Alarm_low_soc;
  String Alarm; 
  String Relay;  

  double Irms; //Calculo pinza amp
  int WtEsclavo = 9; // W Establece los amperios a los que se activa el hibrido esclavo
  int ReleHibrido = 7; // Pin para arrancar el hibrido paralelo
  
char serverEmon[] = "emoncms.org";     
String apikey = "XXXXa0XXXXX1dXXXX96e8XXXXX4b2XXX";  //api key, regístrate en emoncms.org e introduce tu api key
int node = 0; //if 0, not used, puede tener más nodos
unsigned long lastConnectionTime = 0;          // ultima vez que conectó en milisegundos
boolean lastConnected = false;                 // estado de la conexión última vez a través delloop
const unsigned long postingInterval = 10*1000;  // establece en milisegundos el delay en actualizaciones

void setup() {
  Serial.begin(19200);
  Victron.begin(19200);
  Serial.println("Emoncms client starting...");
  Ethernet.begin(mac, ip, DNS, gw, subnet);
    emon1.current(0, 56.606);// Pinza amperimetrica:( input pin, calibration)//
  pinMode(ReleHibrido, OUTPUT);
}

// <-- Inicio loop
void loop() { 
  
// <-- Victron 
  if (Victron.available()) {
    c = Victron.read();
 
    if (V_buffer.length() <80) {
      V_buffer += c;
    }
 
    if (c == '\n') {  // New line.
  
       if (V_buffer.startsWith("I")) {//Corriente bateria
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        I = (float) temp_int/1000;}
       if (V_buffer.startsWith("P")) {//Potencia instantanea
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        P = (int) temp_int;}   
      if (V_buffer.startsWith("CE")) {//Consumido kwh
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        CE = (float) temp_int/1000;}
       if (V_buffer.startsWith("TTG")) {//Time to go
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        TTG = (float) temp_int/60;}
      if (V_buffer.startsWith("H1")) {//Profundidad descarga máxima
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H1 = (int) temp_int/10;}  
      if (V_buffer.startsWith("H2")) {//Profundidad ultima descarga
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H2 = (int) temp_int/10;}  
      if (V_buffer.startsWith("H3")) {//Profundidad de la descarga media
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H3 = (int) temp_int;}  
      if (V_buffer.startsWith("H4")) {//Numero de ciclos de carga
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H4 = (int) temp_int;}    
      if (V_buffer.startsWith("H5")) {//Numero de descargas completas
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H5 = (int) temp_int;}    
      if (V_buffer.startsWith("H6")) {//Horas acumuladas amperaje
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H6 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H7")) {//Minimo voltaje bateria
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H7 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H8")) {//Maximo voltage bateria
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H8 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H9")) {//Tiempo desde ultima descarga
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H9 = (float) temp_int/86400;}
      if (V_buffer.startsWith("H10")) {//Numero de sincronizaciones automaticas
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H10 = (int) temp_int;}
      if (V_buffer.startsWith("H11")) {//Numero de alarmas voltaje bajo
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H11 = (int) temp_int;} 
      if (V_buffer.startsWith("H12")) {//Numero de alarmas voltaje alto
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        H12 = (int) temp_int;} 
      if (V_buffer.startsWith("H17")) {//Cantidad energia descargada
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H17 = (float) temp_int/1000;}
      if (V_buffer.startsWith("H18")) {//Cantidad de energia cargada
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        double temp_int = temp_string.toInt();
        H18 = (float) temp_int/1000;}
      if (V_buffer.startsWith("Alarm")) {
        Alarm = V_buffer.substring(V_buffer.indexOf("\t")+1);
        Alarm.trim();}     
      if (V_buffer.startsWith("Relay")) {
        Relay = V_buffer.substring(V_buffer.indexOf("\t")+1);
        Relay.trim();}     
      if (V_buffer.startsWith("AR")) {
        String temp_string = V_buffer.substring(V_buffer.indexOf("\t")+1);
        int temp_int = temp_string.toInt();
        if (bitRead(temp_int,0)) {
          Alarm_low_voltage = 1;}
        else {Alarm_low_voltage = 0;}
        if (bitRead(temp_int,1)) {
          Alarm_high_voltage = 1;}
          else {Alarm_high_voltage = 0;}
        if (bitRead(temp_int,2)) {Alarm_low_soc = 1;}
        else {Alarm_low_soc = 0;}
      }
      V_buffer="";
    }
  }
// Victron -->
  if (!clientEmon.connected() && lastConnected) {
    Serial.println();
    Serial.println("Desconectando...");
    clientEmon.stop();
  }
  if(!clientEmon.connected() && (millis() - lastConnectionTime > postingInterval)) {
    // <-- Pinza amperimetrica 
    Irms = emon1.calcIrms(1480);  // Calculate Irms only
    // <-- Activa esclavo
    if (Irms >= WtEsclavo){
      digitalWrite(ReleHibrido,LOW);// Activa el hibrido esclavo
    } else {
      digitalWrite(ReleHibrido,HIGH);
      }
    // Activa esclavo -->
    
    sendData();
  }
  lastConnected = clientEmon.connected();
}
//  Fin Loop -->

// <-- Devuelve grados celsius
double Thermister(int RawADC) {  
double Temp;
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
Temp = Temp - 273.15;// Converierte de Kelvin a Celsius
//Para convertir Celsius a Farenheith esriba en esta linea: Temp = (Temp * 9.0)/ 5.0 + 32.0; 
return Temp;
} 
//  Devuelve grados celsius --> 

// <-- Envía datos a emoncms 
void sendData() {
  if (clientEmon.connect(serverEmon, 80)) {
    Serial.println("Connecting...");
    clientEmon.print("GET /api/post?apikey=");
    clientEmon.print(apikey);
    if (node > 0) {
      clientEmon.print("&node=");
      clientEmon.print(node);
    }
    clientEmon.print("&json={");
    clientEmon.print(",Potencia:");
    clientEmon.print(P);
    clientEmon.print(",SOC:");
    clientEmon.print(SOC);
    clientEmon.print(",TTG:");
    clientEmon.print(TTG);
    clientEmon.print(",CE:");
    clientEmon.print(CE);
    clientEmon.print(",H1:");
    clientEmon.print(H1);
    clientEmon.print(",H2:");
    clientEmon.print(H2);
    clientEmon.print(",H3:");
    clientEmon.print(H3);
    clientEmon.print(",H4:");
    clientEmon.print(H4);
    clientEmon.print(",H5:");
    clientEmon.print(H5);
    clientEmon.print(",H6:");
    clientEmon.print(H6);
    clientEmon.print(",H7:");
    clientEmon.print(H7);
    clientEmon.print(",H8:");
    clientEmon.print(H8);
    clientEmon.print(",H9:");
    clientEmon.print(H9);
    clientEmon.print(",H10:");
    clientEmon.print(H10);
    clientEmon.print(",H11:");
    clientEmon.print(H11);
    clientEmon.print(",H12:");
    clientEmon.print(H12);
    clientEmon.print(",H17:");
    clientEmon.print(H17);
    clientEmon.print(",H18:");
    clientEmon.print(H18);
    clientEmon.print(",Alarm_high_voltage:");
    clientEmon.print(Alarm_high_voltage);
    clientEmon.print(",Alarm_low_voltage:");
    clientEmon.print(Alarm_low_voltage);
    clientEmon.print(",Alarm_low_soc:");
    clientEmon.print(Alarm_low_soc);
    clientEmon.print(",Alarm:");
    clientEmon.print(Alarm);
    clientEmon.print(",Relay:");
    clientEmon.print(Relay);
    // <-- Thermister
    int val=analogRead(A1);//Lee el valor del pin analogo 0 y lo mantiene como val
    double temp=Thermister(val);//Realiza la conversión del valor analogo a grados Celsius
    clientEmon.print(",Temp:");
    clientEmon.print(temp);
    Serial.println("temp: ");//Escribe la temperatura en el monitor serial debug
    Serial.println(temp);//Escribe la temperatura en el monitor serial debug
    // Thermister -->
    // <-- Pinza amp
    clientEmon.print(",Consumo_W_Hibrid:");
    clientEmon.print(Irms*230); // Potencia W aparente
    clientEmon.print(",Consumo_I:");
    clientEmon.print(Irms); // Irms
    // Pinza amp -->
    clientEmon.println("} HTTP/1.1");
    clientEmon.println("Host:emoncms.org");
    clientEmon.println("User-Agent: Arduino-ethernet");
    clientEmon.println("Connection: close");
    clientEmon.println();

    lastConnectionTime = millis();
  } 
  else {
    // Si no puede establecer conexión:
    Serial.println("Conexion fallida");
    Serial.println("Desconectando...");
    clientEmon.stop();
  }
}
//  Envía datos a emoncms -->