Controllo temperatura ambientale e accensione caldaia

Ciao a tutti!

Eccomi qua col mio primo progettino da principiante (siate clementi). Sò che esistono già centinaia di sketch a riguardo, ma un semplice "copia e incolla" mi toglierebbe tutti il gusto e, siccome il mio scopo è anche quello di imparare, preferisco partire da zero e sviluppare la cosa piano piano.

Per ora la mia intenzione è quella di rilevare la temperatura in tre stanze diverse e fare intervenire l'accensione e spegnimento della caldaia in base temperatura stabilita ( ovvietà ). Tutto questo è già operativo nel mio appartamento tramite termostati, elettrovalvole, una manciata di relè e qualche spia. Ora vorrei poter fare la stessa cosa in maniera più "elegante" fino ad avere il controllo da un termilale video.

Ma procediamo per gradi:

ho realizzato questo script che rileva la temperatura ( anche l'umidità ma al momento non mi serve) tramite un sensore DHT11 (poi lo cambierò xchè non è il massimo visto che non rileva i decimi di grado, ma per ora va bene così) e fa accendere un Led ( che simule l'accansione della caldaia) in base alla temperatura desiderata tenedo conto anche del Delta di intervento ( si dice così?) che ho impostato a 2 gradi; e fino a qua nn ci sono problemi:
impostando la temperatura a 20° il Led si accende fino a quando la temperatura non raggiunge i 21 e non si riaccende fino a quando la temperatura non scende a 19°. Il tutto poi è riportato su una pagina html dove mi indica la temperatura e (dovrebbe) lo stato della caldaia (accesa / spenta). In quest'ultima parte ho riscontrato qualche problemino. Ho capito che per sapere lo stato di acceso o spendo devo rilevare l'effettivo stato del pin e poi mi sono domandato: " ma se accendo il tutto e la temperatura è già nel campo del Delta come verrà interpretato? Si accenderà vino ad arrivare al Delta max o rimarrà spento fino al Delta min? ( anche se alla fine ha poca rilevanza ). Forse il mio calcolo è corretto ma non è il modo giusto per farlo.

Bhè ecco il codice. Probabilmente nn è il modo corretto di postarlo. Qualcosa l'ho scopiazzato xchè cmq sono agli inizi e prendo per buono alcune cose. Spero che i commenti siano sufficientemente chiari e spero in commenti, consigli e critiche costruttive.

#include <Ethernet.h>
#include <SPI.h>
#define DHT11_PIN 0 // ADC0

// inizio dati sensore copiati dal file di test del DHT11 //
byte read_dht11_dat()
{
byte i = 0;
byte result=0;
for(i=0; i< 8; i++)
{
while(!(PINC & _BV(DHT11_PIN))); // wait for 50us
delayMicroseconds(30);
if(PINC & _BV(DHT11_PIN))
result |=(1<<(7-i));
while((PINC & _BV(DHT11_PIN))); // wait '1' finish
}
return result;
}
// fine dati sensore copiati dal file di test //

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 2, 5 }; // ip arduino internet in
//byte gateway[] = { 192, 168, ***, *** }; // internet access via router (non utilizzato)
//byte subnet[] = { 255, 255, ***, *** }; //subnet mask (non utilizzato)
Server server(80); //server port

int pin_attuatore = 8; // pin per test accensione
float tempreg = 20.0; // temperatura di controllo in celsius

void setup()
{
DDRC |= _BV(DHT11_PIN); // istruzioni per il dht11 copiate dal file di test
PORTC |= _BV(DHT11_PIN); // istruzioni per il dht11 copiate dal file di test
Serial.begin(9600);
Serial.println("Ready"); //istruzione per il dht11 copiate dal file di test
Ethernet.begin(mac, ip);
pinMode(pin_attuatore, OUTPUT);
}

