Alarma con arduino y conexión bluetooth para activar y desactivar la alarma.

Buenas! aunq es un post que sigue con otro abierto, este ya la duda es totalmente diferente y por eso hago uno nuevo....

Tengo un par de cosas que por separado me funcionan muy bien, pero cuando las intento unir me dan problemas...

1º Tengo un arduino con un altavoz, y un sensor PIR "sensor de movimiento"... cuando algo se mueve, el sensor lo detecta y el altavoz suena creo haber contado 13 veces "no tengo ni idea de dónde viene ese número de veces que suena y cómo poder modificarlo... el esquema de montaje es el siguiente:

Y el código es el siguiente:

 /* declaración de variables */
int spk=2;                                           // altavoz a GND y pin 2
int c[5]={131,262,523,1046,2093};       // frecuencias 4 octavas de Do
int cs[5]={139,277,554,1108,2217};      // Do#
int d[5]={147,294,587,1175,2349};       // Re
int ds[5]={156,311,622,1244,2489};    // Re#
int e[5]={165,330,659,1319,2637};      // Mi
int f[5]={175,349,698,1397,2794};       // Fa
int fs[5]={185,370,740,1480,2960};     // Fa#
int g[5]={196,392,784,1568,3136};     // Sol
int gs[5]={208,415,831,1661,3322};   // Sol#
int a[5]={220,440,880,1760,3520};      // La
int as[5]={233,466,932,1866,3729};    // La#
int b[5]={247,494,988,1976,3951};      // Si

void nota(int a, int b);            // declaración de la función auxiliar. Recibe dos números enteros.


int pirPin = 12;    //PIR sensor's output
 
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  digitalWrite(pirPin, LOW);
  Serial.println("** SENSOR ACTIVO **");
  }
 
void loop(){
     if(digitalRead(pirPin) == HIGH)
     {
       
       nota(as[1],100);noTone(spk);delay(100); 
       Serial.println("Detectado movimiento");
   }
}

void nota(int frec, int t)
{
    tone(spk,frec);      // suena la nota frec recibida
    delay(t);                // para despues de un tiempo t
}

Luego tengo también un módulo bluetooth HC-05, lo tengo conectado según el siguiente esquema:

Y con el siguiente código:

int data;                //Variable for storing received data
void setup() 
{
  Serial.begin(9600);         //Sets the data rate in bits per second (baud) for serial data transmission
  pinMode(13, OUTPUT);        //Sets digital pin 13 as output pin
}
void loop()
{
  if(Serial.available() > 0)  // Send data only when you receive data:
  {
    data = Serial.read();      //Read the incoming data and store it into variable data
    Serial.print(data);        //Print Value inside data in Serial monitor
    Serial.print("\n");        //New line 
    if(data == 1)            //Checks whether value of data is equal to 1 
      digitalWrite(13, HIGH);  //If value is 1 then LED turns ON
    else if(data == 2)       //Checks whether value of data is equal to 0
      digitalWrite(13, LOW);   //If value is 0 then LED turns OFF
  }                            
 
}

Y se enciende el LED y se apaga el LED con una pequeña aplicación que he hecho con APPINVENTOR, Si alguien quiere el APK que me lo diga ya que pesa más de tres megas y no me deja subirlo aquí.

Y hasta aquí todo funciona muy bien... El problema viene al intentar combinarlo, quiero que cuando la variable "data" sea 1 "es decir, que en al app del móvil se pulse el botón encender alarma", entre a funcionar el PIR que hará sonar un tono de altavoz cuando algo se mueva, y cuando la variable "data" sea 2 que deje el pin del pir en LOW.

El combinado lo tengo conectado tal que así:

