Go Down

Topic: Problema pause nel loop (Read 561 times) previous topic - next topic

nico72

Jan 27, 2014, 03:00 pm Last Edit: Jan 27, 2014, 03:13 pm by nico72 Reason: 1
Ciao a tutti, da nuovo iscritto , dopo una breve presentazione eccomi qui a chiedere gia il vostro aiuto. con Arduino vorrei realizzare un sketch per gestire una cella di maturazione per impasti lievitati. ho provato a buttare giu qualcosa, gira ma non come vorrei.quando lo accendo parte dalla sezione lievitazione  poi va a raffreddamento e li rimane. invece a me serve che parta dall'inizio , ossia ci sono 4 fasi : raffreddamento che deve durare 2 ore, poi maturazione per x ore , poi pre-lievitazione per 2 ore e lievitazione per 3 ore. i tempi adesso sono messi provvisori ,durante il tempo di attesa deve poter eseguire il pezzo di loop per mantenere temperatura e umidità adeguata.  non essendo pratico non trovo l'errore, chiedo aiuto a voi per compilare questo mio progetto.grazie
Code: [Select]
#include <LiquidCrystal.h>
#include "DHT.h"
#define DHTPIN 8
// 8 è il pin di Arduino a cui collego il sensore di temperatura
#define DHTTYPE DHT11
// dht11 è il tipo di sensore che uso
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// connessione display (pin)
const int tout = 7;
const int hout = 6;
unsigned long time;

void setup() {
 lcd.begin(20, 4);
 // imposto il tipo di display (colonne, righe)
 lcd.print("Temperatura");
 lcd.setCursor(0,1);
 lcd.print("Umidita'");
 lcd.setCursor(0,2);
 lcd.print("Ciclo");
 lcd.setCursor(0,3);
 lcd.print("Tempo");
 pinMode(tout, OUTPUT);
 pinMode(hout, OUTPUT);
 time=millis();
}

void loop() {
 time=millis();
 int t = dht.readTemperature();
 int h = dht.readHumidity();
 // posiziono il cursore alla colonna 14 e riga 0
 lcd.setCursor(14, 0);
 lcd.print(t);
 lcd.setCursor(14, 1);
 lcd.print(h);

 do
   if (t > 25)
 {
   digitalWrite(tout, LOW);
   lcd.setCursor(14, 4);
   lcd.print("acceso");
 }
 else {
   digitalWrite(tout, HIGH);
   lcd.setCursor(14, 4);
   lcd.print("spento");
   lcd.setCursor(6, 2);
   lcd.print("Raffreddamento");
 }
 while ( time > 60000 );
 

 do
 if (t > 25)
 {
   digitalWrite(tout, LOW);
   lcd.setCursor(14, 4);
   lcd.print("acceso");
 }
 else {
   digitalWrite(tout, HIGH);
   lcd.setCursor(14, 4);
   lcd.print("spento");
   lcd.setCursor(6, 2);
   lcd.print("Maturazione   ");
 }
   while ( time > 80000 );

do
 if (t > 25)
 {
   digitalWrite(tout, LOW);
   lcd.setCursor(14, 4);
   lcd.print("acceso");
 }
 else {
   digitalWrite(tout, HIGH);
   lcd.setCursor(14, 4);
   lcd.print("spento");
   lcd.setCursor(6, 2);
   lcd.print("Pre-lievitaz.");
 }
   while ( time > 100000 );
   
   do
 if (t > 25)
 {
   digitalWrite(tout, LOW);
   lcd.setCursor(14, 4);
   lcd.print("acceso");
 }
 else {
   digitalWrite(tout, HIGH);
   lcd.setCursor(14, 4);
   lcd.print("spento");
   lcd.setCursor(6, 2);
   lcd.print("Lievitazione ");
 }
   while ( time > 120000 );

}

nid69ita

1. devi crearti una variabile che contiene lo stato, ovvero il "momento" in cui sei.
Tu parli di 4 fasi o stati, perciò puoi avere stato 0=raffreddamento, 1=maturazione, 2=prelievitazione, 3=lievitazione
avrai un bel
Code: [Select]
switch(fase)
{ case 0: // raffreddamento
  case 1: // maturazione
...
}


2. devi vedere l'esempio blink without delay. Usando la millis().

Dovrai tu far aumentare questa variabile stato in base al tempo trascorso (non dico che è facile).
Qualsiasi delay() o ciclo while()  ti si blocca li.
my name is IGOR, not AIGOR

