Problema codice cicalino

Salv

SPIEGAZIONE PROGETTO:
Il progetto consiste in Arduino (+ Ethernet Shield), collegato a un router, che mette a disposizione un sito html (statico) a tutti gli host della medesima rete, dal quale si possono gestire 2 diodi LED, una ventola 5v e visualizzare i dati (temperatura/umidità) del sensore DHT22 e visualizzare lo stato dell'allarme anti-incendio (attivo/spento); tutti collegati ad Arduino. Inoltre c'è un modulo RTC DS3231 e un buzzer/cicalino che funge appunto da allarme anti-incendio e si attiva quando la temperatura è troppo alta (27.50 gradi perché ci impiego un sacco di tempo ad attivarlo con un accendino...).

PROBLEMA
Quando la temperatura supera i 27.5 gradi, il cicalino si attiva come dovrebbe ma la pagina html non viene visualizzata. Posto sotto il codice ma le parti interessate sono all'inizio con //CONTROLLO ALLARME// in cui controllo se la temperatura ha superato il limite e salvo lo stato dell'allarme nella stringa 'allarme' e alla fine in //stampo html// quando stampo la variabile allarme nell'HTML.

#include <Ethernet.h>
#include <String.h>
#include <DHT.h>
#include <DS3232RTC.h>

DHT dht(2, DHT22);

#define ventola 9

#define piezo 8

#define led1 5
#define f1 A2

#define led2 3
#define f2 A3

byte mac[] = {0x90, 0xA2, 0xDA, 0x10, 0xF6, 0xA3}; //indirisso fisico
byte ip[] = {192, 168, 1, 99}; //indirizzo ip locale
byte subnet[] = {255, 255, 255, 0}; //indirizzo subnet
byte gateway[] = {192, 168, 1, 254}; //indirizzo gateway
EthernetServer server(80); //creo il server 'server' che ascolta sulla porta 80
String ascoltatore;

int statoLed1 = 2;
int statoLed2 = 2;
int caldo = 2;