void loop(){

/inizio temp/
/* inizio codice sensore dht11 copiato dal file di test */
{
byte dht11_dat[5];
byte dht11_in;
byte i;// start condition
// 1. pull-down i/o pin from 18ms
PORTC &= ~_BV(DHT11_PIN);
delay(18);
PORTC |= _BV(DHT11_PIN);
delayMicroseconds(40);
DDRC &= ~_BV(DHT11_PIN);
delayMicroseconds(40);

dht11_in = PINC & _BV(DHT11_PIN);
if(dht11_in)
{
Serial.println("dht11 start condition 1 not met");
return;
}
delayMicroseconds(80);
dht11_in = PINC & _BV(DHT11_PIN);
if(!dht11_in)
{
Serial.println("dht11 start condition 2 not met");
return;
}

delayMicroseconds(80);// now ready for data reception
for (i=0; i<5; i++)
dht11_dat = read_dht11_dat();

  • DDRC |= _BV(DHT11_PIN);*
  • PORTC |= _BV(DHT11_PIN);*
  • byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];// check check_sum*
  • if(dht11_dat[4]!= dht11_check_sum)*
  • {*
  • Serial.println("DHT11 checksum error");*
  • }*
  • Serial.print("Current humdity = ");*
  • Serial.print(dht11_dat[0], DEC); // valore di umidità*
  • Serial.print(".");*
  • Serial.print(dht11_dat[1], DEC); // valore di umidità dopo la virgola (che non viene rilevato)*
  • Serial.print("% ");*
  • Serial.print("temperature = ");*
  • Serial.print(dht11_dat[2], DEC); // valore di temperatura*
  • Serial.print(".");*
  • Serial.print(dht11_dat[3], DEC); // valore di temperatura dopo la virgola (che non viene rilevato)*
  • Serial.println("C ");*
  • delay(2000);*
    _ /* fine codice sensore dht11 copiato dal file di test */_
    _ /fine temp/_
  • // inizio temperatura di intervento (calcolo del Delta T)*
  • if (dht11_dat[2]<=tempreg-1) // condizione per l'accansione*
  • {*
  • digitalWrite(pin_attuatore, HIGH);*
  • Serial.println("Acceso");*
  • }*
  • if (dht11_dat[2]>=tempreg+1) // condizione per lo spegnimento*
  • {*
  • digitalWrite(pin_attuatore, LOW);*
  • Serial.println("Spento");*
  • }*
  • // fine temperatura di intervento*

_ /inizio client////////////////////////////////////////////////////////////_
Client client = server.available();

  • // COSTRUZIONE PAGINA HTML*

  • client.println("HTTP/1.1 200 OK");*

  • client.println("Content-Type: text/html");*

  • client.println();*

  • // inizializzo pagina*

  • client.print("ARDUINO Controllo Temperatura via WEB");*

  • //send first heading*

  • client.println("

    "); //risoluzione*

  • client.println("

    STATUS SENSORI


    ");*

  • //Scrive sul browser il valore del termistore*

  • client.println("

    TEMPERATURA = ");*

  • client.print(dht11_dat[2], DEC);*

  • client.print(".");*

  • client.print(dht11_dat[3], DEC);*

  • client.println(" C*

    ");

  • if (pin_attuatore, HIGH) {*

  • // scrive sul web che il pin attuatore è attivo*

  • client.print("

    ACCESO

    ");*

  • }*

  • if (pin_attuatore, LOW) {*

  • // scrive sul web che il pin attuatore è spento*

  • client.print("

    SPENTO

    ");*
    }

  • client.print("

    AGGIORNA SENSORI: CHECK


    ");*

  • // chiudo il div*

  • client.println("");*

  • // chiudo pagina*

  • client.println("");*

  • client.stop();*

  • }*

  • }*

  • // fine*
    Ciao
    Clarky

Ciao,
certo che come principiante, utilizzare i pin tramite registri... :roll_eyes:

Attenzione perchè, soprattutto agli inizi, rende molto difficile la rilettura del codice ..

Ciao,
certo che come principiante, utilizzare i pin tramite registri... smiley-roll

Attenzione perchè, soprattutto agli inizi, rende molto difficile la rilettura del codice ..

Perdonami ma nn ho la + pallida idea di quello che hai detto. :blush:

clarky:
Ciao a tutti!

Eccomi qua col mio primo progettino da principiante (siate clementi). Sò che esistono già centinaia di sketch a riguardo, ma un semplice "copia e incolla" mi toglierebbe tutti il gusto e, siccome il mio scopo è anche quello di imparare, preferisco partire da zero e sviluppare la cosa piano piano.

Bene.

In quest'ultima parte ho riscontrato qualche problemino. Ho capito che per sapere lo stato di acceso o spendo devo rilevare l'effettivo stato del pin

O usi una variabile di stato che modifichi insieme alla variazione del segnale sul pin (ad esempio HIGH=TRUE e LOW=FALSE) oppure leggi lo stato del pin leggendo i registri del micro.

e poi mi sono domandato: " ma se accendo il tutto e la temperatura è già nel campo del Delta come verrà interpretato? Si accenderà vino ad arrivare al Delta max o rimarrà spento fino al Delta min? ( anche se alla fine ha poca rilevanza ). Forse il mio calcolo è corretto ma non è il modo giusto per farlo.

Devi fare un controllo: se "tenti" di accendere la caldaia già accesa, semplicemente devi ignorare l'operazione. E viceversa per staccarla.

Bhè ecco il codice. Probabilmente nn è il modo corretto di postarlo.

Esatto. Devi usare l'apposito tag CODE (il pulsantino con l'icona "#" presente sopra all'area di inserimento dei reply)

Qualcosa l'ho scopiazzato xchè cmq sono agli inizi e prendo per buono alcune cose.

Uh... ma non avevi detto che non volevi scopiazzare per imparare? :sweat_smile:

clarky:

Ciao,
certo che come principiante, utilizzare i pin tramite registri... smiley-roll

Attenzione perchè, soprattutto agli inizi, rende molto difficile la rilettura del codice ..

Perdonami ma nn ho la + pallida idea di quello che hai detto. :blush:

Perché poi succede questo. :roll_eyes:

Grazie Leo, vedo che hai capito il tipo di aiuto che cerco; non soluzioni pronte ma suggerimenti per trovare la soluzione :wink: .

Quote
Qualcosa l'ho scopiazzato xchè cmq sono agli inizi e prendo per buono alcune cose.
Uh... ma non avevi detto che non volevi scopiazzare per imparare? smiley-sweat

E' vero hai ragione, ma volevo dedicarmi per ora all'elaborazione dei dati ricevuti senza perdere tempo (per ora) sul come vengono ricevuti (mi riferisco a come viene confezionato il dato della temperatura)
Comunque ecco il codice modificato e funzionante nella sua parte principale (lettura e visualizzazione sia su seriale che via http della temperatura, accensione e spegnimento della caldaia in base alla temperatura di riferimento tenendo conto di un Delta T e visualizzazione dello stato della caldaia sia su seriale che via http )

Altri consigli o migliorie sono sempre ben accetti

#include <Ethernet.h>
#include <SPI.h>
#define DHT11_PIN 0      // ADC0
#define pin_attuatore 8

// inizio dati sensore copiati dal file di test //
byte read_dht11_dat()
{
  byte i = 0;
  byte result=0;
  for(i=0; i< 8; i++)
  {
    while(!(PINC & _BV(DHT11_PIN)));  // wait for 50us
    delayMicroseconds(30);
    if(PINC & _BV(DHT11_PIN)) 
      result |=(1<<(7-i));
    while((PINC & _BV(DHT11_PIN)));  // wait '1' finish
    }
    return result;
}
// fine dati sensore copiati dal file di test //

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 2, 5 }; // ip arduino internet in
//byte gateway[] = { 192, 168, ***, *** }; // internet access via router (non utilizzato)
//byte subnet[] = { 255, 255, ***, *** }; //subnet mask (non utilizzato)
Server server(80); //server port 
float tempreg = 20.0; // temperatura di controllo in celsius
int stato_caldaia;

 
void setup()
{
  DDRC |= _BV(DHT11_PIN);  // istruzioni per il dht11 copiate dal file di test
  PORTC |= _BV(DHT11_PIN); // istruzioni per il dht11 copiate dal file di test
  Serial.begin(9600); 
  Serial.println("Ready"); //istruzione per il dht11 copiate dal file di test
  Ethernet.begin(mac, ip);
  pinMode(pin_attuatore, OUTPUT);
}
 
void loop(){
 
  /*inizio temp*/
  /* inizio codice sensore dht11 copiato dal file di test */
  {
  byte dht11_dat[5];
  byte dht11_in;
  byte i;// start condition
	 // 1. pull-down i/o pin from 18ms
  PORTC &= ~_BV(DHT11_PIN);
  delay(18);
  PORTC |= _BV(DHT11_PIN);
  delayMicroseconds(40);
  DDRC &= ~_BV(DHT11_PIN);
  delayMicroseconds(40);
  
  dht11_in = PINC & _BV(DHT11_PIN);
  if(dht11_in)
  {
    Serial.println("dht11 start condition 1 not met");
    return;
  }
  delayMicroseconds(80);
  dht11_in = PINC & _BV(DHT11_PIN);
  if(!dht11_in)
  {
    Serial.println("dht11 start condition 2 not met");
    return;
  }
  
  delayMicroseconds(80);// now ready for data reception
  for (i=0; i<5; i++)
    dht11_dat[i] = read_dht11_dat();
  DDRC |= _BV(DHT11_PIN);
  PORTC |= _BV(DHT11_PIN);
  byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];// check check_sum
  if(dht11_dat[4]!= dht11_check_sum)
  {
    Serial.println("DHT11 checksum error");
  }
  Serial.print("Current humdity = ");
  Serial.print(dht11_dat[0], DEC); // valore di umidità
  Serial.print(".");
  Serial.print(dht11_dat[1], DEC); // valore di umidità dopo la virgola (che non viene rilevato)
  Serial.print("%  ");
  Serial.print("temperature = ");
  Serial.print(dht11_dat[2], DEC); // valore di temperatura
  Serial.print(".");
  Serial.print(dht11_dat[3], DEC); // valore di temperatura dopo la virgola (che non viene rilevato)
  Serial.println("C  ");
  delay(1000);
  /* fine codice sensore dht11 copiato dal file di test */
  /*fine temp*/
  
  stato_caldaia = digitalRead(pin_attuatore);
  
  // inizio temperatura di intervento (calcolo del Delta T)
  
  if (dht11_dat[2]<=tempreg-1) // condizione per l'accansione
  {
    digitalWrite(pin_attuatore, HIGH);
  }
  if (dht11_dat[2]>=tempreg+1) // condizione per lo spegnimento
  {
    digitalWrite(pin_attuatore, LOW);
  }
  // fine temperatura di intervento
  
  // scrive su seriale lo stato della caldaia
  if (stato_caldaia == HIGH)
  {
    Serial.println("ACCESO");
  }
  else
  {
    Serial.println("SPENTO");
  }
  
  // fine 
  
  /*inizio client*////////////////////////////////////////////////////////////
Client client = server.available();
 
        // COSTRUZIONE PAGINA HTML
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/html");
        client.println();
        // inizializzo pagina
        client.print("<html><head><title>ARDUINO Controllo Temperatura via WEB</title><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' ></head><body>");
        //send first heading
        client.println("<div style='width:360px; height:640px;'>"); //risoluzione
        client.println("<h1>STATUS SENSORI</h1><hr />");
        //Scrive sul browser il valore del termistore
        client.println("<p>TEMPERATURA = ");
        client.print(dht11_dat[2], DEC);
        client.print(".");
        client.print(dht11_dat[3], DEC);
        client.println(" C 
</p>");
        
       
      if (stato_caldaia == HIGH) {
       
        client.print("<p><strong>ACCESO</strong></p>"); // scrive sul web che il pin attuatore è attivo
        
        }
        
      if (stato_caldaia == LOW) {
        
        client.print("<p><strong>SPENTO</strong></p>"); // scrive sul web che il pin attuatore è spento
        
        }
        client.print("<h2>AGGIORNA SENSORI: <a href=''>CHECK</a></h2><hr />");

       
        // chiudo il div
        client.println("</div>");
        // chiudo pagina
        client.println("</body></html>");
 
        client.stop();
  }
  }
   // fine

Saluti
Clarky

Sell'ethernet non ti posso dare aiuto, non è un campo che ho affrontato (non mi interessa). Su altre cose, se hai bisogno, puoi chiedere.

leo72:
Sell'ethernet non ti posso dare aiuto, non è un campo che ho affrontato (non mi interessa). Su altre cose, se hai bisogno, puoi chiedere.

come non ti interessa, è la parte più affascinante!! ricevere dati e inviarli da un palmare, costruirsi un sinottico non ha prezzo, altro che controllare arduino con un pulsantino e leggere i valori sulla seriale... troppo facile :smiley: :smiley:

ciao

Non ho palmari né ho in previsione di acquistarne uno. Per come vedo io l'informatica necessito sempre di un computer, un palmare/tablet è troppo limitativo per me.
Mi diverto vedere le cose che fate in questo campo ma non mi interessano assolutamente. :wink: