Alarma con sensor PIR

Buenas. estoy tratando de hacer una alarma con un sensor PIR, mas adelante pienso agregar un detector de humo, de sonido, detector de apertura de puertas y ventanas etc; pero primero necesito que funcione este, ya que debo presentarlo para el colegio.
El codigo " empieza a correr" cuando se detecta un estado alto, y se activa la alarma cuando el sensor de movimiento manda un estado alto, esto por ahora es un led( pero despues sera reemplazado por un optoacoplador con un rele que ensienda las luces de la red electrica).
Estoy usando un Arduino UNO, y el sketch me da un error de compilacion y nose como resolverlo, la entrada del pulsador esta hecha con un pull up, desde ya muchisimas gracias!!!

[code]
int threeState = LOW;
int valpir = 0;
int oneState = 0;

void setup() {
  pinMode(1, INPUT);//  el boton de inicio
  pinMode(2, OUTPUT); //led
  pinMode(3, INPUT);// PIR
}

void loop() {
  oneState = digitalRead(1);
  if (oneState == HIGH);{ // al detectar un pulso en el pin 1 empieza a correr el codigo
    delay(1);
    valpir = digitalRead(3);
    if (valpir == HIGH);{ // al resivir un un pulso de el PIR se activa el codigo
      digitalWrite(2, HIGH);
      if (threeState == LOW){
        threeState = HIGH; // en el pin D2 hay un led que se activa 
        delay(1);
        digitalWrite(2, HIGH);
        delay(500); // se espera medio segundo
        digitalWrite(2, LOW); // se apaga
        delay(500); // se vuelve a esperar medio segundo 
        return 20;} // y se vuelve a la linea 20 y asi infinitamente hasta resetearse
      } 
      else {
        delay(1);
        return 14; // si no hay un pulso de PIR se vuelve a la linea 14
    }
  }
  else {
    delay(1);
    return 11;} // si no se recibe la señal en el pin 1 no corre el codigo y vuelve a la linea 11
}

[/code]

Y este es el error que me da.

Arduino:1.8.5 (Windows 7), Tarjeta:"Arduino/Genuino Uno"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\Dario\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\Dario\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Dario\Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10805 -build-path C:\Users\Dario\AppData\Local\Temp\arduino_build_673122 -warnings=all -build-cache C:\Users\Dario\AppData\Local\Temp\arduino_cache_70391 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.4-arduino2 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.1.1 -prefs=runtime.tools.avrdude.path=C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino9 -verbose C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\Dario\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\Dario\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Dario\Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10805 -build-path C:\Users\Dario\AppData\Local\Temp\arduino_build_673122 -warnings=all -build-cache C:\Users\Dario\AppData\Local\Temp\arduino_cache_70391 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.4-arduino2 -prefs=runtime.tools.arduinoOTA.path=C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.1.1 -prefs=runtime.tools.avrdude.path=C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino9 -verbose C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino
Using board 'uno' from platform in folder: C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21
Using core 'arduino' from platform in folder: C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21
Detecting libraries used...
"C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.4-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino" "-IC:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard" "C:\Users\Dario\AppData\Local\Temp\arduino_build_673122\sketch\alarma_movimiento.ino.cpp" -o "nul"
Generating function prototypes...
"C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.4-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics  -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino" "-IC:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard" "C:\Users\Dario\AppData\Local\Temp\arduino_build_673122\sketch\alarma_movimiento.ino.cpp" -o "C:\Users\Dario\AppData\Local\Temp\arduino_build_673122\preproc\ctags_target_for_gcc_minus_e.cpp"
"C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\Users\Dario\AppData\Local\Temp\arduino_build_673122\preproc\ctags_target_for_gcc_minus_e.cpp"
Compilando programa...
"C:\Users\Dario\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.4-arduino2/bin/avr-g++" -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR   "-IC:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino" "-IC:\Users\Dario\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\variants\standard" "C:\Users\Dario\AppData\Local\Temp\arduino_build_673122\sketch\alarma_movimiento.ino.cpp" -o "C:\Users\Dario\AppData\Local\Temp\arduino_build_673122\sketch\alarma_movimiento.ino.cpp.o"
C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino: In function 'void loop()':