Hasta donde he logrado, cuando pongo el valor en la variable "data" en 1, es decir, doy al botón encender alarma, si en ese preciso momento hay algo moviéndose por delante del PIR, sonará una sola vez el altavoz... pero si en ese momento de dar al botón de encender alarma "variable data en 1" no hay nada moviéndose delante del PIR, luego puede moverse cualquier cosa que ya no pitará ni una vez.... he estado probando a meter un while para que mientras la variable sea 1 que haga sonar el altavoz cuando se mueva algo delante del PIR, y entonces parece que funciona.... pero luego le das a parar alarma "variable data en 2" y no para de sonar la alarma.... este último caso me pasa con el siguiente código....:

int c[5]={131,262,523,1046,2093};       // frecuencias 4 octavas de Do
int cs[5]={139,277,554,1108,2217};      // Do#
int d[5]={147,294,587,1175,2349};       // Re
int ds[5]={156,311,622,1244,2489};    // Re#
int e[5]={165,330,659,1319,2637};      // Mi
int f[5]={175,349,698,1397,2794};       // Fa
int fs[5]={185,370,740,1480,2960};     // Fa#
int g[5]={196,392,784,1568,3136};     // Sol
int gs[5]={208,415,831,1661,3322};   // Sol#
int a[5]={220,440,880,1760,3520};      // La
int as[5]={233,466,932,1866,3729};    // La#
int b[5]={247,494,988,1976,3951};      // Si

void nota(int a, int b);            // declaración de la función auxiliar. Recibe dos números enteros.

int pirPin = 12;    //PIR sensor
int altavoz = 2;    // Altavoz pin
int data;           // declaración de variable INT llamada Data que recibe del bluetooth


               
void setup() 
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);        
  pinMode(pirPin, INPUT);
  pinMode(altavoz, OUTPUT);
}
void loop()
{
  if(Serial.available() > 0)  // Send data only when you receive data:
  {
    data = Serial.read();      //Read the incoming data and store it into variable data
    Serial.print(data);        //Print Value inside data in Serial monitor
    Serial.print("\n");        //New line 
    if(data == 1){            //Checks whether value of data is equal to 1 
      digitalWrite(13, HIGH);  //If value is 1 then LED turns ON
        Serial.println("Dentro del 1");
       // inicio de llamada al PIR y al altavoz
    while (data == 1){
            if(digitalRead(pirPin) == HIGH)
     {
       
       nota(as[1],100);noTone(altavoz);delay(100); 
       Serial.println("Detectado movimiento");
       
   }
}

      // fin de llamada al PIR y al altavoz
   
    }else if(data == 2)       //Checks whether value of data is equal to 0
      Serial.println("Dentro del 2");
      digitalWrite(13, LOW);   //If value is 0 then LED turns OFF
  }                            
 
}    


void nota(int frec, int t){
    tone(altavoz,frec);      // suena la nota frec recibida
    delay(t);                // para despues de un tiempo t
}

Pero no consigo lo que quiero.... que cuando encienda la alarma desde la app del móvil "recibir un 1 en consola", el PIR esté activo y cuando algo se mueva pite el altavoz durante cosa de 30 segundos.... y cuando la alarma está apagada "recibir un 2 en consola", no suceda nada al pasar por delante del pir

¿Alguna ayuda????

Gracias.

Creo que lo mejor es que te detengas y busques un libro sobre C.

Mira el código del loop()

Dice que cada vez que el PIR este en TRUE que hará?,

Ejecuta un tono por 100 mseg y si no sabes porque busca en Google Arduino tone() y verás que se coloca una frecuencia y luego una duración (los 100 mseg)

Luego hay un noTone() que lo apaga Y luego un delay()

Da la casualidad que tu PIR permanece en HIGH tanto tiempo como para que lo escuches 13 veces.

EDITO: cuando vi tu msg solo estaba el primer código no el segundo ni la foto. Ahora leo y respondo.

Lo que te falta es aprender a controlar las cosas con un simple flag

Olvidate del PIR por ahora. Concéntrate en el BT y su código '1'y '2' entonces

Creo que te lo puse en otro código similar cuando recibes 1 pones el flag en true y cuando recibes 2 lo pones en LOW

Luego tu PIR fucionar de acuerdo a que el flag este en TRUE y listo

Se comprende?

