Centralina antifurto: led che rimane acceso

Buonasera a tutti,

Vorrei implementare su una centralina antifurto una funzione che, una volta scattato l'allarme (piedino 13 a livello alto), faccia rimanere acceso un led anche quando l'evento allarme è cessato, per poi spegnerlo premendo un pulsante (reset). Questo per poter verificare se l'allarme è entrato in funzione in mia assenza o nel caso non abbia sentito il cicalino.

Ho pensato di inserire un flip flop set-reset esterno ad Arduino, ma vorrei sapere se per tale scopo sia possibile utilizzare Arduino stesso. Ho provato a scrivere il codice utilizzando la funzion "while", ma non riesco ad andare avanti.

Questo è il codice attuale, grazie a tutti:

/*
Centralina antifurto 5 ingressi
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int sensore_1 = 7;
int sensore_2 = 8;
int sensore_3 = 9;
int sensore_4 = A0;
int sensore_5 = A1;
int ill_disp = 10;
int uscita = 13;

void setup() {
  pinMode(sensore_1, INPUT);
  pinMode(sensore_2, INPUT);
  pinMode(sensore_3, INPUT);
  pinMode(sensore_4, INPUT);
  pinMode(sensore_5, INPUT);
  pinMode(ill_disp, OUTPUT);
  pinMode(uscita, OUTPUT);
 
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
}



void loop() {
  int sensore_1 = digitalRead(9);
  int sensore_2 = digitalRead(8);
  int sensore_3 = digitalRead(7);
  int sensore_4 = digitalRead(A0);
  int sensore_5 = digitalRead(A1);
 
  if (sensore_1 == HIGH  && sensore_2 == HIGH && sensore_3 == HIGH && sensore_4 == HIGH && sensore_5 == HIGH) {
    digitalWrite(uscita, LOW);
    digitalWrite(ill_disp, LOW);
    noTone(6);
    lcd.setCursor(0, 0);
    lcd.clear();
    lcd.print("Tutto bene");
    lcd.setCursor(0, 1);
    lcd.print("Sensori ok!");
    lcd.setCursor(0, 3);
    lcd.print("Zone:");
    lcd.setCursor(6, 3);
    lcd.print(sensore_1);
    lcd.setCursor(9, 3);
    lcd.print(sensore_2);
    lcd.setCursor(12, 3);
    lcd.print(sensore_3);
    lcd.setCursor(15, 3);
    lcd.print(sensore_4);
    lcd.setCursor(18, 3);
    lcd.print(sensore_5);
    delay(1000);
  }
else
{
digitalWrite(uscita, HIGH);
digitalWrite(ill_disp, HIGH);
tone(6,2000,2000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Allarme sensore!");

    lcd.setCursor(3, 2);
    lcd.print(sensore_1);
    lcd.setCursor(6, 2);
    lcd.print(sensore_2);
    lcd.setCursor(9, 2);
    lcd.print(sensore_3);
    lcd.setCursor(12, 2);
    lcd.print(sensore_4);
    lcd.setCursor(15, 2);
    lcd.print(sensore_5);
   
    //mostra le zone attivate

    lcd.setCursor(0, 3);   
    if(sensore_1==0) {
    lcd.print( "Garage " );
    }
    else
    lcd.print("");

    if(sensore_2==0) {
    lcd.print( "Cantina " );
    }
    else
    lcd.print("");
   
    if(sensore_3==0) {
    lcd.print( "Terrazzo " );
    }
    else
    lcd.print("");
   
    if(sensore_4==0) {
    lcd.print( "Mansarda " );
    }
    else
    lcd.print("");
   
    if(sensore_5==0) {
    lcd.print( "Casa!! " );
    }
    else
    lcd.print("");

    delay(3000);

}
}

Forse non ho ben capito, ma basta che colleghi il led al pin che preferisci e ci lo setti ad HIGH quando necessario, se non lo spegni mai, rimarrà sempre acceso.

O intendi anche in caso di interruzione dell'alimentazione? Nel tal caso insieme all'accensione del led scrivi un valore da qualche parte nella EEPROM, all'avvio rileggilo ed eventualmente accendi il led.

SukkoPera:
Forse non ho ben capito, ma basta che colleghi il led al pin che preferisci e ci lo setti ad HIGH quando necessario, se non lo spegni mai, rimarrà sempre acceso.

O intendi anche in caso di interruzione dell'alimentazione? Nel tal caso insieme all'accensione del led scrivi un valore da qualche parte nella EEPROM, all'avvio rileggilo ed eventualmente accendi il led.

Non intendo in caso di interruzione dell'alimentazione, ma durante il normale funzionamento.
Quando entra in azione l'allarme, il pin 13 va a livello logico alto per poi ritornare al valore LOW dopo un periodo di tempo. Avrei bisogno di un altro led che, una volta scattato l'allarme, continui a rimanere acceso anche quando l'allarme sarà cessato e fin quando non si prema un pulsante di reset

Continuo a non capire che problema ci sia a farlo... Hai tutti i pin occupati?

no... non so come scrivere il codice. Per pulsante di reset non intendo quello di arduino, ma un pulsante esterno che mi faccia spegnere il secondo led che si è acceso per evidenziare che l'allarme (pur se ora è LOW) è entrato in funzione durante la giornata

Ah ok, allora facciamo un passo alla volta: sapresti almeno scrivere il codice per accenderlo? Basta copiare quello che usi per il led sul pin 13.

ma si... la centralina funziona perfettamente, avrei solo bisogno di implementare quest'altra funzione.
Riposto il codice:

/*
Centralina antifurto 5 ingressi
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int sensore_1 = 7;
int sensore_2 = 8;
int sensore_3 = 9;
int sensore_4 = A0;
int sensore_5 = A1;
int ill_disp = 10;
int uscita = 13;

void setup() {
  pinMode(sensore_1, INPUT);
  pinMode(sensore_2, INPUT);
  pinMode(sensore_3, INPUT);
  pinMode(sensore_4, INPUT);
  pinMode(sensore_5, INPUT);
  pinMode(ill_disp, OUTPUT);
  pinMode(uscita, OUTPUT);
 
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
}



void loop() {
  int sensore_1 = digitalRead(9);
  int sensore_2 = digitalRead(8);
  int sensore_3 = digitalRead(7);
  int sensore_4 = digitalRead(A0);
  int sensore_5 = digitalRead(A1);
 
  if (sensore_1 == HIGH  && sensore_2 == HIGH && sensore_3 == HIGH && sensore_4 == HIGH && sensore_5 == HIGH) {
    digitalWrite(uscita, LOW);
    digitalWrite(ill_disp, LOW);
    noTone(6);
    lcd.setCursor(0, 0);
    lcd.clear();
    lcd.print("Tutto bene");
    lcd.setCursor(0, 1);
    lcd.print("Sensori ok!");
    lcd.setCursor(0, 3);
    lcd.print("Zone:");
    lcd.setCursor(6, 3);
    lcd.print(sensore_1);
    lcd.setCursor(9, 3);
    lcd.print(sensore_2);
    lcd.setCursor(12, 3);
    lcd.print(sensore_3);
    lcd.setCursor(15, 3);
    lcd.print(sensore_4);
    lcd.setCursor(18, 3);
    lcd.print(sensore_5);
    delay(1000);
  }
else
{
digitalWrite(uscita, HIGH);
digitalWrite(ill_disp, HIGH);
tone(6,2000,2000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print("Allarme sensore!");

    lcd.setCursor(3, 2);
    lcd.print(sensore_1);
    lcd.setCursor(6, 2);
    lcd.print(sensore_2);
    lcd.setCursor(9, 2);
    lcd.print(sensore_3);
    lcd.setCursor(12, 2);
    lcd.print(sensore_4);
    lcd.setCursor(15, 2);
    lcd.print(sensore_5);
   
    //mostra le zone attivate

    lcd.setCursor(0, 3);   
    if(sensore_1==0) {
    lcd.print( "Garage " );
    }
    else
    lcd.print("");

    if(sensore_2==0) {
    lcd.print( "Cantina " );
    }
    else
    lcd.print("");
   
    if(sensore_3==0) {
    lcd.print( "Terrazzo " );
    }
    else
    lcd.print("");
   
    if(sensore_4==0) {
    lcd.print( "Mansarda " );
    }
    else
    lcd.print("");
   
    if(sensore_5==0) {
    lcd.print( "Casa!! " );
    }
    else
    lcd.print("");

    delay(3000);

}
}

Il codice lo vedevamo già nel primo post, modificalo aggiungendo l'accensione del 2° led.

Eccolo, ho pensato di chiamare il led "led_di_avviso" e di aggiungere l'istanza "rimani_on()" per tenerlo acceso una volta trascorso il tempo di attivazione dell'allarme, che verrà interrotta dal comando "While" non appena viene premuto il pulsante "puls_reset"

Grazie ancora... soprattutto per la pazienza...

/*
Centralina antifurto 5 ingressi
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int sensore_1 = 7;
int sensore_2 = 8;
int sensore_3 = 9;
int sensore_4 = A0;
int sensore_5 = A1;
int ill_disp = 10;
int uscita = 13;
int puls_reset = A2;
int led_di_avviso = A3;

void rimani_on() {
  if (uscita = HIGH) {
    digitalWrite(led_di_avviso, HIGH);
  }
}


void setup() {
  pinMode(sensore_1, INPUT);
  pinMode(sensore_2, INPUT);
  pinMode(sensore_3, INPUT);
  pinMode(sensore_4, INPUT);
  pinMode(sensore_5, INPUT);
  pinMode(ill_disp, OUTPUT);
  pinMode(uscita, OUTPUT);
  pinMode(puls_reset, INPUT);
  pinMode(led_di_avviso, OUTPUT);
  
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
}



void loop() {
  
  while (digitalRead(puls_reset) == HIGH) {
    rimani_on();
  }
  
  int sensore_1 = digitalRead(9);
  int sensore_2 = digitalRead(8);
  int sensore_3 = digitalRead(7);
  int sensore_4 = digitalRead(A0);
  int sensore_5 = digitalRead(A1);
  
  if (sensore_1 == HIGH  && sensore_2 == HIGH && sensore_3 == HIGH && sensore_4 == HIGH && sensore_5 == HIGH) {
    digitalWrite(uscita, LOW);
    digitalWrite(ill_disp, LOW);
    noTone(6);
    lcd.setCursor(0, 0);
    lcd.clear();
    lcd.print("Tutto bene");
    lcd.setCursor(0, 1);
    lcd.print("Sensori ok!");
    lcd.setCursor(0, 3);
    lcd.print("Zone:");
    lcd.setCursor(6, 3);
    lcd.print(sensore_1);
    lcd.setCursor(9, 3);
    lcd.print(sensore_2);
    lcd.setCursor(12, 3);
    lcd.print(sensore_3);
    lcd.setCursor(15, 3);
    lcd.print(sensore_4);
    lcd.setCursor(18, 3);
    lcd.print(sensore_5);
    delay(1000);
  }
else
{
digitalWrite(uscita, HIGH);
digitalWrite(ill_disp, HIGH);

lcd.clear();
lcd.setCursor(2,0);
lcd.print("Allarme sensore!");

    lcd.setCursor(3, 2);
    lcd.print(sensore_1);
    lcd.setCursor(6, 2);
    lcd.print(sensore_2);
    lcd.setCursor(9, 2);
    lcd.print(sensore_3);
    lcd.setCursor(12, 2);
    lcd.print(sensore_4);
    lcd.setCursor(15, 2);
    lcd.print(sensore_5);
    
    //mostra le zone attivate
    lcd.setCursor(0, 3);    
    if(sensore_1==0) {
    lcd.print( "Garage " );
    }
    else
    lcd.print("");

    if(sensore_2==0) {
    lcd.print( "Cantina " );
    }
    else
    lcd.print("");
    
    if(sensore_3==0) {
    lcd.print( "Terrazzo " );
    }
    else
    lcd.print("");
    
    if(sensore_4==0) {
    lcd.print( "Mansarda " );
    }
    else
    lcd.print("");
    
    if(sensore_5==0) {
    lcd.print( "Casa!! " );
    }
    else
    lcd.print("");

  //avvio cicalino
  tone(6,1000);
  delay(500);
  tone(6,2000);
  delay(500);
  tone(6,1000);
  delay(500);
  tone(6,2000);
  delay(500);
  noTone(6);
  delay(800);


}
}

Troppo complicato, e manco funziona come vorresti :stuck_out_tongue:. Il led all'inizio è spento. Lo accendiamo insieme a quello del pin 13, per cui subito dopo:

digitalWrite(uscita, HIGH);

aggiungiamo:

digitalWrite(led_di_avviso, HIGH);

A questo punto quando scatta l'allarme il led si accende e rimane acceso finché non spegni Arduino, no? Per cui puoi togliere il codice che hai aggiunto per il pulsante e sostituirlo con l'opposto, per gestirne lo spegnimento:

  if (digitalRead(puls_reset) == LOW) {
    digitalWrite(led_di_avviso, LOW);
  }

Questo però presuppone che il pin abbia il pull-up attivo, per cui in setup() devi inizializzarlo come:

pinMode(puls_reset, INPUT_PULLUP);

Non era poi così difficile, no? :slight_smile:

Sei un grande... soluzione semplice e perfetta :grin: . Grazie infinite.

Ora capisci perché non ci vedevo niente di complicato?

Comunque, se vuoi che il led si riaccenda dopo una mancanza di alimentazione, definiamo una locazione in EEPROM:

const int avviso_eeprom_offset = 5;

Prima di accendere i due led scriviamo nella EEPROM che l'allarme è scattato:

EEPROM.write (avviso_eeprom_offset, 1);

Nell'if che spegne il led togliamo il flag anche dalla EEPROM:

EEPROM.write (avviso_eeprom_offset, 0);

A questo punto dobbiamo solo più preoccuparci di riaccendere il led in setup(), se il flag è settato, per cui basta aggiungere al fondo:

digitalWrite (led_di_avviso, EEPROM.read (avviso_eeprom_offset));

Fine!

Grazie anche per questo "up-grade" :slight_smile:

Purtroppo sono davvero alle prime armi e spesso mi vado ad ingarbugliare in soluzioni "strane" piuttosto che adottare le più ovvie :o

KISS principle - Wikipedia :wink: