jueves, 23 de julio de 2020

Programador de sistema de enfriamiento por pulverización.

En esta nueva entrada voy a describir como fabricar un programador para un sistema de pulverización de agua de los que se usan para refrescar zonas como terrazas al aire libre. Dicho sistema utiliza pulverizadores de 0,3 mm de diametro de agujero pulverizador y usa la presión del agua corriente de nuestros grifos. El control de la pulverización se hace con dos electrovalvulas comandadas por sendos reles, que son gobernados por el programador, basado en un Arduino Uno y en una placa DIY que incorpora un LCD del tipo Nokia y un pulsador de 4 botones del tipo resistencias en serie. El material de todo el artilugio, incluidas las especificaciones del material para hacer el sistema de pulverización, se describe mas abajo. El usar dos reles se explica por la tendencia a gotear de los pulverizadores tras cortarse el suministro de agua a presión por el primer relé, el que controla el suministro de agua a presión desde el grifo. El segundo relé sirve de desague de presión del sistema, una vez realizada la pulverización, evitando el goteo. El material es el siguiente:

- Arduino Uno.
- Caja de plastico
- Sensor de temperatura, humedad y presion: BME250
- Tubo de polietileno de alta presión 1/4 pulgada (6 mm)
- Conectores T y acodados para realizar las conexiones de los tubos de 1/4 pulgada (6 mm)
- Boquillas de spray de laton de 0.3 mm
- Terminales obturadores para extremos del sistema de tubuladura.
- Un filtro de agua en linea de malla de acero (para evitar atascos de los pulverizadores con las piedrecillas de arena que pudiera tener el agua)
- Dos electrovávulas de 12v, cerradas en pasivo.
- Dos reles capaces de manejar 12v, cerrados en pasivo.
- Cable dipolo
- Fuente de alimentación de 12v.

La manguera es asi:


Los conectores para la manguera son estos:
Los pulverizadores son estos:

Se atornillan a un trozo de tubo y este se inserta en los conectores de plastico anteriores.

La mejor manera de hacer el montaje de los pulverizadores es usando un acodado y un pulverizador, para que la pulverizacion sea horizontal y no se dirija hacia el suelo (mayor tiempo de vuelo de la nebulizacion implica mayor probabilidad de evaporación y mas eficiencia refrigeradora), o montarlos dobles horizontales con un conector T que se acopla a la salida de una T de la tubuladura.

El filtro es este:
Tiene indicados la entrada y la salida, es desmontable y limpiable. Incluso lo podeis rellenar de antical para el mantenimiento de los pulverizadores en invierno.


Conexiones de la pantalla LCD NOKIA:


El sistema de botonadura:




Sensor BME250:

El esquema para la conexión con el Arduino UNO mediante I2C sería así usando los pines A4(SDA) y A5 (SLC). Las resistencias son de 4K7Ohm.


Los reles son del tipo normal con tres pines, VCC, GND y el pin de conexión a Arduino. Los pines asignados a cada rele están en el sketch y son para el rele de control de spray el pin 8 y el de vaciado de presion el pin 9. Los pines de entrada de 12v para controlar las electrovalvulas  son los que tienen tornilleria. Debeis elegir los pines que estan normalmente abiertos y que cuando reciben la señal de Arduino, cierran el circuito y dan 12v de salida a la electrovalvula.



La valvula solenoide es de este tipo, no tiene polaridad especifica, y debeis aseguraros de que sea del tipo NORMALMENTE CERRADA.

Un video de Youtube de como funciona todo el mecanismo instalado:
(PROXIMAMENTE)

El sketch ya terminado es el siguiente:

// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// BME280
// This code is designed to work with the BME280_I2CS I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/content/Humidity?sku=BME280_I2CS#tabs-0-product_tabset-2
//Compiled for Arduino UNO ver. IDE 1.8.10

#include<Wire.h>

int a,b,c = 0;
int pin = 0;// Pin analogico 0 botonadura

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnr      0
#define btnc      2
#define btnl      4
#define btnNONE   5
#define btnOK     6


//define bytes for menu response
byte byter = B00000;;
byte bytec = B00000;
byte bytel = B00000;
byte byteout = B00000;

unsigned long tAntes = 0;
int flag = 0;


//Define pin reles
int led1 = 8;
int led2 = 9;