Con eso del flag me has dejado en blanco... nunca lo había leído ni escuchado... creo que a mí no me has puesto nada similar de ningún código, ya que hasta ahora el LED me encendía muy bien con la app del móvil y desde hoy intento combinarlo con una alarma en vez de un LED... pero o me funciona sólo con un pitido, o se queda sonando y no funciona el botón "Parar Alarma" es decir... cuando recibe un 2 en consola ni se visualiza en "Monitor Serie".

Gracias.

Aca la respuesta, solo falta poner el flag con ese 'a' y 'b' pero es lo mismo. Sabes como es un flag o como se define

bool flag = false; // por ejemplo

http://forum.arduino.cc/index.php?topic=559069.msg3812297#msg3812297

supongamos que usas el código parecido a ese

switch(cmd) {
     case '1': flag = true;
               break;

     case '2': flag = false;
               break;
     default:  cmd = 0;
               break;
  }
  if (flag) {
     if (digitalRead(pirPin) == HIGH) {
         nota(as[1],100);noTone(spk);delay(100); 
         Serial.println("Detectado movimiento");
     }
   }

Pues no entiendo muy bien eso de flag, porque hasta donde llegan mis conocimientos, ahí declaras una variable booleana llamada flag, y la inicializas en false. Quieres decir que un flag es una bolean declarado en false??

Gracias.

Bueno, una variable boolean puede tomar dos valores, SI/NO TRUE/FALSE

La defino como quiero y luego la uso para controlar si va a presetar o no atención al PIR. Cuando presiones 1 flag se pondra en TRUE y cuando este en TRUE prestará atencion al PIR. Cuando presiones 2 flag se pondra en FALSE y si miras, el PIR no será leído.

una variable booleana solo tiene dos estados, SI o NO, Verdadero o Falso como el estado de un switch/pulsador o lo que gustes.

Bueno, comentaros que he cambiado el código por algo similar a lo que me has mandado, lo he hecho con una variable boleana, el sketch queda así:

int c[5]={131,262,523,1046,2093};       // frecuencias 4 octavas de Do
int cs[5]={139,277,554,1108,2217};      // Do#
int d[5]={147,294,587,1175,2349};       // Re
int ds[5]={156,311,622,1244,2489};    // Re#
int e[5]={165,330,659,1319,2637};      // Mi
int f[5]={175,349,698,1397,2794};       // Fa
int fs[5]={185,370,740,1480,2960};     // Fa#
int g[5]={196,392,784,1568,3136};     // Sol
int gs[5]={208,415,831,1661,3322};   // Sol#
int a[5]={220,440,880,1760,3520};      // La
int as[5]={233,466,932,1866,3729};    // La#
int b[5]={247,494,988,1976,3951};      // Si

void nota(int a, int b);            // declaración de la función auxiliar. Recibe dos números enteros.

int pirPin = 12;    //PIR sensor
int altavoz = 2;    // Altavoz pin
int ledPin = 13;    //PIR sensor's output
int cmd;           // declaración de variable INT llamada Data que recibe del bluetooth
bool flag = false; // por ejemplo

               
void setup() 
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);        
  pinMode(pirPin, INPUT);
  pinMode(altavoz, OUTPUT);
  pinMode(ledPin, OUTPUT);
}


void loop()
{
  if(Serial.available() > 0)  // Send data only when you receive data:
  {

    cmd = Serial.read();      //Read the incoming data and store it into variable data
    Serial.print("CMD: ");
    Serial.print(cmd);        //Print Value inside data in Serial monitor
    Serial.print("\n");        //New line 
    
switch(cmd) {
     case '1': Serial.println("pulsando 1");
               flag = true;
               break;

     case '2': Serial.println("pulsando 2");
               flag = false;
               break;
               
     default:  cmd = 4;
               break;
  }
  if (flag) {
     if (digitalRead(pirPin) == HIGH) {
         nota(as[1],100);noTone(altavoz);delay(100); 
         digitalRead(ledPin) == HIGH;
         Serial.println("Detectado movimiento");
     }
   }
  }
}                            

    


