Allarme con start e stop

Ciao a Tutti,

Volevo chiedervi un consiglio riguardo al voler costruire un allarme da garage che vorrei costruire.

Il sistema è molto semplice, almeno a parole lo è, solo che io non riesco a mettere insieme le istruzioni che vorrei fargli fare:

L'allarme avrà soltanto contatti digitali:
1 Contatto collegato alla porta di ingresso del garage;
2 Contatti anti scasso sul retro della scatola porta Arduino e sul coperchio della scatola stessa;
2 pulsanti che utilizzo come start e stop ;
1 Uscita per l'attivazione di un buzzer come avviso di pre allarme;
Un'uscita relè per attivare la sirena.

Il funzionamento del sistema:
Per fare si che l'allarme si attivi, con contatto porta e gli altri contatti anti scasso chiusi, premendo il pulsante "start" si attiva un temporizzatore di 10 secondi che mi da la possibilità di uscire dal garage e chiudere la porta/portone.
Ovviamente se il contatto non viene chiuso dopo questi 10secondi, si eccita il relè e si attiva la sirena.

Per disattivare l'allarme, una volta che apro la porta principale avrò un pre allarme dal buzzer per 10secondi, in questo timer dovrò premere il pulsante "stop", in caso non riuscissi a premere in tempo il pulsante di stop scatterà il relè.

Fino ad ora ho creato una parte di sketch che riporto sotto:

/*----------------------------------------------------------------------------------*/
int tempo = 1000;
int tempo10sec = 10000; /*tempo di pre allarme*/
int pinSirena = 8; /*Attivazione rele sirena*/
int buttonPin = 9; /*pulsante o contatto porta*/
int buzzer = 7; /*avviso preallarme*/
int startallarme = 5; /*attiva l'allarme*/
int stopallarme = 6; /*stoppa l'allarme*/

