Go Down

Topic: Aiuto If, else If, else (Read 244 times) previous topic - next topic

aquilacieca

ciao a tutti,
sto cercando di gestire una piccola serra con dht22, ventole per pc e un riscaldatore da 5 v tutto comandato da arduino uno e scheda relè. non voglio far scattare il relè ogni secondo quindi ho creato un'isteresi

la mia intenzione è quella di attivare le ventole sopra i 24 gradi, tenere tutto spento tra 24 e 21 e accendere il riscaldamento sotto i 21.

vi allego il mio codice:

Code: [Select]

int Tempimpostata = 24;
int Isteresi = 3;

voip setup ()
....
void loop ()
if (t > Tempimpostata)
{
  calore e ventola spente
   }
 else if (t < Tempimpostata - Isteresi)
{
   calore acceso e ventole spente
    }
else if (t > Tempimpostata + isteresi)
{
   calore spento e ventole accese
  }
else
{
   calore spento e ventole spente
 
  }



vedete degli errori? sto cercando di capire se ho ragionato in maniera troppo contorta e se c'è un modo piu semplice.

grazie mille

daniele

MatteoDerrico

ciao

io modificherei semplicemente così :)

Code: [Select]
#define TempimpostataMAX = 24;
#define TempimpostataMIN = 21;



voip setup ()
....
void loop (){
if (t >= TempimpostataMAX){  calore spento e ventole accese   }
if (t > TempimpostataMIN && t <TempimpostataMAX){ Tutto spento}
if (t < TempimpostataMIN){riscaldamento acceso e ventole spente}
 
 }


se un valore è fisso, tipo TempimpostataMAX non definirla come int, essendo che non varia all'interno del codice, ma bensì come #define, così risparmi spazio sulla memoria del micro :)

MD
Se una scrivania in disordine è segno di una mente disordinata, di cosa sarà segno allora una scrivania vuota?

aquilacieca

grazie mille per la risposta, seguiro il tuo consiglio sul #define.

con il tuo codice se la temperatura è bassa accedo il riscaldamento cosi:
Code: [Select]

if (t < TempimpostataMIN){riscaldamento acceso e ventole spente}



ma una volta raggiunta la temperatura minima il relè si staccherà e si riattaccherà appena scenderà di 0,1 gradi; in pratica avrò un continuo stacca e attacca  o sbaglio?

fabpolli

Io lo modificherei cosi:
Code: [Select]

if (t > Tempimpostata)
{
  if (t > Tempimpostata + isteresi)
  {
    calore spento e ventole accese
  }
  else
  {
    calore e ventola spente
  }
}
else
{
  if (t < Tempimpostata - Isteresi)
  {
    calore acceso e ventole spente
  }
}

perché nel tuo codice se la temperatura è maggiore di quella impostata entra nel primo if e spegne tutto senza considerare gli altri else if che contemplano l'isteresi

docdoc

#4
Jan 17, 2019, 02:45 pm Last Edit: Jan 17, 2019, 02:46 pm by docdoc
Boh a me sembra che il problema sia semplice...
La descrizione dice tutto:
"attivare le ventole sopra i 24 gradi, tenere tutto spento tra 24 e 21 e accendere il riscaldamento sotto i 21"

Quindi basta implementare questa logica "traducendo" i commenti in codice:

Code: [Select]
#define TEMP_MIN 21
#define TEMP_MAX 24
 ...
void loop ()
  ...
  // attivare le ventole sopra i 24 gradi
  if (t > TEMP_MAX)
  {
    // Attivo ventole
  }
  // accendere il riscaldamento sotto i 21
  else if (t < TEMP_MIN)
 {
    // Attivo riscaldamento
  }
  else
  // tenere tutto spento tra 24 e 21
  {
    // Disattivo ventole
    // Disattivo riscaldamento
  }


Per ora questa è la soluzione più semplice ed immediata ma ovvio che ci sono anche altri modi, ad esempio per attivare o disattivare solamente al primo passaggio di stato evitando di fare digitalWrite ad ogni loop:

Code: [Select]
#define TEMP_MIN 21
#define TEMP_MAX 24

#define STATO_LOW -1
#define STATO_OFF 0
#define STATO_HIGH 1
int stato = STATO_OFF;
 ...
void loop ()
  ...
  // attivare le ventole sopra i 24 gradi
  if (t > TEMP_MAX && stato < STATO_HIGH)
  {
    // Attivo ventole
    stato = STATO_HIGH;
  }
  // accendere il riscaldamento sotto i 21
  else if (t < TEMP_MIN && stato > STATO_LOW)
 {
    // Attivo riscaldamento
    stato = STATO_LOW;
  }
  else if ( stato != STATO_OFF )
  // tenere tutto spento tra 24 e 21
  {
    // Disattivo ventole
    // Disattivo riscaldamento
    stato = STATO_OFF;
  }
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

aquilacieca

Io lo modificherei cosi:
Code: [Select]

if (t > Tempimpostata)
{
  if (t > Tempimpostata + isteresi)
  {
    calore spento e ventole accese
  }
  else
  {
    calore e ventola spente
  }
}
else
{
  if (t < Tempimpostata - Isteresi)
  {
    calore acceso e ventole spente
  }
}

perché nel tuo codice se la temperatura è maggiore di quella impostata entra nel primo if e spegne tutto senza considerare gli altri else if che contemplano l'isteresi
Grazie mille, ho risolto grazie al tuo suggerimento.
Stamattina è saltata l'energia elettrica, quando è tornata la temperatura era superiore alla Tempimpostata ed è partito sia il calore sia le ventole (da codice doveva essere tutto spento). quando ha raggiunto Tempimpostata+Isteresi si è spento tutto ed ha iniziato a funzionare regolarmente come da codice. perchè?

fabpolli

Credo dipenda da come hai settato le cose nel setup, probabilmente parti tutto acceso, invece devi partire tutto spento e demandare al loop le decisioni, ma senza il programma completo sto tirando a indovinare

aquilacieca

Credo dipenda da come hai settato le cose nel setup, probabilmente parti tutto acceso, invece devi partire tutto spento e demandare al loop le decisioni, ma senza il programma completo sto tirando a indovinare
scusa, hai ragione, in setup parte tutto acceso; grazie ancora, molto gentile. Risolto


docdoc

scusa, hai ragione, in setup parte tutto acceso; grazie ancora, molto gentile. Risolto
Bene, ma ti consiglio caldamente di implementare il codice come nel mio secondo esempio, che NON modifica nulla a meno che tu non stia passando da uno stato all'altro... ;)
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito, clicca su "add" qui a sinistra, vicino al mio nome ;) **

aquilacieca

grazie del consiglio, non appena avrò risolto altri piccoli inghippi proverò il tuo codice.

ciao ciao

Go Up