void nota(int frec, int t){
    tone(altavoz,frec);      // suena la nota frec recibida
    delay(t);                // para despues de un tiempo t
}

Una vez cargado "que no sé porqué tengo que desconectar el RX y el TX del bluetooth ya que sino me da error a la hora de subir el sketch" abro la app del móvil y emparejo el bluetooth, después pulso "Encender Alarma" y en el Monitor Serie veo que aparece CMD: 1, y le doy a apagar alarma y en el monitor serie me aparece CMD: 2, lo que veo es que no entra al switch

cmd = Serial.read();      //Read the incoming data and store it into variable data
    Serial.print("CMD: ");
    Serial.print(cmd);        //Print Value inside data in Serial monitor
    Serial.print("\n");        //New line 
    
switch(cmd) {
     case '1': Serial.println("pulsando 1");
               flag = true;
               break;

Ya que si en el "Monitor Serie" aparece CMD: 1, también debería de entrar al switch con la variable CMD valiendo 1, y debería de aparecer en el "Monitor Serie" la frase "pulsando 1" y no aparece....

¿Alguna idea de porqué?

Gracias.

@cotarejo tu tienes conectado el BT a los pines 0 y 1. Eso esta bien para las tareas de funcionamiento pero mientras estar monitoreando o subiendo sketchs nada puede estar conectado a pines 0 y 1 porque es el mismo puerto el que se usa para subir los sketchs. Asi que usa SoftwareSerial en un par de pines disponibles y luego cuando termines de resolver tu código lo cambias a Serial (0,1) obviamente como lo tienes ahora y sin SoftwareSerial.

@cotarejo, es el mejor post que he visto. Ordenado, explicado, con los diagramas, código con comentarios... Oye así da gusto. ???

Si pero que te cuente como se enojó conmigo por privado por entender como se deben presentar las cosas!! Ahora entendió y lo hace y presenta perfectamente y por eso obtiene las mejores respuestas, sin malos entendidos ni nada.

Ya se lo he dicho por privado y ahora tmb públicamente.

@ArduMyth gracias por tu comentario! :wink: voy a probar eso que me dices, y @surbyte, yo no me enojé contigo, sólo te dije que si tienes que sancionarme que lo hagas, pero sin amenazar que ya soy muy mayor para esas cosas :wink:

Vale ahora con el código que me habéis comentado, parece que funciona como yo quiero... lo único que aún no doy con ello es configurar el tiempo que quiero que el tono esté sonando... querría que sonase cosa de un minuto, y no encuentro la forma de cómo hacerlo... el código hasta ahora va así:

int c[5]={131,262,523,1046,2093};       // frecuencias 4 octavas de Do
int cs[5]={139,277,554,1108,2217};      // Do#
int d[5]={147,294,587,1175,2349};       // Re
int ds[5]={156,311,622,1244,2489};    // Re#
int e[5]={165,330,659,1319,2637};      // Mi
int f[5]={175,349,698,1397,2794};       // Fa
int fs[5]={185,370,740,1480,2960};     // Fa#
int g[5]={196,392,784,1568,3136};     // Sol
int gs[5]={208,415,831,1661,3322};   // Sol#
int a[5]={220,440,880,1760,3520};      // La
int as[5]={233,466,932,1866,3729};    // La#
int b[5]={247,494,988,1976,3951};      // Si

void nota(int a, int b);            // declaración de la función auxiliar. Recibe dos números enteros.

int pirPin = 12;    //PIR sensor
int altavoz = 2;    //Altavoz pin
int ledPinrojo = 11;    //pin led rojo
int ledPinverde = 10;    //pin led verde
int cmd;           // declaración de variable INT llamada Data que recibe del bluetooth
bool flag = false; // boolean
int SSR = 9; // Pin al que está conectado el relé SSR para encender la luz

               
void setup() 
{
  Serial.begin(9600);        
  pinMode(pirPin, INPUT);
  pinMode(altavoz, OUTPUT);
  pinMode(ledPinrojo, OUTPUT);
  pinMode(ledPinverde, OUTPUT);
  pinMode(SSR, OUTPUT);
  digitalWrite(ledPinrojo , LOW);
  digitalWrite(ledPinverde , 255);
}


void loop()
{
  if(Serial.available() > 0)  //Envía datos sólo cuando se recibe un dato
  {

    cmd = Serial.read();      //Lee el dato llegado por serial.
    Serial.print("CMD: ");
    Serial.print(cmd);        //Imprime el valor llegado al puerto serie
    Serial.print("\n");        //Nueva línea
    
switch(cmd) {
     case 1: Serial.println("pulsando 1");
               flag = true;
               break;

     case 2: Serial.println("pulsando 2");
               flag = false;
               digitalWrite(ledPinrojo , LOW);
               digitalWrite(ledPinverde , HIGH);
               digitalWrite(SSR , LOW);
               Serial.println("Sin movimiento");
               break;
               
     default:  cmd = 4;
               break;
   }
  }
  
  if (flag) {
         digitalWrite(ledPinrojo , HIGH); //Enciende el led rojo
         digitalWrite(ledPinverde , LOW); //Apaga el led verde
     if (digitalRead(pirPin) == HIGH) {   //Si el pin del PIR se pone en HIGH hace lo siguiente
         nota(as[1],100);noTone(altavoz);delay(0); // Suena un pitido
         digitalWrite(SSR , HIGH); //Enciende el foco
         Serial.println("Detectado movimiento");
     }
   }
}

¿alguna idea de cómo configurarlo para que suene y la luz encienda durante un minuto?

Gracias.

Entonces una cosa es generar el disparo, eso lo haces con el flag a travez de BT y ahora quieres que ese disparo no dure mas de un X tiempo. Hagamos asi para darle flexibilidad a la idea.

bueno en el momento en que disparas con '1' cargas una variable con el valor de millis() y luego vas comparando ese valor con millis() cuando la diferencia de estos supere el INTERVALO que te interesa entonces pones en false el flag y dejará de sonar. De este modo

#define INTERVALO 60*1000   // 60 segundos x 1000 milisegundos

int c[5] = {131, 262, 523, 1046, 2093}; // frecuencias 4 octavas de Do
int cs[5] = {139, 277, 554, 1108, 2217}; // Do#
int d[5] = {147, 294, 587, 1175, 2349}; // Re
int ds[5] = {156, 311, 622, 1244, 2489}; // Re#
int e[5] = {165, 330, 659, 1319, 2637}; // Mi
int f[5] = {175, 349, 698, 1397, 2794}; // Fa
int fs[5] = {185, 370, 740, 1480, 2960}; // Fa#
int g[5] = {196, 392, 784, 1568, 3136}; // Sol
int gs[5] = {208, 415, 831, 1661, 3322}; // Sol#
int a[5] = {220, 440, 880, 1760, 3520}; // La
int as[5] = {233, 466, 932, 1866, 3729}; // La#
int b[5] = {247, 494, 988, 1976, 3951}; // Si

void nota(int a, int b);            // declaración de la función auxiliar. Recibe dos números enteros.

int pirPin = 12;    //PIR sensor
int altavoz = 2;    //Altavoz pin
int ledPinrojo = 11;    //pin led rojo
int ledPinverde = 10;    //pin led verde
int cmd;           // declaración de variable INT llamada Data que recibe del bluetooth
bool flag = false; // boolean
int SSR = 9; // Pin al que está conectado el relé SSR para encender la luz
unsigned long start;

void setup()
{
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(altavoz, OUTPUT);
  pinMode(ledPinrojo, OUTPUT);
  pinMode(ledPinverde, OUTPUT);
  pinMode(SSR, OUTPUT);
  digitalWrite(ledPinrojo , LOW);
  digitalWrite(ledPinverde , 255);
}


void loop()
{
  if (Serial.available() > 0) //Envía datos sólo cuando se recibe un dato
  {
    cmd = Serial.read();      //Lee el dato llegado por serial.
    Serial.print("CMD: ");
    Serial.print(cmd);        //Imprime el valor llegado al puerto serie
    Serial.print("\n");        //Nueva línea

    switch (cmd) {
      case 1: Serial.println("pulsando 1");
        flag = true;
        start = millis();
        break;

      case 2: Serial.println("pulsando 2");
        flag = false;
        digitalWrite(ledPinrojo , LOW);
        digitalWrite(ledPinverde , HIGH);
        digitalWrite(SSR , LOW);
        Serial.println("Sin movimiento");
        break;

      default:  cmd = 4;
        break;
    }
  }

  if (flag && (millis() - start > INTERVALO))
     flag = false;

  if (flag) {
    digitalWrite(ledPinrojo , HIGH); //Enciende el led rojo
    digitalWrite(ledPinverde , LOW); //Apaga el led verde
    if (digitalRead(pirPin) == HIGH) {   //Si el pin del PIR se pone en HIGH hace lo siguiente
      nota(as[1], 100); noTone(altavoz); delay(0); // Suena un pitido
      digitalWrite(SSR , HIGH); //Enciende el foco
      Serial.println("Detectado movimiento");
    }
  }
}

Gracias por tu respuesta surbyte! había estado pensando en usar millis o micros, pero los tengo muy poco tratados y siempre me parecen un poco liosos, tengo que ponerme con ellos más en serio para no usar delay´s.

Fuera parte de mostrar mi ignoranca, decirte que me sigue pasando exactamente lo mismo que antes de tener

#define INTERVALO 60*1000   // 60 segundos x 1000 milisegundos
unsigned long start;
if (flag && (millis() - start > INTERVALO))
     flag = false;

El altavoz suena cosa de tres o cuatro segundos y luego no vuelve a sonar hasta que no se mueve algo delante del PIR, y la bombilla se enciende cuando algo se mueve pero no se apaga nunca...Yo lo que intento es que tanto la bombilla "pin 9 relé SSR" como el altavoz "PIR pin 12 y Altavoz pin 2" estén en HIGH 1 minuto y luego paren... y si vuelve a moverse algo por delante del PIR, que vuelva a sonar el altavoz y encenderse la bombilla otro minuto...

Yo sigo por aquí intentando resolverlo yo mismo que en realidad me encanta cuando algo que no me funcionaba lo hago funcionar, pero siempre lo resuelvo por ensayo y error... no por mis sobrados conocimientos :)

Gracias por contestar @ArduMyth, he estado varias horas probando con millis() en proyectos a parte para aprender a funcionar con ello y lo veo la lógica, pero no consigo implantarlo en mi proyecto para que la alarma encienda la bombilla y suene el altavoz un minuto, por que el valor de la variable start es de 0, pero después se le asigna millis():

switch (cmd) {
      case 1: Serial.println("pulsando 1");
        flag = true;
        start = millis();
        break;

Por lo que creo que eso está bien así.. y luego en el if pone:

  if (flag && (millis() - start > INTERVALO))
     flag = false;

Si el flag es true Y millis actuales menos los millis de cuando se produjo el evento de recibir el 1 del bluetooth es mayor que el intervalo que es 60 segundos, etnonces flag pasará a ser falso...

Por lo que debería de esperar 60 segundos hasta que el boolean fuese falso de nuevo, pero no funciona...

Me estoy volviendo loco y no doy con la solución...

Alguna ayuda???

Gracias!

Explica algo cotarejo.

Como quieres que funcione esto? NOsotros te vamos respondiendo en función de lo que dices, si te expicas mal entonces luego resulta que pareciera que agregas algo.. digo pareciera porque puede que yo te haya malentendido.

Dijiste que querías que con tu celular via BT le enviabas 1 y 2 y con eso se prendiera apagara el sonido. Luego que activara desactivar el PIR cosa que te hice Luego que cuando se active sea por un tiempo... cosa que tambien hice.

Ahora no entiendo que es lo que esta mal a la luz de lo que en su momento explicaste y lo que hace el programa.

Esta es la falla?

lo único que aún no doy con ello es configurar el tiempo que quiero que el tono esté sonando.

Y esto?

Si el flag es true Y millis actuales menos los millis de cuando se produjo el evento de recibir el 1 del bluetooth es mayor que el intervalo que es 60 segundos, etnonces flag pasará a ser falso...

Por lo que debería de esperar 60 segundos hasta que el boolean fuese falso de nuevo, pero no funciona...

Me estoy volviendo loco y no doy con la solución...

No se supone que 1 activa y 2 desactiva el PIR? Entonces porque hablas de esperar un tiempo sea el que hayas programado?

Cuando actives con '1' recien el PIR estará esperando un objeto.. y si pasa el objeto deberia sonar esos 60 segundos. No lo hace asi?

@surbyte

Cuando actives con '1' recien el PIR estará esperando un objeto.. y si pasa el objeto deberia sonar esos 60 segundos. No lo hace asi?

No, no lo hace así, así debería de hacer pero no lo hace. Lo que hace es sonar unos segundos y parar de sonar, y la bombilla se queda encendida pero no se apaga nunca.... No sé si me habré explicado mal, pero siempre intento ponerlo de la manera más descriptiva posible para que no de lugar a errores "aunque a veces los de"

Gracias!

@ArduMyth escribo desde el hospital, que acabo de ser padre, ha nacido mi hija Vega!!! y cuando vuelva por casa lo probaré. Pero ante todo. Muchas gracias!!

Hombre muchas pero muchas felicidades, disfruta a tu familia que es un momento único!!!

Buenas de nuevo ante todo muchas gracias por vuestras felicitaciones, la peke ahora es mi nuevo amor y con ta solo cinco días de vida ya me ha arrebatado el corazón! ahora que la recién nacida me deja un momento me pongo con la alarma disuasoria de ladrones, y no doy con la opción para que cuando algo se mueva, se enciendan durante un minuto tanto el altavoz como el foco. Creo que el código debería ser algo así, "aunque está claro que así no, ya que sino no me haría falta preguntaros…

#define INTERVALO 6*1000   // 60 segundos x 1000 milisegundos

int c[5] = {131, 262, 523, 1046, 2093}; // frecuencias 4 octavas de Do
int cs[5] = {139, 277, 554, 1108, 2217}; // Do#
int d[5] = {147, 294, 587, 1175, 2349}; // Re
int ds[5] = {156, 311, 622, 1244, 2489}; // Re#
int e[5] = {165, 330, 659, 1319, 2637}; // Mi
int f[5] = {175, 349, 698, 1397, 2794}; // Fa
int fs[5] = {185, 370, 740, 1480, 2960}; // Fa#
int g[5] = {196, 392, 784, 1568, 3136}; // Sol
int gs[5] = {208, 415, 831, 1661, 3322}; // Sol#
int a[5] = {220, 440, 880, 1760, 3520}; // La
int as[5] = {233, 466, 932, 1866, 3729}; // La#
int b[5] = {247, 494, 988, 1976, 3951}; // Si

void nota(int a, int b);            // declaración de la función auxiliar. Recibe dos números enteros.

int pirPin = 12;    //PIR sensor
int altavoz = 2;    //Altavoz pin
int ledPinrojo = 11;    //pin led rojo
int ledPinverde = 10;    //pin led verde
int cmd;           // declaración de variable INT llamada Data que recibe del bluetooth
bool flag = false; // boolean
int SSR = 9; // Pin al que está conectado el relé SSR para encender la luz
unsigned long start = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  pinMode(altavoz, OUTPUT);
  pinMode(ledPinrojo, OUTPUT);
  pinMode(ledPinverde, OUTPUT);
  pinMode(SSR, OUTPUT);
  digitalWrite(ledPinrojo , LOW);
  digitalWrite(ledPinverde , HIGH);
  Serial.println("Encendiendo alarma");
}