void setup() {
  pinMode(pinSirena, OUTPUT);
  pinMode(buttonPin, INPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(startallarme, INPUT);
  pinMode(stopallarme, INPUT); 
}
void loop() {
   if(digitalRead(startallarme)==HIGH){
    digitalWrite(buzzer, LOW);
    delay(tempo10sec);
    digitalWrite(buzzer, LOW);
   }

    if(digitalRead(stopallarme)==HIGH){
    digitalWrite(buzzer, LOW);
    delay(tempo10sec);
    digitalWrite(buzzer, LOW);
   }
   
  if(digitalRead(buttonPin)==HIGH) {
    delay(tempo);
    digitalWrite(buzzer, HIGH);
     delay(tempo10sec);
     digitalWrite(pinSirena, HIGH);   
  }

  
  else{
      digitalWrite(pinSirena, LOW);
      digitalWrite(buzzer, LOW);
      delay(tempo);
      digitalWrite(startallarme, LOW);
      digitalWrite(buzzer, LOW);
      delay(tempo);


  }
      }

Ho provato a leggere alcune dispense/manuali ma non credo di aver trovato il libro, manuale, youtuber ecc per riuscire a capire davvero quello che devo usare come comando.

Ho provato anche ad inserire un comando "while" ma non credo di averlo usato bene, se non sbaglio il comando while significa che "fino a quando non succede una cosa, allora non fare l'istruzione.

Vorrei chiedervi dove ho sbagliato e se mi potreste aiutare a capire i miei errori così da poter migliorare.

Un'altra domanda, potete consigliarmi un sito, libro, manuale dove vengono descritti i vari comandi per Arduino, anche un qualcosa a livello proprio "tera tera"...

Grazie per ora
Andrea

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.

Ho letto la presentazione, quindi PLC e forse potresti pensare di usare arduino e la sua MCU come un PLC, ma non lo è sia dal punto di vista elettronica che software.

All'interno della MCU c'è una sola CPU quando la impegni con delay(1000) per 1 secondo tutto il resto del codice presente nel loop() non viene eseguito, usiamo dire che delay() è bloccante.

Al suo posto le temporizzazioni vengono gestite tramite la funzione millis() che sostanzialmente restituisce un numero che corrisponde ai millesimi di secondo dal momento in cui lo accendi e la chiami, in breve un orologio in millesimi si secondo.

Qui c'è un pdf.

Qui invece un articolo pratico sull'uso di millis()

PS: problema ricorrente quello di delay() e millis().

Ciao.

Qui c'è la mia spiegazione culinaria su millis():

@paguro82: Come scrivo sempre ...

... devi studiarti come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina ... vedrai che poi ti sarà tutto più chiaro :wink:

Guglielmo

non riesco a mettere insieme le istruzioni che vorrei fargli fare

Si tratta di immaginare la funzione loop come il ciclo di scansione
di un PLC, e formalizzare la procedura in termini di tanti paragrafi
nella forma:

SE sono in questa situazione:
   E rilevo questo:
       faccio questo

premendo il pulsante "start" si attiva un temporizzatore di 10 secondi

SE non attivo:        <---- se sono in questa situazione
  SE premuto:         <---- e rilevo questo evento
    imposta attivo    <---- eseguo queste azioni
    accendi buzzer
    salva tempo di sistema attuale

Cosa sono "attivo" e "non attivo"? In un PLC si parlerebbe di merker, qui
si può usare una variabile con la stessa funzione a cui assegnare 0 o 1.

"se il contatto non viene chiuso dopo questi 10secondi, si eccita il relè e si attiva la sirena"

Qui implicitamente si sottointende la presenza di una temporizzazione di tipo Ton, e di un nuovo stato/merker, che potremo chiamare "armato".

SE attivo E non armato:
  SE timeout:
    SE tutto chiuso:
        imposta armato
        spegni buzzer
    ALTRIMENTI:
        accendi sirena

"una volta che apro la porta principale avrò un pre allarme dal buzzer per 10secondi"

SE armato:
  SE non chiuso E non preallarme:
    imposta preallarme
    accendi buzzer
    salva tempo inizio preallarme

"in caso non riuscissi a premere in tempo il pulsante di stop scatterà il relè."

SE preallarme
  SE timeout:
    accendi sirena

E sottointeso ci dovrà essere un:

SE premuto stop:
    spegni sirena
    spegni buzzer
    disattiva preallarme
    disattiva armato
    disattiva attivo

In sostanza con tre "variabili merker" (preallarme, armato, attivo),
due variabili temporali per simulare due timer Ton, e cinque if,
risolto.

E se sembra che questi if ricordino in qualche modo dei rung... è proprio così :wink:

1 Like

@UKHeliBob Grazie dell'avviso, ero convinto di aver scritto nella sezione giusta...
@gpb01 Grazie dei link!
@Claudio_FF Maremma Claudio, riesco a capire meglio lo schema ladder che hai fatto che un codice Arduino :smiley:

Mi devo mettere a studiare il tutto!

@Maurotec Si PLC, ma non a livello di programmazione, il mio compito viene molto dopo, diciamo parte di loopcheck, prove funzionali test ed avviamento...

Non mi ero proprio immaginato che Arduino leggesse il codice puramente riga per riga o meglio, pensavo che mettendo i comandi tra parentesi graffe era come creare una sorta di diversificazione tra i comandi, non so se mi sono spiegato...

@Datman Mitico, grazie :slight_smile:

Ciao a Tutti,

Ho provato a leggere gli articoli ed ho utilizzato, riadattandolo, il codice trovato nella pagina suggerita da Guglielmo, Questa Pagina.

Di seguito il codice che ho provato a creare, ma ho ancora molti dubbi non vorrei aver solamente pasticciato.

const byte buttonPin=2; /*pulsante o contatto porta*/
const byte pinSirena=10; /*uscita per allarme*/
int tempo = 1000;
int tempo10sec = 10000; /*tempo di pre allarme*/
int buzzer = 7; /*avviso preallarme*/
int startallarme = 5; /*attiva l'allarme*/
int stopallarme = 6; /*stoppa l'allarme*/


bool buttonPin = false; //defines when blinking should occur
unsigned long blinkInterval = tempo10sec; // intervallo azionamento buzzer
unsigned long currentMillis; // tracciamnto variabile tempo millis()
unsigned long previousMillis;
unsigned long startallarme;
unsigned long stopallarme;

void setup() {
 pinMode(buttonPin, INPUT);
 pinMode(pinSirena, OUTPUT);
 pinMode(buzzer, OUTPUT);
 pinMode(startallarme, INPUT);
 pinMode(stopallarme, INPUT); 
}
    
void loop() {
 if (buttonPin) {
  currentMillis = millis(); // better to store in variable, for less jitter
  if ((unsigned long)(currentMillis - previousMillis) >= blinkInterval) { // 10 secondi sono passati?
   digitalWrite(pinSirena, !digitalRead(pinSirena)); // aziono la sirena o no
   previousMillis = currentMillis; // sets the time we wait "from"
  }
 } 
 if ((unsigned long)(stopallarme) = !blinkInterval) { //non faccio suonare la sirena e fermo il timer
  digitalWrite(pinSirena, !digitalRead(pinSirena));
 else {
  digitalWrite(pinSirena, LOW); // force LED off when not blinking
 }
if ((unsigned long)(startallarme) = !blinkInterval) { //non faccio suonare la sirena e parte il timer
  digitalWrite(pinSirena, !digitalRead(pinSirena));
 else {
  digitalWrite(pinSirena, HIGH); // forza la sirena ad accendersi
 
 int reading = digitalRead(buttonPin);
 delay(50); // de-bouncing

 if (reading==LOW) // buttons with pull-up are pressed when LOW
  blinking=true; // start blinking
 else
  blinking=false; // stop blinking
}

Ho provato a fare il compile solo che ricevo sempre lo stesso messaggio "conflicting declaration 'bool buttonPin' "

Potreste indicarmi dove ho sbagliato, supportarmi?

Grazie per ora

Due nomi di variabile identici, allora il compilatore non sa che fare. L'ultima potrebbe essere invece:

bool buttonState = false; //defines when blinking should occur

Hai ragione :man_facepalming:t2:

È importantissimo quando si posta del codice incolonnarlo correttamente, c'è l'apposita funzione formattazione automatica dell'IDE che si attiva anche con CTRL+T. È l'unico modo per vedere a colpo d'occhio quali istruzioni sono subordinate/contenute a/in cosa, ed evita un sacco di errori.

Per il resto in generale (sempre per evitare errori e confusione) è meglio usare nomi di variabili coerenti con la loro funzione e con i commenti, ad esempio la riga:

bool buttonPin = false; //defines when blinking should occur

definisce una variabile che secondo il commento dovrebbe indicare se il lampeggio deve essere attivo oppure no, quindi il nome 'lampeggio' al posto di 'buttonPin' sarebbe più indicato. Ma vuoi realmente relizzare un lampeggio? Perché se non è così allora anche il nome 'lampeggio' crea solo confusione.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.