int temperaturafin = 0;
int humedadfin = 0;
double humedad = 0.0;
double temperatura = 0.0;
//Valores de inicio configurados
int tempset = 32.00;//Limite de temperatura inicio spray
int humedadset = 60;//Limite de humedad maxima spray 
int timespray = 30;///Tiempo de duracion spray: 10=1 segundo
int timeintsp = 12;//Tiempo entre sprays: 6=1 minuto
int modificador;
int vaciado = 1500;//tiempo de activado rele antigoteo, justo para evitar goteo sin vaciado: 1.5 seg

unsigned long tAntes1 = 0;
unsigned long tAntes2 = 0;
unsigned long tAntes3 = 0;
unsigned long tAntes4 = 0;
unsigned long tAntes5 = 0;
unsigned long tAntes6 = 0;

String modificadorst;

boolean encendido = false;

// BME280 I2C address is 0x76(108)
#define Addr 0x76

#define PIN_SCE   4
#define PIN_RESET 3
#define PIN_DC    5
#define PIN_SDIN  6
#define PIN_SCLK  7

#define LCD_C     LOW
#define LCD_D     HIGH

#define LCD_X     84
#define LCD_Y     48

static const byte ASCII[][5] =
{
 {0x00, 0x00, 0x00, 0x00, 0x00} // 20  
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j 
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f →
};

void LcdCharacter(char character)
{
  LcdWrite(LCD_D, 0x00);
  for (int index = 0; index < 5; index++)
  {
    LcdWrite(LCD_D, ASCII[character - 0x20][index]);
  }
  LcdWrite(LCD_D, 0x00);
}

void LcdClear(void)
{
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    LcdWrite(LCD_D, 0x00);
  }
}

void LcdInitialise(void)
{
  pinMode(PIN_SCE, OUTPUT);
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC, OUTPUT);
  pinMode(PIN_SDIN, OUTPUT);
  pinMode(PIN_SCLK, OUTPUT);
  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_RESET, HIGH);
  LcdWrite(LCD_C, 0x21 );  // LCD Extended Commands.
  LcdWrite(LCD_C, 0xB1 );  // Set LCD Vop (Contrast). 
  LcdWrite(LCD_C, 0x04 );  // Set Temp coefficent. //0x04
  LcdWrite(LCD_C, 0x14 );  // LCD bias mode 1:48. //0x13
  LcdWrite(LCD_C, 0x20 );  // LCD Basic Commands
  LcdWrite(LCD_C, 0x0C );  // LCD in normal mode.
}

void LcdString(char *characters)
{
  while (*characters)
  {
    LcdCharacter(*characters++);
  }
}

void LcdWrite(byte dc, byte data)
{
  digitalWrite(PIN_DC, dc);
  digitalWrite(PIN_SCE, LOW);
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
  digitalWrite(PIN_SCE, HIGH);
}


void setup()
{
  // initialize the digital pin as an output.
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);  
  // Initialise I2C communication as MASTER
  Wire.begin();
  // Initialise Serial communication, set baud rate = 9600
  Serial.begin(9600);
  
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  
  LcdInitialise();
  LcdClear();
  gotoXY(0,0);
  LcdString("V.1.20.06     ");
  gotoXY(1,2);
  LcdString("Iniciando Medicion...");
  delay(3000);
  LcdClear();
}

void gotoXY(int x, int y)
{
  LcdWrite( 0, 0x80 | x);  // Column.
  LcdWrite( 0, 0x40 | y);  // Row.  
  pinMode(A0, INPUT_PULLUP); // sets analog pin for input
}