void loop()
{
    
  if (Serial.available() > 0) //Envía datos sólo cuando se recibe un dato
  {
    cmd = Serial.read();      //Lee el dato llegado por serial.
    Serial.print("CMD: ");
    Serial.print(cmd);        //Imprime el valor llegado al puerto serie
    Serial.print("\n");        //Nueva línea

    switch (cmd) {
      case 1: Serial.println("pulsando 1");
        flag = true;
        start = millis();
        break;

      case 2: Serial.println("pulsando 2");
        flag = false;
        digitalWrite(ledPinrojo , LOW);
        digitalWrite(ledPinverde , HIGH);
        digitalWrite(SSR , LOW);
        Serial.println("Sin movimiento");
        break;

      default:  cmd = 4;
        break;
    }
  }

//  if (flag && (millis() - start > INTERVALO)){
//    flag = false;
//  }
     

  if (flag) {
      Serial.println("Dentro del flag en true");
    digitalWrite(ledPinrojo , HIGH); //Enciende el led rojo
    digitalWrite(ledPinverde , LOW); //Apaga el led verde
    if (digitalRead(pirPin) == HIGH) {   //Si el pin del PIR se pone en HIGH hace lo siguiente
      Serial.println("Dentro de que ha detectado movimiento");
      if (millis() - start < INTERVALO){
        Serial.println("Dentro de la función millis");
      nota(as[1], 100); noTone(altavoz); delay(0); // Suena un pitido
      digitalWrite(SSR , HIGH); //Enciende el foco
//      Serial.println("Detectado movimiento");
      }else{
      digitalWrite(SSR , LOW); //Apagar el foco
      Serial.println("Fuera de la función de millis");
      }
    }
  }
}

