Alarma

Buenas, espero que me podáis ayudar con esto... Resulta que nunca antes he hecho nada con Arduino y he empezado de cero, teniendo poco tiempo para hacer un proyecto y sólo pudiendo utilizar este soporte (de hecho me queda menos de una semana para presentarlo) y he hecho la programación como buenamente he podido.

El proyecto consiste en una alarma de vivienda, la cual lleva un mando a distancia por control RF, un sensor ultrasónico, tres sensores PIR, un LED y una sirena.

Cuando se pulsa la secuencia: A, A, B, C, D con el mando, la alarma se activa y, en el caso de que los sensores detecten movimiento o proximidad, el led se encenderá y la sirena sonará.
Si se pulsa la secuencia: D, A, B, C, D, la alarma se desactivará, el led se apagará y la sirena no sonará.
Si se pulsa el botón B, el sistema se reseteará en caso de bloqueo y volverá a estar en el estado inicial (desactivada).
Si se pulsa el botón C, la sirena sonará por intervalos de dos segundos y el led parpadeará con el mismo intervalo.

Por otro lado, desde una página web se puede encender y apagar el led.

El problema que me surge, y por el que pido ayuda aquí, es el siguiente: al tratar de introducir en el programa las secuencias de activación o desactivación con el mando (como si fuese una contraseña), me da errores en el compilador y no sé cómo subsanar.
He probado con el código que está a modo de comentario pero no acababa de funcionar bien, así que he tratado de probar con el otro, el que hace cambios de estado y comparativas con los botones; pero me da un fallo en el programa que no soy capaz de arreglar.

He de decir que el código tiene partes que son copia y pega de foros, ya que como he dicho antes, he empezado de cero a hacer todo esto.

¿Me podríais ayudar a resolver el error? Muchas gracias. Adjunto el código de programa.

alarma_ethernet1.ino (11.1 KB)

Hola de nuevo.

He simplificado un poco el programa quitando comentarios a ver si así podía descubrir el error. Pienso que tal vez no he puesto bien un bucle dentro del otro. ¿Cómo puedo hacer eso, dos bucles dentro de un mismo bucle (para eso de la contraseña)?

¿Y cómo hago para definir dos contraseñas diferentes en un mismo bucle (que no sé si así funcionaría mejor)?

Adjunto el programa modificado:

#define WEBDUINO_AUTH_REALM "ALARMNET"

#include <SPI.h>
#include <Ethernet.h> 
#include <WebServer.h> 

//Servidor
EthernetServer server(80);

static uint8_t mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
static uint8_t ip[] = {192,168,0,194};
String HTTP_req; 
boolean LED9_status = 0;

//Declaración de variables de alarma
long distancia_1;
long PIR_1; 
long PIR_2; 
long PIR_3;
long tiempo;
long Punto;
long A = 2;
long B = 3;
long C = 4;
long D = 5;
long Activacion; 

//Configuración del bucle de red y variables
void setup()
{   Ethernet.begin(mac, ip);  
    server.begin();           
    Serial.begin(9600); 
    Punto = int( 15 );
    
    pinMode(14, OUTPUT); //Sirena
    pinMode(9, OUTPUT); //Led     
    pinMode (A, INPUT);
    pinMode (B, INPUT);
    pinMode (C, INPUT);
    pinMode (D, INPUT);
    pinMode(15, OUTPUT); //salida ultrasónico
    pinMode(16, INPUT); //rebote ultrasónico 
    pinMode(6, INPUT); //S1
    pinMode(7, INPUT); //S2
    pinMode(8, INPUT); //S3
      
    digitalWrite(2,LOW);
    digitalWrite(5,LOW);
      Activacion = 0;    
}

//Buble de red+alarma
void loop()