C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino:13:24: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]

   if (oneState == HIGH);{ // al detectar un pulso en el pin 1 empieza a correr el codigo

                        ^

C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino:16:24: warning: suggest braces around empty body in an 'if' statement [-Wempty-body]

     if (valpir == HIGH);{ // al resivir un un pulso de el PIR se activa el codigo

                        ^

C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino:25:16: warning: return-statement with a value, in function returning 'void' [-fpermissive]

         return 20;} // y se vuelve a la linea 20 y asi infinitamente hasta resetearse

                ^

alarma_movimiento:27: error: 'else' without a previous 'if'

       else {

       ^

C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino:29:16: warning: return-statement with a value, in function returning 'void' [-fpermissive]

         return 14; // si no hay un pulso de PIR se vuelve a la linea 14

                ^

alarma_movimiento:32: error: 'else' without a previous 'if'

   else {

   ^

C:\Users\Dario\Documents\Arduino\alarma_movimiento\alarma_movimiento.ino:34:12: warning: return-statement with a value, in function returning 'void' [-fpermissive]

     return 11;} // si no se recibe la señal en el pin 1 no corre el codigo y vuelve a la linea 11

            ^

exit status 1
'else' without a previous 'if'

alarma_movimiento.ino (1.06 KB)

El problema que te está arrojando es porque te estás equivocado en las estructuras de las condiciones, la cual es:

if (condición)
{
    Acción 1;
    Acción 2;
}

y tú estás poniendo

if (condición);
{
    Acción 1;
    Acción 2;
}

nótese el ; después de la condición.
También la referencia return sirve para retornar a la función que la llamó o devolver un valor en tu caso no a una linea en especifico del código por lo cual no me parece necesario utilizarla a menos que utilices funciones.
Para que la alarma funcione debe estar presionado el botón caso contrario con pulsarlo y soltarlo no funcionara, si piensas agregar más sensores no te recomiendo el uso de delay ya que el código se detendrá en y no podrá atender las demás cosas te recomiendo utilices millis
También en la parte que enciendes el led

if (threeState == LOW)
            {
                threeState = HIGH; // en el pin D2 hay un led que se activa
                delay(1);
                digitalWrite(3, HIGH);
                delay(500);           // se espera medio segundo
                digitalWrite(3, LOW); // se apaga
                delay(500);           // se vuelve a esperar medio segundo
            }

Cambias el valor de la variable threeState con lo cual solo se ejecutara una sola vez a no ser que se reinicie el arduino no si eso es lo que quieres que haga.
Adjunto el código que compila correctamente

int threeState = LOW;
int valpir = 0;
int oneState = 0;

void setup()
{
    pinMode(2, INPUT);  //  el boton de inicio
    pinMode(3, OUTPUT); //led
    pinMode(4, INPUT);  // PIR
}

void loop()
{
    oneState = digitalRead(2);
    if (oneState == HIGH)
    { // al detectar un pulso en el pin 2 empieza a correr el código
        delay(1);
        valpir = digitalRead(4);
        if (valpir == HIGH)
        { // al resivir un un pulso de el PIR se activa el codigo
            digitalWrite(2, HIGH);
            if (threeState == LOW)
            {
                threeState = HIGH; // en el pin D3 hay un led que se activa
                delay(1);
                digitalWrite(3, HIGH);
                delay(500);           // se espera medio segundo
                digitalWrite(3, LOW); // se apaga
                delay(500);           // se vuelve a esperar medio segundo
            } // y se vuelve a la linea 20 y asi infinitamente hasta resetearse
        }
        else
        {
            delay(1);
        
        }
    }
    else
    {
        delay(1);
    } }

has confundido return con goto ,por cierto nada aconsejable pues favorece un codigo caotico,ilegible y poco facil de mantener,ademas creo que funciona con etiquetas:

menu:
//codigo

goto menu;

Muchísimas gracias a ambos por la ayuda. Como debería cambiar el código para que se pueda prender con un botón sin tener que mantenerlo pulsado? Como se puede crear un bucle infinito? por ejemplo para que prenda y apague un led infinitamente hasta que se reinicie el arduino o se deje de alimentarlo. Muchas gracias!!!

Pues en google hay muchos pero muchos tutoriales como hacerlo, Tutorial Arduino: Entradas (2): Botones revisa esta bien detallado como hacerlo y te adjunto un código de los que está, intenta agregarlos por tu cuenta y si te presente algún fallo pregunta aquí adjuntando el código para explicar en qué estas fallando y lo puedas solucionar.

/**************************/
/* Encender LED con Botón */
/* Interruptor sin rebote */
/**************************/

/*** Fernando Martinez Mendoza ***/

//** Definiciones **//

int pulsador=0;              //almacena el estado del botón
int estado=0;                //0=led apagado, 1=led encendido
int pulsadorAnt=0;           //almacena el estado anterior del boton

//** Programa **//

void setup() {
  pinMode(2, OUTPUT);        //declaramos el pin 2 como salida
  pinMode(4, INPUT);         //declaramos el pin 4 como entrada
}

void loop() {
  pulsador = digitalRead(4); //lee si el botón está pulsado
  
  if((pulsador==HIGH)&&(pulsadorAnt==LOW)){  //si el boton es pulsado y antes no lo estaba
    estado=1-estado;
    delay(40);               //pausa de 40 ms
  }
  pulsadorAnt=pulsador;      //actualiza el nuevo estado del boton        
  
  if(estado==1) {            //si el estado es 1
    digitalWrite(2, HIGH);   //se enciende el led
  }
  else{                      //si el estado es 0
    digitalWrite(2, LOW);    //se apaga el led
  }
}

matyas1272:
Como se puede crear un bucle infinito? por ejemplo para que prenda y apague un led infinitamente hasta que se reinicie el arduino o se deje de alimentarlo.

Pues el void loop es un bucle infinito que se repetirá hasta que se le quite la alimentación al arduino ahora si la condición com la cual quieres que se encienda y se apague el led nunca cambia se repetirá hasta el fin de los tiempos o se le quite la alimentación del arduino, no tendría sentido crear otro bucle para encender y apagar otro led, espero haberte ayudado.

Muchas gracias por la ayuda, si me ayudaste, el problema es que el void loop tiene varios códigos, y quiero que se repita el parpadeo del LED que es una condición de un if.

[code]
int boton=0;                 //almacena el estado del botón
int estado=0;               //0=led apagado, 1=led encendido
int botonAnt=0;            //almacena el estado anterior del boton
int treceState = LOW;     // LED etado
int valpir = 0;          // pin 3

void setup() {
  pinMode(2, INPUT);        //pin 2 = boton (IN)
  pinMode(3, INPUT);       // pin 3 = PIR
  pinMode(13, OUTPUT);    // 13 = LED
}

void loop() {
  boton = digitalRead(2); //lee si el botón está pulsado
  
  if((boton==HIGH)&&(botonAnt==LOW)){  //si el boton es pulsado y antes no lo estaba
    estado=1-estado;
    delay(40);               //pausa de 40 ms
  }
  botonAnt=boton;      //actualiza el nuevo estado del boton        
  
  if(estado==1) {
     delay(60000);
    valpir = digitalRead(4);
    if (valpir == HIGH)
    { // al resivir un un pulso de el PIR se activa el codigo
      digitalWrite(2, HIGH);
      if (treceState == LOW)
      {
        treceState = HIGH; // en el pin D3 hay un led que se activa
        delay(1);
        digitalWrite(13, HIGH);
        delay(500);           // se espera medio segundo
        digitalWrite(13, LOW); // se apaga
        delay(500);// se vuelve a esperar medio segundo
      } digitalWrite(13, HIGH);
        delay(500);           // se espera medio segundo
        digitalWrite(13, LOW); // se apaga
        delay(500);// y se vuelve a la linea 25 y asi infinitamente hasta resetearse
    }
    else
    {
      delay(1);

    }
  }
  else
  {
    delay(1);
  }
}

[/code]

Hi, Te voy a dar un consejo cuando estes desarollando un projecto trata de hacer pequenas routinas y no una que incluyas todo tu programacion como en una larga longaniza. Esto te traira problemas cuando tengas hacer cambios en la programaccion pues todo esta junto. Haciendo pequenas routinas si tienes que cambiar algo solo cambias esa routtina. Entonces en el loop solamente puedes ir llamando las routine de acuerdo el orden que tu quieres. No pongas toda la programacion en el loop. Espero que hallas entedido lo que te quiero aconsejar. Por favor a los programdores profeccionales este es mi forma de programar pues lo aprendi por mi propio esfuerzo. Lo mio es lo electronico y por necesidad tuve que aprender a programar. Todavia me falta mucho por aprender.

ejemplo:

void Loop{
alar_pir();
alrm_humo();
detec_puerta();
}

//*******************
void alar_pir(){
intrucciones
}

//*******************
void alrm_humo()}
intrucciones
}
//*******************
void detec_puerta(){
intrucciones
}

