Allarme non si disattiva con il codice

Ciao a tutti e buona sera :),
Ho un problema con il mio codice: dovrebbe essere un semplice allarme che puoi attivare/disattivare via internet, solo che nel momento in cui apro la pagina, premo “Spegni l’allarme” e il browser manda un ?alarmoff, il sistema si disattiva (sul seriale vedo "allarme disattivato), ma dopo circa 3 secondi si riattiva…Come potrei risolvere?

Grazie per la risposta :confused:

/*
 * Progetto domotico per la camera
 */

#include <SPI.h>
#include <Ethernet.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  //in questa stringa indichiamo i pin che useremo per connettere il display LCD al microcontrollore
int movement = 7;
int alarm = 0;
int movementstatus = 0;
int piezo = 8; //il buzzer si torva sul pin 8
int sensorPin = 0; //il sensore di temperatura si trova sul pin Analogico 0
int trigger = 0; //il numero di volte che il PIR ha rilevato movimento, il -1 è per bilanciare il "false trigger" iniziale
int button = 9;   //The word “button” stands for the value 7.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 177 }; // fixed IP addr in LAN
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
EthernetServer server(80); //server port
String readString;
void setup() {
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.begin(9600);
  pinMode(piezo, OUTPUT);  //il buzzer è un output.
  pinMode(movement, INPUT);  //il movement è definito come un imput.
  lcd.begin(16, 2);   //nel setup indichiamo quante righe e quante colonne andremo ad utilizzare del display
  lcd.setCursor(0, 0);
  lcd.print("#####AVVIO######");
  lcd.setCursor(0, 1);
  lcd.print("#192.168.1.177##");
  digitalWrite(piezo, HIGH);
  delay (200);
  digitalWrite(piezo, LOW);
  delay (200);
  digitalWrite(piezo, HIGH);
  delay (200);
  digitalWrite(piezo, LOW);
  delay (2000);
  lcd.setCursor(0, 0);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");
}
void loop() { //inizia il loop
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();
          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Camera Ricky</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY bgcolor='red'>");
          client.println("<H1>Camera Ricky</H1>");
          client.println("<hr />");
          client.println("
");

          client.println("<a href=\"/?alarmon\"\">Accendi l'allarme</a>");
          client.println("<a href=\"/?alarmoff\"\">Spegni l'allarme</a>
");

          client.println("</BODY>");
          client.println("</HTML>");

          delay(1);
          //stopping client
          client.stop();
          if (readString.indexOf("?alarmon") > 0 && alarm == 0) //checks for on
          {
            Serial.println("allarme attivato");
            alarm = 1;
            digitalWrite(piezo, HIGH);
            delay (170);
            digitalWrite(piezo, LOW);
            lcd.setCursor(0, 1);
            lcd.print("In avvio...     ");
            delay (5000);
          }
          else
          {
            Serial.println ("allarme già attivato");
          }
          if (readString.indexOf("?alarmoff") > 0 && alarm == 1) //checks for off
          {
            alarm = alarm - 1;
            digitalWrite(piezo, HIGH);
            delay (170);
            digitalWrite(piezo, LOW);
            Serial.println ("allarme disattivato");
            trigger = 0;
            digitalWrite (piezo, LOW);
          }
          else
          {
            Serial.println ("allarme gia disattivato");
          }
        }
      }
    }
movementstatus = digitalRead(movement); //leggi il voltaggio che arriva dal pin 7...
if (movementstatus == HIGH && alarm == 1 && trigger <= 2) //se viene rilevato del movimento...
{ //inizia la struttura "if"
  Serial.println("MOVIMENTO RILEVATO");
  lcd.setCursor(0, 1);
  lcd.print("ANCORA ");
  lcd.setCursor(8, 1);
  lcd.print(1 - trigger);
  lcd.setCursor(9, 1);
  lcd.print("TENTATI      ");
  trigger = trigger + 1;
  lcd.setCursor(0, 0);
  lcd.print("MOVIMENTO RILEVA");
  delay (1000);
  lcd.setCursor(0, 0);
  lcd.print("OVIMENTO RILEVAT");
  delay (1000);
  lcd.setCursor(0, 0);
  lcd.print("VIMENTO RILEVATO");
  delay (1000);

}
lcd.setCursor(0, 0);   //reset del display
lcd.print("                ");
lcd.setCursor(0, 1);
lcd.print("                ");

int reading = analogRead(sensorPin); //leggi il voltaggio che arriva del pin analogico...
float voltage = reading * 5.0 / 1024; //...e trasforma in temperatura
float temperatureC = (voltage - 0.5) * 100 ;
lcd.setCursor(0, 0);
lcd.print("Temp.=");
lcd.setCursor(6, 0);
lcd.print(temperatureC);
lcd.setCursor(10, 0);
lcd.print("C");
if (alarm == 1);
{
  lcd.setCursor(0, 1);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("Allarme Attivo");
  lcd.setCursor(15, 1);
  lcd.print(trigger);
}
if (alarm == 0) {
  lcd.setCursor(0, 1);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("Allarme Disattivo");
}
if (trigger >= 2) {
  delay (5000);
  lcd.setCursor(0, 0);   //reset del display
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");
  digitalWrite(piezo, HIGH);
  lcd.setCursor(0, 0);   //reset del display
  lcd.print("Allarme!!!");
}

delay (2000);   //delay per il loop
}
}