nico72

Grazie per la celere risposta, guarderò se capisco come sfruttare l'esempio del blink. ma perchè si blocca tutto con la funzione do while ? dalla mia lettura ho capito che esegue l'istruzione contenuta nelle graffe fin quando la condizione nelle tonde è vera ( leggi i secondi dall'avvio del programma se inferiori al dato impostato continua a ripetere l'istruzione ) , quando falsa va avanti, non va così in realtà? devo includere tutto l' if else in un unica istruzione ( case) ? mi sembrava facile così pianificare varie fasi con tempi diversi.

PaoloP

Si blocca perché non aggiorni la variabile time all'interno del ciclo.
Quindi rimane in attesa di un evento che non si verifica, appena si verifica rimane intrappolato perché non diventa mai falso.
Qui (http://forum.arduino.cc/index.php?topic=207407.0) c'è un esempio di un mio progetto dove uso la funzione millis() con uno Switch Case. So che il codice è un po' incasinato. L'ho fatto di fretta.

nico72

Ciao Paolo,
wow , non ho capito nulla del tuo sketch per il momento ...... ho un po di casino in testa troppe info e cose da capire. come faccio a far variare la condizione temp. io credevo che mills restituisse i secondi dall'avvio , non cambiano sempre dunque? manca qualcosa al mio ragionamento.

nid69ita

@nico, uno switch() non è altro che un if multiplo.
L'errore segnalato da @Paolo non lo avevo visto.
Quel che intendo con un case (tipo il codice di @Paolo) è che può aiutare a capire i vari pezzi del codice. Con una variabile di stato sai in quale momento sei del programma. Nel tuo codice manca un qualcosa che faccia capire in quale momento sei.

Per il tuo codice, mi sembra che manchino anche delle graffe.
Questo è il pezzo raffreddamento, giusto? @Paolo ti dice che nel while tu non rileggi mai time=millis()
Code: [Select]
do
{ if (t > 25)
 { digitalWrite(tout, LOW);
   lcd.setCursor(14, 4);
   lcd.print("acceso");
 }
 else
 { digitalWrite(tout, HIGH);
   lcd.setCursor(14, 4);
   lcd.print("spento");
   lcd.setCursor(6, 2);
   lcd.print("Raffreddamento");
 }
 // ma time rimane a quello letto all'inizio!!! ti manca la rilettura di time=millis(); da mettere qui
} while ( time > 60000 );


Poi usata così la millis() non è del tutto corretto, avrai altri problemi. Ma un passo alla volta.
Naturalmente anche negli altri blocchi while hai lo stesso problema.
Ah, la millis() non conta i secondi ma i millisecondi da quando Arduino è acceso
my name is IGOR, not AIGOR

PaoloP

Altrimenti invece di chiamarsi milli s, abbreviazione di milliseconds, si chiamerebbe solo seconds.

nid69ita

#7
Jan 27, 2014, 05:23 pm Last Edit: Jan 27, 2014, 05:36 pm by nid69ita Reason: 1
Qualcosa del genere (aiutami se puoi @Paolo, di sicuro ci infilerò una cavolata) :
Code: [Select]
#include <LiquidCrystal.h>
#include "DHT.h"
#define DHTPIN 8
// 8 è il pin di Arduino a cui collego il sensore di temperatura
#define DHTTYPE DHT11
// dht11 è il tipo di sensore che uso
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// connessione display (pin)
const byte tout = 7;
const byte hout = 6;
unsigned long prevMillis;  // era la tua variabile time
#define K_1H 3600000L
#define K_2H 7200000L
#define K_3H 10800000L
int fase=0;          // 0,1,2,3 fasi

void setup()
{ lcd.begin(20, 4);
 // imposto il tipo di display (colonne, righe)
 lcd.print("Temperatura");
 lcd.setCursor(0,1);
 lcd.print("Umidita'");
 lcd.setCursor(0,2);
 lcd.print("Ciclo");
 lcd.setCursor(0,3);
 lcd.print("Tempo");
 pinMode(tout, OUTPUT);
 pinMode(hout, OUTPUT);
}

void loop()
{ unsigned long currMillis = millis();
 int t = dht.readTemperature();
 int h = dht.readHumidity();
 // posiziono il cursore alla colonna 14 e riga 0
 lcd.setCursor(14, 0);
 lcd.print(t);
 lcd.setCursor(14, 1);
 lcd.print(h);
 switch(fase)
 { case 0: Raffreddamento();  break;
   case 1: Maturazione();     break;
   case 2: PreLievitazione(); break;
   case 3: Lievitazione();    break;
 }  
}

void Raffreddamento()
{ if(currMillis - prevMillis > K_2H)  
 { fase=1;                              // finite le 2 ore passa a Maturazione
   prevMillis = currMillis;
 }
 else                                  // le due ore non sono passate...
 { if (t > 25)  
   { digitalWrite(tout, LOW);
     lcd.setCursor(14, 4);
     lcd.print("acceso");
   }
   else
   { digitalWrite(tout, HIGH);
     lcd.setCursor(14, 4);
     lcd.print("spento");
     lcd.setCursor(6, 2);
     lcd.print("Raffreddamento");
   }
 }
}

void Maturazione()
{ if(currMillis - prevMillis > K_1H)  
 { fase=2;                              // finite le 1 ora passa a Pre-levitazione
   prevMillis = currMillis;
 }
 else  
 {
 }
}

void PreLievitazione()
{ if(currMillis - prevMillis > K_2H)  
 { fase=3;                              // finite le 2 ore passa a levitazione
   prevMillis = currMillis;
 }
 else  
 {
 }
}

void Lievitazione()
{ if(currMillis - prevMillis > K_3H)  
 { fase=0;                              // finite le 3 ore passa a ??? boh, torna a 0 ?
   prevMillis = currMillis;
 }
 else  
 {
 }
}


Di sicuro il tutto non è completo e neppure segue bene il tuo ragionamento.
Anche perchè non sei stato chiarissimo. Ad esempio fase maturazione x ore che vuol dire?
Durante tutte le fasi deve controllare la temperatura ma in ogni fase quali sono i valori ti temperatura da mantenere?
my name is IGOR, not AIGOR

nico72

Si forse per chi non sa di cosa si tratta non si riesce a capire. Devo gestire una cella di lievitazione che ha 4 fasi distinte di produzione.i dati di temp e umidita sono indicativi poi li dovro modificare in base a varie condizioni climatiche Prima fase di raffreddamento durata ore 3 temp 0C.  seconda fase maturazione ore fino a 72 temp 2C umidita 70% . Terza pre-lievitazione ore 2 temp12C umidita 80% ultimafase lievitazione ore 3 temp 28C umidita 90%. Spero di essermi spiegato meglio. Appena posso provero quanto mi avete ggerito.  rimango sempre disponibile ad altri suggerimenti o da chi ha voglia tempo e

nico72

Cavolo di telefono...difficile scrivere. Spero si capisca

nico72

Ecco quello che ho fatto. il programma gira esegue tutto quello che mi serve. Magari non è scritto nella forma più giusta, o è sprecato scritto così, ma per me è già una soddisfazione. Adesso mi servirebbe riuscire a far partire lo sketch alla pressione di un tasto. ho provato guardando lo sketch accendiamo un led con un tasto , ma non mi funziona. come posso compilarlo correttamente? attendo e accetto tutto osservazioni e critiche comprese.
Code: [Select]

#include <LiquidCrystal.h>
#include "DHT.h"
#define DHTPIN 8
// 8 è il pin di Arduino a cui collego il sensore di temperatura
#define DHTTYPE DHT11
// dht11 è il tipo di sensore che uso
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// connessione display (pin)
const int toutraf = 7;
const int toutris = 6;
const int hout = 9;
unsigned long time;

void setup() {
  lcd.begin(20, 4);
  // imposto il tipo di display (colonne, righe)
  lcd.print("Temperatura");
  lcd.setCursor(0,1);
  lcd.print("Umidita'");
  lcd.setCursor(0,2);
  lcd.print("Ciclo");
  lcd.setCursor(0,3);
  lcd.print("Tempo");
  pinMode(toutraf, OUTPUT);
  pinMode(toutris, OUTPUT);
  pinMode(hout, OUTPUT);
  time=millis();
}

void loop() {
  int t = dht.readTemperature();
  int h = dht.readHumidity();
  // posiziono il cursore alla colonna 14 e riga 0
  lcd.setCursor(14, 0);
  lcd.print(t);
  lcd.setCursor(14, 1);
  lcd.print(h);

  do

    if (t > -2)
  {
    digitalWrite(toutraf, HIGH);
    lcd.setCursor(14, 3);
    lcd.print("acceso");
    lcd.setCursor(6, 2);
    lcd.print("Raffreddamento");
    time=millis();
    lcd.setCursor(7,3);
    lcd.print(time / 1000 / 60);
  }

  else
  {
    digitalWrite(toutraf, LOW);
    lcd.setCursor(14, 3);
    lcd.print("spento");
    lcd.setCursor(6, 2);
    lcd.print("Raffreddamento");
    time=millis();
    lcd.setCursor(7,3);
    lcd.print(time / 1000 / 60);
  }
  while ( time < 3600000 );


  do
  {
    if (t > 2)
      if (h < 70)
      {
        digitalWrite(toutraf, HIGH);
        digitalWrite(hout, HIGH);
        lcd.setCursor(14, 3);
        lcd.print("acceso");
        lcd.setCursor(6, 2);
        lcd.print("Maturazione   ");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);

      }
      else
    {
      digitalWrite(toutraf, LOW);
      digitalWrite(hout, LOW);
      lcd.setCursor(14, 3);
      lcd.print("spento");
      lcd.setCursor(6, 2);
      lcd.print("Maturazione   ");
      time=millis();
      lcd.setCursor(7,3);
      lcd.print(time / 1000 / 60);
    }
    if ( t < 2 )
      if (h < 70)
      {
        digitalWrite(toutris, HIGH);
        digitalWrite(hout, HIGH);
        lcd.setCursor(14, 3);
        lcd.print("acceso");
        lcd.setCursor(6, 2);
        lcd.print("Maturazione   ");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);

      }
      else
    {
      digitalWrite(toutris, LOW);
      digitalWrite(hout, LOW);
      lcd.setCursor(14, 3);
      lcd.print("spento");
      lcd.setCursor(6, 2);
      lcd.print("Maturazione   ");
      time=millis();
      lcd.setCursor(7,3);
      lcd.print(time / 1000 / 60);
    }
  }
  while ( time < 21981600 );


  do
  {
    if (t > 13)
      if (h < 80)
      {
        digitalWrite(toutraf, HIGH);
        digitalWrite(hout, HIGH);
        lcd.setCursor(14, 3);
        lcd.print("acceso");
        lcd.setCursor(6, 2);
        lcd.print("Pre-lievitaz.");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }
      else {
        digitalWrite(toutraf, LOW);
        digitalWrite(hout, LOW);
        lcd.setCursor(14, 3);
        lcd.print("spento");
        lcd.setCursor(6, 2);
        lcd.print("Pre-lievitaz.");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }
    if (t < 13)
      if (h < 80)
      {
        digitalWrite(toutris, HIGH);
        digitalWrite(hout, HIGH);
        lcd.setCursor(14, 3);
        lcd.print("acceso");
        lcd.setCursor(6, 2);
        lcd.print("Pre-lievitaz.");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }
      else {
        digitalWrite(toutris, LOW);
        digitalWrite(hout, LOW);
        lcd.setCursor(14, 3);
        lcd.print("spento");
        lcd.setCursor(6, 2);
        lcd.print("Pre-lievitaz.");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }
  }
  while ( time < 220356000  );

  do
  {
    if (t > 28)
      if (h < 85)
      {
        digitalWrite(toutraf, HIGH);
        digitalWrite(hout, HIGH);
        lcd.setCursor(14, 3);
        lcd.print("acceso");
        lcd.setCursor(6, 2);
        lcd.print("Lievitazione ");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }
      else {
        digitalWrite(toutraf, LOW);
        digitalWrite(hout, LOW);
        lcd.setCursor(14, 3);
        lcd.print("spento");
        lcd.setCursor(6, 2);
        lcd.print("Lievitazione ");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }

    if (t < 28)
      if (h < 85)
      {
        digitalWrite(toutris, HIGH);
        digitalWrite(hout, HIGH);
        lcd.setCursor(14, 3);
        lcd.print("acceso");
        lcd.setCursor(6, 2);
        lcd.print("Lievitazione ");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }
      else {
        digitalWrite(toutris, LOW);
        digitalWrite(hout, LOW);
        lcd.setCursor(14, 3);
        lcd.print("spento");
        lcd.setCursor(6, 2);
        lcd.print("Lievitazione ");
        time=millis();
        lcd.setCursor(7,3);
        lcd.print(time / 1000 / 60);
      }

  }
  while ( time < 231156000 );
  lcd.clear();
  lcd.setCursor(4, 2);
  lcd.print("FINE PROGRAMMA");
  while(1) {
  }

}























Go Up