void setup()
{
  dht.begin(); //avvio il sensore
  Ethernet.begin(mac, ip, gateway, subnet);
  pinMode(f1, INPUT);
  pinMode(f2, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(piezo, OUTPUT);
  pinMode(ventola, OUTPUT);
  digitalWrite(ventola,HIGH);
  //setSyncProvider(RTC.get);
}

void loop()
{
  EthernetClient client = server.available(); //se c'è un oggetto cliente lo salva in 'client', se no inserisce false

  /////////////////////////////////////CALCOLO UMIDITA'+TEMPERATURA//////////////////////////////
  float umidita = dht.readHumidity(); // Leggo il valore di umidità
  float gradi = dht.readTemperature(); // Leggo il valore di temperatura
  ///////////////////////////////////////////////////////////////////////////////////////////////
  String allarme;
  /////////////////////////////////CONTROLLO ALLARME/////////////////////////////////////////////
  if (gradi > 27.50) {
    allarme="Acceso";
    tone(8, 1000, 500); //pin, frequenza, durata
    delay(500);
    tone(8, 650, 500);
    delay(500);
  }
  else {
    allarme="Spento";
    //NIENTE INCENDIO, NIENTE ALLARME
    noTone(8);
    //STATO NORMALE
    if (caldo == 2) {
      //C'E' CALDO
      if (gradi > 20) {
        digitalWrite(ventola, LOW); //HIGH
      }

      //NON C'E' COSI' CALDO
      else {
        digitalWrite(ventola, HIGH); //LOW
      }

      //SEMPRE ACCESO
    } else if (caldo == 1) {
      digitalWrite(ventola, LOW); //HIGH
    }

    //SEMPRE SPENTO
    else if (caldo == 0) {
      digitalWrite(ventola, HIGH); //LOW
    }
  }

  ///////////////////////////////////////////////////////////////////////////////////////////////


  int ora = 23;
  //int ira = hour();



  int valF1 = analogRead(f1); // salvo il valF1ore fotoresistenza dentro alla variabile valF1
  valF1 = (valF1 / 20) - 5;
  if (valF1 < 0) {
    valF1 = 0;
  }
  int valF2 = analogRead(f2); // salvo il valF1ore fotoresistenza dentro alla variabile valF1
  valF2 = (valF2 / 20) - 5;
  if (valF2 < 0) {
    valF2 = 0;
  }


  if (statoLed1 == 0) { //controllo che nell'url ci sia led11111=1
    //MOD.NORMALE
    if ((ora >= 7) && (ora <= 22)) {
      analogWrite(led1, valF1);
    }
    else {
      analogWrite(led1, 0);
    }
  }
  else {
    //BLOCCO
    //SEMPRE ACCESO
    if (statoLed1 == 1) {
      analogWrite(led1, valF1);
    }
    //SEMPRE SPENTO
    else if (statoLed1 == 0) {
      analogWrite(led1, 0);
    }
  }

  if (statoLed2 == 0) { //controllo che nell'url ci sia led11111=1
    //MOD.NORMALE
    if ((ora >= 7) && (ora <= 22)) {
      analogWrite(led2, valF2);
    }
    else {
      analogWrite(led2, 0);
    }
  }
  else {
    //BLOCCO
    //SEMPRE ACCESO
    if (statoLed2 == 1) {
      analogWrite(led2, valF2);
    }
    //SEMPRE SPENTO
    else if (statoLed2 == 0) {
      analogWrite(led2, 0);
    }
  }

  if (client) {
    char c = client.read(); // leggo i caratteri che invia
    ascoltatore.concat(c); // e li concateno i caratteri del client
    if (c == '\n') { //se arrivo a fine riga

      if (ascoltatore.indexOf("statoLed1=2") > 0) {
        //MOD.NORMALE
        statoLed1 = 2;
      }
      else {
        //SEMPRE ACCESO
        if (ascoltatore.indexOf("statoLed1=1") > 0) {
          statoLed1 = 1;
        }
        //SEMPRE SPENTO
        else if (ascoltatore.indexOf("statoLed1=0") > 0) {
          statoLed1 = 0;
        }
      }

      if (ascoltatore.indexOf("statoLed2=2") > 0) {
        //MOD.NORMALE
        statoLed2 = 2;
      }
      else {
        //SEMPRE ACCESO
        if (ascoltatore.indexOf("statoLed2=1") > 0) {
          statoLed2 = 1;
        }
        //SEMPRE SPENTO
        else if (ascoltatore.indexOf("statoLed2=0") > 0) {
          statoLed2 = 0;
        }
      }
  

      //////////////ARIA CONDIZIONATA/////////////////
      if (ascoltatore.indexOf("caldo=1") > 0) {
        caldo = 1;
      } else if (ascoltatore.indexOf("caldo=0") > 0) {
        caldo = 0;
      } else if (ascoltatore.indexOf("caldo=2") > 0) {
        caldo = 2;
      }
      /////////////////////////////////////////////////

      //stampo html
      client.println("HTTP/1.1 200 OK"); //codice di stato http standard - 2xx successo
      client.println("Content-Type: text/html"); //indico il formato - standard http
      client.println();
      client.println("<html>"); //inizio codice html
      client.println("<head>");
      client.println("<title>");
      client.println("Arduino");
      client.println("</title>");
      client.println("</head>");
      client.println("<body>");
      client.println("<table border='0' width='100%' cellspacing='2' cellpadding='5'>");
      client.println("<tr bgcolor='#E0E0FF'><td width='25%'><b>GESTIONE LUCI</b></td><td>LED1</td><td>LED2</td><td width='25%'></td></tr>");
      client.println("<tr><td>FORZA ACCENSIONE</td><td><a href='/?statoLed1=1'>Cliccami</a></td> <td><a href='/?statoLed2=1'>Cliccami</a></td></tr>");
      client.println("<tr><td >FORZA SPEGNIMENTO</td><td><a href='/?statoLed1=0'>Cliccami</a></td><td><a href='/?statoLed2=0'>Cliccami</a></td></tr>");
      client.println("<tr><td >LED NORMALE</td><td><a href='/?statoLed1=2'>Cliccami</a></td> <td><a href='/?statoLed2=2'>Cliccami</a></td></tr>");
      client.println("<tr  bgcolor='#E0E0FF'><td><b>STATO AMBIENTE</b></td><td>Temperatura(\260C)</td><td>Umidit&#224(%)</td><td>ALLARME INCENDIO</td></tr>");
      client.println("<tr><td></td><td>");
      client.print(gradi);
      client.print("</td> <td>");
      client.print(umidita);
      client.print("</td><td>");
      client.println(allarme);
      client.println("</td></tr>");
      client.println("<tr> <td>ARIA CONDIZIONATA</td><td><a href='/?caldo=1'>Accendi</a></td><td><a href='/?caldo=0'>Spegni</a></td><td><a href='/?caldo=2'>Normale</a></td></tr>");
      /*client.println("<tr><td></td><td></td><td><a href='/?caldo=0'>Spegni</a></td></tr>");
      client.println("<tr><td></td><td></td><td><a href='/?caldo=2'>Normale</a></td></tr>");*/
      client.println("</table>");
      client.println("</body>");
      client.println("</html>"); 
      client.stop();
      ascoltatore = "";
    }
  }
}

Secondo me hai un problema di RAM.
Usa la macro F() per tenere libero la RAM.

in tutti i
client.println("stringa"); o
client.print("stringa");
aggiungi la macro che diventa
client.println(F("stringa")); o
client.print(F("stringa"));

Ciao Uwe

Ciao uwefed, ho fatto come mi hai detto tu mettendo tutto nella flash, così la SRAM è passata da 78% utilizzata (dopo l'80% non funzionava più) a 41%, ma il problema persiste.

Ora ho provato a togliere quei 2 delay() che avevo messo dopo i tone(); la pagina parte, l'allarme è 'acceso' ma il risultato è un rumore fastidiosissimo che non si avvicina lontanamente al suono di un allarme.

Consigli su come fare?

Magari un'alternativa a delay()?

Scusa, due domande.
Primo, se usi il delay() perché in "tone()" specifichi anche la durata (terzo parametro)? Basterebbe un più semplice:

    allarme="Acceso";
    tone(8, 1000);
    delay(500);
    tone(8, 650);
    delay(500);

Ma a parte questo, la seconda domanda: ma tu COSA hai collegato al pin 8 esattamente? Un buzzer piezo, quindi qualcosa di passivo, o un buzzer attivo ossia che emette un suono quando alimentato? Perché nel secondo caso non devi usare tone() secondo me ma semplicemente usare il pin come ON/OFF (o al massimo in PWM).

Ciao docdoc,

  1. Perché sono un deficiente -.-', ho rifatto un'allarme decente senza delay() ok, problema risolto;
    2)E' il piezo PKM22EPP-40 del kit base di Arduino UNO (http://svel.to/w15), credo sia attivo perché si, emette un suono quando alimentato.
    Grazie del vostro aiuto.

Già che ci sono faccio un'altra domanda, non so se devo aprire un altro topic.
Come detto all'inizio, ho una ventola 5V comprata su amazon (http://svel.to/w16), incluso quello che mi sembra un mosfet (anche se non c'è scritto).
Praticamente ho notato che se do un valore digitale LOW al pin al quale è collegato il mosfet la ventola si accende e se do un valore digitale HIGH si spegne, mentre dandogli valori analogici (usando il PWM), inserendo lo stesso valore e.g. analogWrite(pin,200) a volte si accende altre volte no, addirittura si è accesa dandogli 0. Il circuito non l'ho sbagliato (c'è un LED power nel mosfet che si accende solo se colleghi correttamente gnd e vcc ). Ho già scritto il codice con logica invertita quindi la mia è solo una curiosità, non un problema. E' normale che si comporti così?

semplice:

  1. si è un mosfet
  2. è di tipo pnp quindi conduce nel momento in cui gli dai low, equivalente di analogWrite(pin, 0)
    Per avere l'effetto contrario, ovvero accendere la ventola quando hai il pin su HIGH devi usare un mosfet npn e metterlo a valle del load.

Aaaah Ok, Grazie Mille

Giagobox:
2)E' il piezo PKM22EPP-40 del kit base di Arduino UNO (http://svel.to/w15), credo sia attivo perché si, emette un suono quando alimentato.

Ah, ecco, mi pareva... :slight_smile: Quindi non puoi fare il bitonale, devi solo mettere il pin a HIGH e magari fare 500ms HIGH e 500ms LOW.
Oppure togli quello e ci metti un piezo passivo o un altoparlantino, e allora puoi usare la tone() (ci metterei anche in serie una resistenza da 1k ed un transistorino, per sicurezza).