//Comienzo bucle alarma
{                       
      A = digitalRead (2);
      D = digitalRead (5);
         
     //Clave
    int clave []= {D,A,B,C,D};
    int sec []= {100,100,100,100,100}; 
    int estado = 0;

  void loop () {
       if (digitalRead(D)) {
       sec [estado] =0; 
       estado++;
       delay (500);
       }
       if (digitalRead(A)){
       sec [estado] =1;  
       estado++;
       delay (500);
       }
        if (digitalRead(B)){
        sec [estado] =2;
       estado++;
       delay (500);
       }
        if (digitalRead(C)){
       sec [estado] =3; 
       estado++;
       delay (500);
       }
        if (digitalRead(D)){
       sec [estado] =4;  
       estado++;
       delay (500);
       }   
        if (estado==5) {
        if((sec[0]==clave[D])&&(sec[1]==clave[A]&&(sec[2]==clave[B])&&(sec[3]==clave[C])&&(sec[4]==clave[D]))
        {((Activacion=0);
        digitalWrite (14, LOW);
        digitalWrite (9,LOW));}
        }
    }
 
   {
   int clave []= {A,A,B,C,D};
   int sec []= {100,100,100,100,100};  
   int estado = 0;

   void loop (){ 
       if (digitalRead(A)) { 
       sec [estado] =0;  
       estado++;
       delay (500);
       }
       if (digitalRead(A)){
       sec [estado] =1;  
       estado++;
       delay (500);
       }
        if (digitalRead(B)){
       sec [estado] =2;
       estado++;
       delay (500);
       }
        if (digitalRead(C)){
       sec [estado] =3;  
       estado++;
       delay (500);
       }
        if (digitalRead(D)){
       sec [estado] =4;  
       estado++;
       delay (500);
       }   
        if (estado==5){
        if((sec[0]==clave[A])&&(sec[1]==clave[A]&&(sec[2]==clave[B])&&(sec[3]==clave[C])&&(sec[4]==clave[D]))
 
    {digitalWrite (5, LOW); Activacion = 1;} 
       }
   }
    
     if (Activacion == 1)
          {              
                //Control RF 
                digitalWrite(4,LOW); 
                digitalWrite(3,LOW);
                              
                //Sensor Ultrasonico
                digitalWrite(15,LOW); 
                delayMicroseconds(5);
                digitalWrite(15, HIGH); 
                delayMicroseconds(10);
                tiempo=pulseIn(16, HIGH);
                distancia_1= int(0.017*tiempo);
                Serial.println("Distancia_1 ");
                Serial.println(distancia_1);
                Serial.println(" cm");
                delay(100);
                
                PIR_1 = digitalRead (6);
                PIR_2 = digitalRead (7);
                PIR_3 = digitalRead (8);
            
                D = digitalRead (5);
                A = digitalRead (2);             
               
                if (distancia_1 <= Punto || PIR_1 == HIGH || PIR_2 == HIGH || PIR_3 == HIGH) 
                      {digitalWrite (14, HIGH );
                       digitalWrite (9, HIGH );} 
                else if (D == HIGH )
                      {digitalWrite (14, LOW );
                       digitalWrite (9, LOW );}
              
               C = digitalRead (4);
               if (C == HIGH)
               {
               digitalWrite (14, HIGH);
               digitalWrite (9, HIGH);
               delay(1000);
               digitalWrite (14, LOW);
               digitalWrite (9, LOW);
               delay(1000);
               digitalWrite (14, HIGH);
               digitalWrite (9, HIGH);
               delay(1000);
               digitalWrite (14, LOW);
               digitalWrite (9, LOW);
               }
        } 
    
//Comienzo bucle de red
  EthernetClient client = server.available();
   if (client)                                
      {  boolean currentLineIsBlank = true;
         while (client.connected()) 
           { if (client.available())     
               { char c = client.read();
                 HTTP_req += c;       
                 if (c == '\n' && currentLineIsBlank)
                    { client.println("HTTP/1.1 200 OK");
                      client.println("Content-Type: text/html");
                      client.println("Connection: close");
                      client.println();
                      client.println("<!DOCTYPE html>"); 
                      client.println("<html>");
                      client.println("<head>");
                      client.println("<title>Home Alarmnet</title>");
                      client.println("</head>");
                      client.println("<body>");
                      client.println("<h1>HOME ALARMNET</h1>");
                      client.println("<p>Haga click aquí para encender y apagar las luces.</p>");
                      client.println("<form method=\"get\">");
                      ProcessCheckbox(client);
                      client.println("</form>");
                      client.println("</body>");
                      client.println("</html>");
                      Serial.print(HTTP_req);
                      HTTP_req = "";
                      break;
                    }
                 if (c == '\n')
                      currentLineIsBlank = true;
                 else if (c != '\r')
                      currentLineIsBlank = false;
                      } 
                    } 
                      delay(10); 
                      client.stop();
   }
}

void ProcessCheckbox(EthernetClient cl)
  {  if (HTTP_req.indexOf("LED9=9") > -1)
          LED9_status = !LED9_status ; 
          digitalWrite(9, LED9_status);
     if (LED9_status)
             cl.println("<input type=\"checkbox\" name=\"LED9\" value=\"9\" \\ onclick=\"submit();\" checked>LED9");
     else
             cl.println("<input type=\"checkbox\" name=\"LED9\" value=\"9\" \\  onclick=\"submit();\">LED9");
      
  }
   } 
   [code] 
 Donde me da este error:

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
Home_Alarmnet.ino: In function 'void loop()':
Home_Alarmnet:65: error: a function-definition is not allowed here before '{' token
Home_Alarmnet:237: error: expected `}' at end of input

POr favor, lee las normas, ya te mandé privado. Usa los tags para poner códigos. No es leible tu código de este modo o se dificulta hacerlo.
Gracias.

Lo siento, no me ha llegado ningún privado o no logro localizarlo. Ya lo he modificado de forma que sea más legible. Gracias.

Hola Morma,

Creo que no estás direccionando correctamente la array que contiene la clave. ¿Has probado esto?

if((sec[0]==clave[0])&&(sec[1]==clave[1]&&(sec[2]==clave[2])&&(sec[3]==clave[3])&&(sec[4]==clave[4]))

Un saludo,

Juanjo

Hola de nuevo Morma,

Viendo tu código algo mas al detalle, no puede haber más que una única función void loop() y veo que lo tienes hasta 3 veces.
Por otro lado cada vez que se ejecuta la función loop reestableces el array de las teclas pulsadas a 100

int sec []= {100,100,100,100,100};

con lo que perderás los valores pulsados con anterioridad. La inicialización del array debería estar en el setup(), así como la definición de las secuencias de activación y desactivación ( int clave []= {D,A,B,C,D}; y int clave []= {A,A,B,C,D}:wink:

En la función loop() pondría el código para que controle la secuencia de teclas pulsadas y poder realizar las comprobaciones pertinentes.

Deberás replantear tu código.

Saludos,

Juanjo

Muchas gracias por tu respuesta Juanjo. Mientras esperaba vuestras respuestas, he replanteado el código haciendo esa opción de contraseña con otro método que había encontrado ya que el mío no me acababa de cuadrar por lo del void loop varias veces (e intentándolo replantear me salían errores por varios sitios), así que lo he replanteado de nuevo y he hecho este código, lo pongo por si hay algún error en la parte donde digo que quiero pulsar una secuencia y en realidad esté diciendo en el código que se pulsan todos a la vez... o algo así. Ahí va el código:

#define WEBDUINO_AUTH_REALM "ALARMNET"

//Librerías
#include <SPI.h>
#include <Ethernet.h> //Librería de la placa Ethernet
#include <WebServer.h> //Librería del código para hacer cosas con la placa 

//Servidor
EthernetServer server(80);
static uint8_t mac[6] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
static uint8_t ip[] = {192,168,0,194};
String HTTP_req;
boolean LED9_status = 0;

//Declaración de variables de alarma
long distancia_1;
long PIR_1;
long PIR_2;
long PIR_3;
long tiempo;
long Punto; 
long A = 2;
long B = 3;
long C = 4;
long D = 5;
long Activacion;

//Configuración del bucle de red y variables
void setup()
{   Ethernet.begin(mac, ip);  
    server.begin();           
    Serial.begin(9600);

      Punto = int( 15 );
      pinMode(14, OUTPUT);//Sirena 
      pinMode(9, OUTPUT);//LED
      
      //Mando
     pinMode (A, INPUT);
     pinMode (B, INPUT);
     pinMode (C, INPUT);
     pinMode (D, INPUT);
    
      
      //Sensor Ultra
      pinMode(15, OUTPUT);//salida ultrasónico
      pinMode(16, INPUT); //entrada ultrasónico
     
      pinMode(6, INPUT); //S1
      pinMode(7, INPUT);//S2
      pinMode(8, INPUT); //S3
      
      // Habilitadores
      digitalWrite(2,LOW);
      digitalWrite(5,LOW);
      Activacion = 0;  
}

//Buble de red+alarma
void loop()

//Comienzo bucle alarma
//Activar y Desactivar
                
    {            
                
      A = digitalRead (2);
      B = digitalRead (3);
      C = digitalRead (4);
      D = digitalRead (5);
  
  if (D == HIGH){ {delay (1000);} //original
  if (A = HIGH) { delay (1000);} 
  if (B = HIGH){ delay (1000);}    // A modo contraseña
  if (C = HIGH) {delay (1000);}
  else if (D == HIGH);
  {(Activacion = 0); 
  digitalWrite (14, LOW); digitalWrite (9, LOW);}  
  }                                               

 if (A == HIGH){ {delay (1000);} 
 if (A = HIGH) { delay (1000);} 
 if (B = HIGH) {delay (1000);}
 if (C = HIGH) {delay (1000);}
 else if (D == HIGH); 
{digitalWrite (5, LOW); 
(Activacion = 1);} 
 }    
     if (Activacion == 1)
          {   
            
                //Control RF 
                digitalWrite(4,LOW);
                digitalWrite(3,LOW);
                
                //Sensor Ultrasonico
                digitalWrite(15,LOW); 
                delayMicroseconds(5);
                digitalWrite(15, HIGH); 
                delayMicroseconds(10);
                tiempo=pulseIn(16, HIGH);
                distancia_1= int(0.017*tiempo);
                Serial.println("Distancia_1 ");
                Serial.println(distancia_1);
                Serial.println(" cm");
                delay(100);
                
                
                PIR_1 = digitalRead (6);
                PIR_2 = digitalRead (7);
                PIR_3 = digitalRead (8);
            
                
                //Activar Desactivar la Sirena y Luces
               D = digitalRead (5);
               A = digitalRead (2); 
               
               
            
               if (distancia_1 <= Punto || PIR_1 == HIGH || PIR_2 == HIGH || PIR_3 == HIGH) {digitalWrite (14, HIGH ); digitalWrite (9, HIGH );} 
                 else if (D == HIGH ) {digitalWrite (14, LOW ); digitalWrite (9, LOW );} 
              
               C = digitalRead (4); 
               if (C == HIGH) 
               {
               digitalWrite (14, HIGH);        
               digitalWrite (9, HIGH);
               delay(1000);
               digitalWrite (14, LOW);
               digitalWrite (9, LOW);          
               delay(1000);
               digitalWrite (14, HIGH);
               digitalWrite (9, HIGH);       
               delay(1000);
               digitalWrite (14, LOW);
               digitalWrite (9, LOW);        
               }
        } 
 
//Comienzo bucle de red
  EthernetClient client = server.available();
   if (client)                                
      {  boolean currentLineIsBlank = true;
         while (client.connected()) 
           { if (client.available())    
               { char c = client.read(); 
                 HTTP_req += c;        
                 if (c == '\n' && currentLineIsBlank)
                    { client.println("HTTP/1.1 200 OK");
                      client.println("Content-Type: text/html");
                      client.println("Connection: close");
                      client.println();
                      client.println("<!DOCTYPE html>");
                    client.println("<html>");
                      client.println("<head>");
                      client.println("<title>Home Alarmnet</title>");
                      client.println("</head>");
                      client.println("<body>");
                      client.println("<h1>HOME ALARMNET</h1>");
                      client.println("<p>Haga click aquí para encender y apagar las luces.</p>");
                      client.println("<form method=\"get\">");
                      ProcessCheckbox(client);
                      client.println("</form>");
                      client.println("</body>");
                      client.println("</html>");
                      Serial.print(HTTP_req);
                      HTTP_req = ""; 
                      break;
                    }
                 if (c == '\n')
                      currentLineIsBlank = true;
                 else if (c != '\r')
                      currentLineIsBlank = false;
              } 
           } 
        delay(10);     
        client.stop();
   }  
    }


//Proceso para pinchar en el check del recuadro y ON del LED mientras se pincha (del proyecto del LED por internet)
void ProcessCheckbox(EthernetClient cl)
  {  if (HTTP_req.indexOf("LED9=9") > -1)  
          LED9_status = !LED9_status ;  

     digitalWrite(9, LED9_status);
     if (LED9_status)
             cl.println("<input type=\"checkbox\" name=\"LED9\" value=\"9\" \\ onclick=\"submit();\" checked>LED9");
     else
             cl.println("<input type=\"checkbox\" name=\"LED9\" value=\"9\" \\  onclick=\"submit();\">LED9");
   }
   
[code]

Hola Morma,

No creo que sea la mejor forma de abordar el control de la secuencia de pulsaciones.
¿Por qué no nos explicas qué componentes estás utilizando como mando de RF y su receptor?
Quizás pudieras aprovechar una interrupción de arduino para la captura de las teclas pulsadas y actuar en consecuencia.

Algo así:

#include "IRremote.h"


const int RECV_PIN = 2;
 
IRrecv irrecv(RECV_PIN);
decode_results results;

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 3;
int sensorIR=2;  //Pin para el receptor de RF
int estado=0;  // estado del led
int loops=0;  // numero de vueltas del bucle

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT); //inicializa puerto para el led

  Serial.begin(9600); //Inicializa comunicación serie
   irrecv.enableIRIn(); // Inicializa receptor de RF
  irrecv.blink13(true);   //habilita el led del pin 13 para que parpadee al recibir una pulsación del mando
  attachInterrupt(1,lee_tecla,CHANGE); //habilita la interrupción del puerto 1 opción CHANGE: cuando cambie de estado high a low o viceversa
  
}

// the loop routine runs over and over again forever:
void loop() {
  if (++loop==100){ //Enciende/apaga leed cada 100 ejecucuines del loop
    estado = !estado;
    loops=0;
    digitalWrite(led, estado);   // turn the LED on (HIGH is the voltage level)
  }

}

void lee_tecla(){  //función que se ejecuta cada vez que el puerto 1 cambia de estado
  if (irrecv.decode(&results)) {
    if (results.decode_type == NEC) {
      Serial.print("NEC: ");
      } 
    else if (results.decode_type == SONY) {
      Serial.print("SONY: ");
      } 
    else if (results.decode_type == RC5) {
      Serial.print("RC5: ");
      } 
    else if (results.decode_type == RC6) {
      Serial.print("RC6: ");
     } 
    else if (results.decode_type == UNKNOWN) {
      Serial.print("UNKNOWN: ");
    }
    
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }

}

Saludos,

Juanjo

Buenas noches, he probado con esa secuencia que había programado, pero no acababa de funcionar bien. Me di cuenta que estaba usando mismas letras para funciones diferentes y el programa no se aclaraba, así que he hecho que en vez de pulsar A A, B, C, D, sea AAAAA y en desactivar, DDDD, y entonces funciona perfectamente.

Pero ahora, al ir a poner todos los componentes en una placa soldada (hasta ahora las pruebas han sido en protoboard), me ha dado nuevos problemas. El LED me parpadea intermitentemente como si estuviese activo el modo comprobar (este modo hace que al pulsar C, el LED parpadee cuatro veces alternándose con el sonido de la sirena) y no me deja hacer nada más, ni siquiera encenderlo desde Internet. Qué ha podido suceder? No sé si en este paso me podéis ayudar. Gracias de todas formas.

Se me olvidaba decir que lo alimento por cable USB en mi ordenador de sobremesa.

Lo siento Morma... me he perdido.
Sigo sin saber qué circuito es el que estás intentando hacer funcionar y ya no sé cual es el código actual y que no te funciona, con lo que no te puedo ayudar.

Saludos,

Juanjo