void loop()
{
  buttonselect();// Selector botones
  
  unsigned int b1[24];
  unsigned int data[8];
  unsigned int dig_H1 = 0;
  for(int i = 0; i < 24; i++)
  {
    // Start I2C Transmission
    Wire.beginTransmission(Addr);
    // Select data register
    Wire.write((136+i));
    // Stop I2C Transmission
    Wire.endTransmission();

    // Request 1 byte of data
    Wire.requestFrom(Addr, 1);

    // Read 24 bytes of data
    if(Wire.available() == 1)
    {
      b1[i] = Wire.read();
    }
  }

  // Convert the data
  // temp coefficients
  unsigned int dig_T1 = (b1[0] & 0xff) + ((b1[1] & 0xff) * 256);
  int dig_T2 = b1[2] + (b1[3] * 256);
  int dig_T3 = b1[4] + (b1[5] * 256);

  // pressure coefficients
  unsigned int dig_P1 = (b1[6] & 0xff) + ((b1[7] & 0xff ) * 256);
  int dig_P2 = b1[8] + (b1[9] * 256);
  int dig_P3 = b1[10] + (b1[11] * 256);
  int dig_P4 = b1[12] + (b1[13] * 256);
  int dig_P5 = b1[14] + (b1[15] * 256);
  int dig_P6 = b1[16] + (b1[17] * 256);
  int dig_P7 = b1[18] + (b1[19] * 256);
  int dig_P8 = b1[20] + (b1[21] * 256);
  int dig_P9 = b1[22] + (b1[23] * 256);

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select data register
  Wire.write(161);
  // Stop I2C Transmission
  Wire.endTransmission();

  // Request 1 byte of data
  Wire.requestFrom(Addr, 1);

  // Read 1 byte of data
  if(Wire.available() == 1)
  {
    dig_H1 = Wire.read();
  }

  for(int i = 0; i < 7; i++)
  {
    // Start I2C Transmission
    Wire.beginTransmission(Addr);
    // Select data register
    Wire.write((225+i));
    // Stop I2C Transmission
    Wire.endTransmission();
   
    // Request 1 byte of data
    Wire.requestFrom(Addr, 1);
   
    // Read 7 bytes of data
    if(Wire.available() == 1)
    {
      b1[i] = Wire.read();
    }
  }

  // Convert the data
  // humidity coefficients
  int dig_H2 = b1[0] + (b1[1] * 256);
  unsigned int dig_H3 = b1[2] & 0xFF ;
  int dig_H4 = (b1[3] * 16) + (b1[4] & 0xF);
  int dig_H5 = (b1[4] / 16) + (b1[5] * 16);
  int dig_H6 = b1[6];

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select control humidity register
  Wire.write(0xF2);
  // Humidity over sampling rate = 1
  Wire.write(0x01);
  // Stop I2C Transmission
  Wire.endTransmission();

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select control measurement register
  Wire.write(0xF4);
  // Normal mode, temp and pressure over sampling rate = 1
  Wire.write(0x27);
  // Stop I2C Transmission
  Wire.endTransmission();

  // Start I2C Transmission
  Wire.beginTransmission(Addr);
  // Select config register
  Wire.write(0xF5);
  // Stand_by time = 1000ms
  Wire.write(0xA0);
  // Stop I2C Transmission
  Wire.endTransmission();

  for(int i = 0; i < 8; i++)
  {
    // Start I2C Transmission
    Wire.beginTransmission(Addr);
    // Select data register
    Wire.write((247+i));
    // Stop I2C Transmission
    Wire.endTransmission();
   
    // Request 1 byte of data
    Wire.requestFrom(Addr, 1);
   
    // Read 8 bytes of data
    if(Wire.available() == 1)
    {
      data[i] = Wire.read();
    }
  }

  // Convert pressure and temperature data to 19-bits
  long adc_p = (((long)(data[0] & 0xFF) * 65536) + ((long)(data[1] & 0xFF) * 256) + (long)(data[2] & 0xF0)) / 16;
  long adc_t = (((long)(data[3] & 0xFF) * 65536) + ((long)(data[4] & 0xFF) * 256) + (long)(data[5] & 0xF0)) / 16;
  // Convert the humidity data
  long adc_h = ((long)(data[6] & 0xFF) * 256 + (long)(data[7] & 0xFF));

  // Temperature offset calculations
  double var1 = (((double)adc_t) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
  double var2 = ((((double)adc_t) / 131072.0 - ((double)dig_T1) / 8192.0) *
  (((double)adc_t)/131072.0 - ((double)dig_T1)/8192.0)) * ((double)dig_T3);
  double t_fine = (long)(var1 + var2);
  double cTemp = (var1 + var2) / 5120.0;
  double fTemp = cTemp * 1.8 + 32;

  // Pressure offset calculations
  var1 = ((double)t_fine / 2.0) - 64000.0;
  var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
  var2 = var2 + var1 * ((double)dig_P5) * 2.0;
  var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
  var1 = (((double) dig_P3) * var1 * var1 / 524288.0 + ((double) dig_P2) * var1) / 524288.0;
  var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
  double p = 1048576.0 - (double)adc_p;
  p = (p - (var2 / 4096.0)) * 6250.0 / var1;
  var1 = ((double) dig_P9) * p * p / 2147483648.0;
  var2 = p * ((double) dig_P8) / 32768.0;
  double pressure = (p + (var1 + var2 + ((double)dig_P7)) / 16.0) / 100;

  // Humidity offset calculations
  double var_H = (((double)t_fine) - 76800.0);
  var_H = (adc_h - (dig_H4 * 64.0 + dig_H5 / 16384.0 * var_H)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * var_H * (1.0 + dig_H3 / 67108864.0 * var_H)));
  double humidity = var_H * (1.0 -  dig_H1 * var_H / 524288.0);
  if(humidity > 100.0)
  {
    humidity = 100.0;
  }
  else if(humidity < 0.0)
  {
    humidity = 0.0;
  }

 /*
  // Output data to serial monitor
  Serial.print("Temperature in Celsius : ");
  Serial.print(cTemp);
  Serial.println(" C");
  //Serial.print("Temperature in Fahrenheit : ");
  //Serial.print(fTemp);
  //Serial.println(" F");
  Serial.print("Pressure : ");
  Serial.print(pressure);
  Serial.println(" hPa");
  Serial.print("Relative Humidity : ");
  Serial.print(humidity);
  Serial.println(" RH");
  */
  
  unsigned long time_now;
  
  time_now = millis();
  if ((long)(time_now - tAntes3) > 1L * 10000L) // regulador de tiempo presentacion lcd - 10 seg
  {
  tAntes3 = time_now;
  
  //LcdInitialise();
  //LcdClear();
  gotoXY(0,0);
  LcdString("Humed...");
  humedad = humidity;
  char buf1[12];
  gotoXY(50,0);
  LcdString(dtostrf(humedad, 5, 2, buf1));
  gotoXY(0,1);
  LcdString("Temp....");
  temperatura = cTemp;
  char buf2[12];
  gotoXY(50,1);
  LcdString(dtostrf(temperatura, 5, 2, buf2));  
  }
  
  time_now = millis();
  if ((long)(time_now - tAntes2) > 1L * 10000L) // regulador de tiempo medida datos - 10 seg
  {
  tAntes2 = time_now;
  temperaturafin = temperatura;
  humedadfin = humedad;
  }
  
  //Control reles
  if(encendido == true)// Stop actividad reles mientras botones pulsados
  {
  time_now = millis();  
  if ((long)(time_now - tAntes1) > timeintsp * 10000L) // regulador de tiempo reles - x10seg
  {
  tAntes1 = time_now;
    
  if (temperaturafin >= tempset && humedadfin <= humedadset)
  {
   digitalWrite(led1, LOW);   //  activa rele spray
   delay(timespray*100);  // segundos activado: 10x100ms = 1 seg.
   digitalWrite(led1, HIGH);    // desactiva rele spray
   delay(100);               // wait for a second
   digitalWrite(led2, LOW);   // activa rele de descarga
   delay(vaciado);               // segundos activado: 2 (solo para reduccion presion y evitar goteo sin vaciar)
   
   digitalWrite(led2, HIGH);    // desactiva rele de descarga
   }

  if (temperaturafin < tempset)// Desactiva los reles a menos tempset
  {
   digitalWrite(led1, HIGH);
   digitalWrite(led2, HIGH);
  }
  //Reles desactivados por defecto - redundante
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  }
  
  //Contador atras segundos para spray  
   gotoXY(1,2);
   char buf[12];
   LcdString("ON:         ");
   gotoXY(1,2);
   LcdString("ON:");
   LcdString(dtostrf(((timeintsp * 10000L - (time_now - tAntes1))/960), 1, 0, buf));
   
 } // fin control encendido
  
}// Fin loop
  
  void buttonselect()
{
  lcd_key = readButtons();  // read the buttons

  switch (lcd_key)               // depending on which button was pushed, we perform an action
 {
   case btnl:
     {
     //gotoXY(1,3);
     //LcdString("     ");  
     //gotoXY(1,3);
     //LcdString("btnL");
     
     if(byteout == B00000)
     {
       bytel = B00100;
       bytec = B00000;
       byter = B00000;
       
     } 
     if(byteout == B00100)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     if(byteout == B00010)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     if(byteout == B00001)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     if(byteout == B00110)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     if(byteout == B00101)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     if(byteout == B01100)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     if(byteout == B01001)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     if(byteout == B01000)
     {
       bytel = B01100;
       bytec = B01100;
       byter = B01100;
     }
     delay(100);
     encendido = false;
     break;
     }
   case btnc:
     {
     //gotoXY(1,3);
     //LcdString("     ");  
     //gotoXY(1,3);
     //LcdString("btnC");
     if(byteout == B00000)
     {
       bytec = B00010;
      //byter = B00000;
      //bytel = B00000;
     }   
     if(byteout == B00010)
     {
       bytec = B01010;
       byter = B01010;
       bytel = B01010;
     }
     if(byteout == B00110)
     {
       bytec = B01010;
       byter = B01010;
       bytel = B01010;
     }
     if(byteout == B00011)
     {
       bytec = B01010;
       byter = B01010;
       bytel = B01010;
     }
     if(byteout == B00100)
     {
       bytec = B01010;
       byter = B01010;
       bytel = B01010;
     }
     if(byteout == B00001)
     {
       bytec = B01010;
       byter = B01010;
       bytel = B01010;
     }
     if(byteout == B01001)
     {
       bytec = B01010;
       byter = B01010;
       bytel = B01010;
     }
     if(byteout == B01000)
     {
       bytec = B01010;
       byter = B01010;
       bytel = B01010;
     }
     delay(100);
     encendido = false;
     break;
     }
   case btnr:
     {
     //gotoXY(1,3);
     //LcdString("     ");  
     //gotoXY(1,3);
     //LcdString("btnR");
     byter = B00001;
     bytec = B00001;
     bytel = B00001;
     if(byteout == B00001)
     {
       bytec = B01001;
       byter = B01001;
       bytel = B01001;
     }
     delay(100);
     encendido = false;
     break;
     }
   
   case btnNONE:
     {
     unsigned long time_now = millis();  
     if ((long)((time_now - tAntes6) > 5000) && (flag == 0)){//Temporizador mantenimiento tras boton pulsado:5000-15000  
     tAntes6 = time_now;
     byter = B00000;
     bytec = B00000;
     bytel = B00000;
     byteout = B00000;
     //gotoXY(1,3);
     //LcdString("     ");  
     //gotoXY(1,3);
     //LcdString("btnNO");
     encendido = true;
     }
     delay(100);
     break;
     }
  }

 byteout = byter | bytec | bytel;

 //Menu de opciones
if (byteout == B00001 && flag == 1){
     modificador = tempset;
     modificadorst = "tempset";
     gotoXY(1,4);
     LcdString("            ");
     gotoXY(1,4);
     LcdString("TEMPERATURA");
     gotoXY(1,5);
     LcdString("            ");
     gotoXY(5,5);
     LcdString("-");
     gotoXY(50,5);
     LcdString("+");
     char buf[12];
     gotoXY(10,5);
     LcdString(dtostrf(modificador, 5, 2, buf));
     //LcdClear();  
     delay(100);
     flag == 0;
     byteout = B01000;
     }
if (byteout == B00010 && flag == 1){
     modificador = timeintsp;
     modificadorst = "timeintsp";
     gotoXY(1,4);
     LcdString("            ");
     gotoXY(1,4);
     LcdString("T.INTSPRx10s");
     gotoXY(1,5);
     LcdString("            ");
     gotoXY(5,5);
     LcdString("-");
     char buf[12];
     gotoXY(10,5);
     LcdString(dtostrf(modificador, 5, 2, buf));
     gotoXY(50,5);
     LcdString("+");
     //LcdClear();  
     delay(100);
     flag == 0;
     byteout = B01000;
     }
if (byteout == B00100 && flag == 1){
     modificador = timespray;
     modificadorst = "timespray";
     gotoXY(1,4);
     LcdString("           ");
     gotoXY(1,4);
     LcdString("T.SPRYx100ms");
     gotoXY(1,5);
     LcdString("            ");
     gotoXY(5,5);
     LcdString("-");
     char buf[12];
     gotoXY(10,5);
     LcdString(dtostrf(modificador, 5, 2, buf));
     gotoXY(50,5);
     LcdString("+");
     //LcdClear();
     delay(100);
     flag == 0;
     byteout = B01000;
     }
if (byteout == B01001 && flag == 1){
     modificador = humedadset;
     modificadorst = "humedadset";
     gotoXY(1,4);
     LcdString("           ");
     gotoXY(1,4);
     LcdString("Humedad     ");
     gotoXY(1,5);
     LcdString("            ");
     gotoXY(5,5);
     LcdString("-");
     char buf[12];
     gotoXY(10,5);
     LcdString(dtostrf(modificador, 5, 2, buf));
     gotoXY(50,5);
     LcdString("+");
     //LcdClear();
     delay(100);
     flag == 0;
     byteout = B01000;
     }     
if (byteout == B01010 && flag == 1){
     modificador++;
     gotoXY(5,5);
     LcdString("-");
     char buf[12];
     gotoXY(10,5);
     LcdString(dtostrf(modificador, 5, 2, buf));
     gotoXY(50,5);
     LcdString("+");
     if (modificadorst == "timespray"){
        timespray = modificador;
     }
     if (modificadorst == "timeintsp"){
        timeintsp = modificador;
     }
     if (modificadorst == "tempset"){
        tempset = modificador;
     }
     if (modificadorst == "humedadset"){
        humedadset = modificador;
     }
     byteout = B01000;
     byter = B01000;
     bytec = B01000;
     bytel = B01000;
     //LcdClear();  
     delay(100);
     flag == 0;
     } 

if (byteout == B01100 && flag == 1){
     modificador--;
     gotoXY(5,5);
     LcdString("-");
     char buf[12];
     gotoXY(10,5);
     LcdString(dtostrf(modificador, 5, 2, buf));
     gotoXY(50,5);
     LcdString("+");
     if (modificadorst == "timespray"){
        timespray = modificador;
     }
     if (modificadorst == "timeintsp"){
        timeintsp = modificador;
     }
     if (modificadorst == "tempset"){
        tempset = modificador;
     }
     if (modificadorst == "humedadset"){
        humedadset = modificador;
     }
     byteout = B01000;
     byter = B01000;
     bytec = B01000;
     bytel = B01000;
     //LcdClear();  
     delay(100);
     flag == 0;
     }  

if (byteout == B00000 && flag == 0){
     //long time_now = millis();  
     //if ((long)((time_now - tAntes5) > 5000) && (flag == 0)){//Temporizador mantenimiento boton pulsado:5000-15000  
     //tAntes5 = time_now;
     gotoXY(1,4);
     LcdString("            ");
     gotoXY(1,5);
     LcdString("            ");
     gotoXY(1,5);
     LcdString("TSP TIN T/H");
     //LcdClear(); 
     byter = B00000;
     bytec = B00000;
     bytel = B00000;
     byteout = B00000;
     //}
     delay(100);
     encendido = true;
     }

   gotoXY(1,3);
   char buf[12];
   LcdString(dtostrf((timespray*100/1000), 1, 0, buf));
   LcdString("s.");
   LcdString(dtostrf((timeintsp*10/60), 1, 0, buf));
   LcdString("m.");
   LcdString(dtostrf(tempset, 1, 0, buf));
   LcdString(".");
   LcdString(dtostrf(humedadset, 1, 0, buf));
   
  //lcd.setCursor(0,1);   
  //lcd.print(adc_key_in); //valor de voltaje
  //lcd.setCursor(8,1);            // move to the of the second line
  //lcd.print(flag);  // presenta el valor de flag
}

// read the buttons
int readButtons()
{
 adc_key_in = analogRead(0);      // read the value from the sensor 
 unsigned long time_now = millis();

//Valores para botonadura simple de 3 resistencias de 3k Ohm en serie

 if (adc_key_in < 250) {
    flag = 1;
    delay(50);
    //c = 0;
     }
   
 if ((long)((time_now - tAntes) > 200) && (adc_key_in > 900))//Temporizador deteccion boton no pulsado
  {  
   tAntes = time_now;
   flag = 0;
   //return btnNONE; // Ningun boton pulsado
   }
        
 if (flag != 0){
    tAntes6 = time_now;//Poner temporizador a 0 para boton no pulsado
   if (adc_key_in < 140 && adc_key_in > 10) 
   {tAntes = time_now;
    flag = 1;
    delay(50); 
    return btnr;}
   if (adc_key_in < 190 && adc_key_in > 145) 
   {tAntes = time_now;
    flag = 1;
    delay(50); 
    return btnc;}
   if (adc_key_in > 200 && adc_key_in < 230) 
   {tAntes = time_now;
    flag = 1;
    delay(50);
    return btnl;}
  }
  
 //lcd.setCursor(12,1);            // move to the of the second line
 //lcd.print(flag);  // presenta el valor de flag

  
 if (flag == 0) return btnNONE; // Ningun boton pulsado 
 //if ((long)((time_now - tAntes4) > 15000) && (flag == 0)){
 //return btnNONE; // Ningun boton pulsado 
  //}
 // if (adc_key_in > 900) return btnNONE; // Ningun boton pulsado  

}

// FIN READ BUTTONS