void nota(int frec, int t){
    tone(altavoz,frec);      // suena la nota frec recibida
    delay(t);                // para despues de un tiempo t
}

Alguna ayuda para hacer que cuando algo se mueva por delante del PIR, se encienda el foco y el altavoz durante un minuto, y luego se quede otra vez esperando a que algo se mueva para volver a encender ambas cosas???

GRACIAS!!!

prueba esto, no has comprendido algunos cambios.
Corrige desde el loop y nos dices si ahora hace lo que esperas.

void loop()
{
    
  if (Serial.available() > 0) {//Envía datos sólo cuando se recibe un dato
      cmd = Serial.read();      //Lee el dato llegado por serial.
      Serial.print("CMD: ");
      Serial.print(cmd);        //Imprime el valor llegado al puerto serie
      Serial.print("\n");        //Nueva línea
  }

  switch (cmd) {
    case 1: Serial.println("pulsando 1");
            flag = true;
            Serial.println("Dentro del flag en true");
            digitalWrite(ledPinrojo , HIGH); //Enciende el led rojo
            digitalWrite(ledPinverde , LOW); //Apaga el led verde
            start = millis();
            break;

    case 2: Serial.println("pulsando 2");
            flag = false;
            digitalWrite(ledPinrojo , LOW);
            digitalWrite(ledPinverde , HIGH);
            digitalWrite(SSR , LOW);
            Serial.println("Sin movimiento");
            break;

    default:  cmd = 4;
              break;
          
  }


  if (flag) {
      if (digitalRead(pirPin) == HIGH) {   //Si el pin del PIR se pone en HIGH hace lo siguiente
          Serial.println("Dentro de que ha detectado movimiento");
          if (millis() - start < INTERVALO){
              Serial.println("Dentro del INTERVALO millis()");
              nota(as[1], 100); noTone(altavoz); delay(0); // Suena un pitido
              digitalWrite(SSR , HIGH); //Enciende el foco
      //      Serial.println("Detectado movimiento");
          } else {
              digitalWrite(SSR , LOW); //Apagar el foco
              Serial.println("Fuera del INTERVALO millis()");
          }
      }
  }
}

void nota(int frec, int t){
    tone(altavoz,frec);      // suena la nota frec recibida
    delay(t);                // para despues de un tiempo t
}