Ciao, ho creato degli sketch usando questo genere di webserver e ho sempre utilizzato la riga

readString = "";

messa dopo il

client.stop();

Perchè appunto dopo ogni utilizzo (un client che richiede una URL) va svuotata…

tu non hai questa riga di codice quindi la readString continui a sommarla a se stessa (semplicemente aggiungendo a quanto già contiene, il nuovo contenuto della richiesta URL…

probabile (non sono sicuro) che per questo motivo ti si inneschi di nuovo la condizione del tuo if:

if (readString.indexOf("?alarmon") > 0 && alarm == 0)

p.s. quando vuoi “pulire” il display non c’è bisogno che fai:

 lcd.setCursor(0, 0);   //reset del display
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");

Usa piuttosto la funzione

lcd.clear();

ti allego comunque il tuo sketch leggermente modificato sulla base dell’esempio webserver (che viene fornito insieme alla libreria) e con qualche modifica alla parte della stampa della pagina web (adesso quando attivi o disattivi il timer ricevi una pagina web diversa con solo scritto se hai attivato o meno, un po come se fosse il tuo monitor seriale)

LEGGI I COMMENTI IN MAIUSCOLO CHE HO INSERITO

(vedi allegato)

c’è da dire inoltre che usi tantissimo i delay… poco importa nel setup quando fai bippare il piezo, ma all’interno del tuo loop non è assolutamente una buona cosa abusare della funzione delay!
Considera che mentre usi delay, mandi in pausa il processore… ci sono sicuramente modi più eleganti di posticipare l’inserimento di un timer…

ti do uno spunto, ma poi fai tu in caso la modifica :slight_smile:

quando viene richiesta la URL di attivazione del timer, oltre a stamparti su seriale e sulla pagina web che l’allarme è stato inserito, anziche attivare subito l’allarme e mettere un delay di 5secondi, imposta una variabile boolean come TRUE e salva i millis() attuali in un’altra variabile.
all’interno del loop poi inserisci una condifizione if basata un po sull’esempio del BlinkWithoutDelay dove controlli se la variabile di attivazione timer è TRUE e SE sono trascorsi i 5secondi da quando hai salvato il tempo (i millis di prima)… se si, attiva l’allarme e riporta a FALSE la variabile boolean che permette al controllo del tempo trascorso di attivare il timer!

spero funzioni come volevi :slight_smile:

edited.zip (2.35 KB)

Grazie mille :smiley:
Funziona alla perfezione, solo che è un po lentino nel caricamento
Gia che ci sono...potrei chiederti come posso far funionare l'LCD che ho messo nel mio progetto? So che è "colpa" della eth shield, ma non ho idea su come disattivare il sd card reader per rendere disponibili i pin occupati da appunto l'sd card, oppure su come cambiare i pin del lcd

bene :slight_smile:

per guanto riguarda lcd tu i pin da usare li dichiari all'inizio dello sketch..sinceramente mi trovi impreparato se ti basta dichiararne altri non usati dalla ethernet shield per risolvere... aspettiamo qualcuno dei big del forum per vedere se puoi risolvere solo via software..

Un'alternativa provata da me e funzionante, con molti lati positivi è l'uso di un moduletto come questo: LINK

che ti permette di gestire il tuo display lcd senza usare tutti i pin che usi ora, ne basteranno 2 (a parte l'alimentazione ovviamente)
Dovrai usare una libreria diversa (praticamente tutti i comandi IDENTICI) che userà il display appunto tramite i 2 pin SDA e SCL (vedi in base a quale arduino usi su che pin trovi questi 2...su Arduino UNO sono al pin 2 e 3 se non ricordo male :slight_smile: )

Per il discorso lentino nel caricamento, credo possa dipendere dai tanti delay che usi!! Come ti ho detto, in quei momenti mandi il pausa il processore quindi per caricare la pagina web, dovrai attendere anche quei tempi!

Trrova un modo per sostituire i delay con l'uso della funzione millis() ! Lasciati ispirare dall'esempio che si chiama BlinkWithoutDelay!