etc 
etc

Moderador: Código editado usando etiquetas

Moderador: No hace falta repetir lo que se lee arriba.

Gacias por la yuda, los consejos y el aporte.
El delay(60000) es para poder salir de la habitacion antes de que se active el sensor de movimiento, y los delay(1) habia leido que se usan para evitar posibles fallos, no se si esto es cierto, como bien fue mencionado soy nuevo en Arduino, y todavia me cuesta entender algunas cosas, como millis, o boolean. Pero igual trato de hacer lo posible por armar el codigo. tambien como dijiste parte del codigo lo saque de internet, de otros proyectos o de los ejemplos de Arduino. Graias por la opinion y la ayuda

PD: vuelvo a subir el codigo con los cambios que propusiste, por lo menos los que entendí.

alarma_movimiento_1.5.ino (1.48 KB)

Moderador: 2da Advertencia!.. No hace falta repetir lo que se lee arriba.

Gracias po el consejo, lo voy a tener en cuenta.

Hola ArduMyth, gracias por los consejos,la verdad no se me habia ocurrido usar un sensor que detecte cuando salga de la habitacion, por eso el delay de 1 minuto, como la idea final era aplicarlo a una casa, me base en una alarma convencional, en la que me fije daba un tiempo de 30 seg para activar la alarma una ves introducido el codigo, yo crei que era poco y puse 1 min, pero voy a tener encuenta lo del sesor, pensandolo un poco podria ser un led infrarojo con un sensor infrarojo que al dejar de recibir luz envie un pulso, o uno de esos llaveros que se detectan con un sensor... nose ya vere pero lo voy a tener en cuenta para la futura modificacion, una ves que logre hacer andar el codigo con millis.

