campanelli ingressi

ciao a tutti voglio realizzare 2 campanelli con 2 buzzer cosi devono funzionare:

PULSANTE A fa suonare il BUZZER A e mai BUZZER B

PULSANTE B fa suonare il BUZZER B e mai BUZZER a

sequenza voluta

premo PULSANTE
suona BUZZER
rilascio il pulsante prima di 3 secondi
BUZZER smette di suonare
non rilascio il PULSANTE
BUZZER smette dopo 3 secondi

ho provato diversi sketch ma tutti non facevano al caso
il buzzer suona al comando e smette dopo il tempo e dopo aver rilasciato il pulsante
in alcuni casi se 1 pulsante è premuto l'altro buzzer non suona. cercando su internet mi pare di aver capito che il delay blocca il ciclo quindi conviene usare il millis.
cercato sketch con millis ma il risultato non e cambiato.pero nelle mie prove se un pulsante rimaneva premuto l'altro funzionava

Chi mi aiuta?

Io farei in questo modo!
1)Uso un if else per ogni pulsante, in questo modo posso ottenere, se il pulsante è premuto suono, else altrimenti arresto il suono.

  1. All'interno dell'if con la funzione millis() comincio il conteggio di 3 secondi, se sono passati interrompo il suono

Esempio per un pulsante, da duplicare per gestire due pulsanti, quindi due variabili per il tempo:

unsigned long tempo1=0; //variabile globale dichiarata ad di fuori di ogni funzione
byte suono1=1;
void loop(){
    if(digitalRead(pulsante)==HIGH){
          if(suono1==1){
              
                  tone(pin, frequency);         
          }
          if(millis()-tempo1>=3000){// Passati 3 secondi
             notone(pin); //fermo il suono
             suono1=0;// rendo falsa la condizione cosi il programma non esegue piu tone
          }
    }else{
          suono1=1; // Abilito il suono se si preme il pulsante
          tempo1=millis(); // Prendo il tempo attuale
          notone(pin); // Se non premo il pulsante arresto il suono
   }// end if

}// end loop()

Ciao, torn24
Per cortesia, togli le righe vuote, così il codice può essere letto senza scorrere inutilmente tante righe?
Grazie :slight_smile:

ho tolto un po di righe vuote, un po sono rimaste ma penso renda più leggibile :slight_smile:

torn24:
ho tolto un po di righe vuote, un po sono rimaste ma penso renda più leggibile

Essendoci due buzzer da gestire con 'tone' (di cui se non sbaglio solo uno alla volta può essere attivo), mi sembra più "sicura" una logica in cui 'notone' venga invocato solo se serve, e non ad ogni ciclo di loop quando il pulsante non è attivo:

unsigned long tempo1 = 0;
byte suono1 = 1;

void loop()
{
    if (digitalRead(pulsante) == HIGH)   // se pulsante premuto
    {
        if (suono1 == 1) // accende se spento
        {              
            tone(pin, frequency);
            tempo1 = millis();
            suono1 = 2;
        }
        else if (suono1==2  &&  (millis()-tempo1 >= 3000)) // spegne se timeout
        {
            notone(pin);
            suono1 = 3;
        }
    }
    else                                   // se pulsante non premuto
    {
        if (suono1 == 2) { notone(pin); }  // spegne se acceso
        suono1 = 1;
    }
}

La variabile suono1 indica le seguenti situazioni:
1 = non premuto, buzzer spento
2 = premuto, buzzer acceso
3 = premuto, buzzer spento per timeout

Claudio_FF è una soluzione adatta, a me non veniva spontaneo risolvere con una macchina a stati :slight_smile:

torn24:
a me non veniva spontaneo risolvere con una macchina a stati

Eppure l'hai scritta, ne ho solo aggiunto uno :slight_smile: Forse intendevi dire che non la avevi pensata esplicitamente a stati, ma in realtà quando c'è anche una sola variabile flag come 'tone1' il codice è già una macchina a stati (cioè l'esecuzione non dipende solo ed esclusivamente dagli ingressi attuali ma anche da quello che è successo prima).