Voy a sacar los delay(1) y tratar de meter los millis, con respecto a lo de el sensor lo tendre en cuenta, sefuramente lo agregare con el sensor de humo. Mchisimas gracias por los consejos y la ayuda.

Para apoyarte con el uso de millis yo utilizo un blink para encender un claxon

/*
 Name:		Pruebas.ino
 Created:	09/03/2018 21:05:50
 Author:	bryam
*/

const int horn = 10;
bool flagHorn = 0, estadoHorn = LOW;
unsigned long tiempoInicialHorn;// Tiempo Horn
const unsigned long tiempoFuncionalHorn = 300;// Tiempo Horn
char comando;
void setup()
{
	Serial.begin(9600);
	pinMode(horn, OUTPUT);
}
void lecturaDatos()
{
	if (Serial.available() > 0)
	{
		comando = Serial.read();
	}
}
void blinkHorn()
{
	if ((flagHorn == 1) && (millis() - tiempoInicialHorn >= tiempoFuncionalHorn))
	{
		tiempoInicialHorn = millis();
		if (estadoHorn == LOW)
		{
			estadoHorn = HIGH;
		}
		else
		{
			estadoHorn = LOW;
		}
	}
	digitalWrite(horn, estadoHorn);
}
void loop()
{
	lecturaDatos();
	blinkHorn();
	switch (comando)
	{
	case 'a':
		flagHorn = 1;
		break;
	case 'b':
		flagHorn = 0;
		estadoHorn = LOW;
		break;
	}
	comando = ' ';
}

Para que que haga el blink lo único que debes hacer es cambiar el estado de la variable flagHorn = 1 para qe funcione y para desactivarlo debes tienes que cambiar estas dos : flagHorn = 0; estadoHorn = LOW;

Gracias Swift, tratare de aplicarlo, gracias por la contribución!!!!

Gracias por el aporte ArduMyth, el return ya lo saque y lo dije en anteriores comentarios, los delay(1) los saque por que coprobe que no fallaba con ellos asi que no hay problema. Tambien como ya aclare, en los comentarios y el codigo publicado, deje de usar el pin 1, y el 0 nunca lo use. Y si, empece con el arduino antes de usar otros lenguajes, ya que me parecio mas sencillo que rasphberry o pic. Igual se agradece el comentario.