funzione millis problema!!!

Riesco a scandire il tempo... mi servirebbe, però un modo per aspettare dopo che si è generata una condizione..... lo scrivo nel codice che è meglio!!!!

unsigned long time;
byte secondi = 60;
int stato = 0;

void setup(){
  Serial.begin(9600);
  time = millis(); // Prendo il tempo
  }
  
  void loop(){
    if(millis()>=time+1000){   // Scandisco i secondi
      secondi--;
      if (secondi==0){
         secondi=60; 
mettere qualcosa del tipo if(millis aspetto 10secondi){
         stato=1;}
         }
        
     if(millis()>=time+1000){
      Serial.println(secondi);
      Serial.println("");
      Serial.print(stato);}
     time=millis();   
        }
        }

spero di essere stato chiaro Grazie

Ciao, ti consiglio la lettura di questo mio articolo, spiego come eseguire più compiti senza bloccare il codice: http://www.leonardomiliani.com/2013/programmiamo-i-compiti-con-millis/

Nell'esempio allegato ogni 100 ms faccio lampeggiare un led mentre ogni 1000 ms stampo un contatore

Tipo questo?

unsigned long time;
unsigned long starttime;
boolean on = false;
byte secondi = 60;
int stato = 0;

void setup(){
  Serial.begin(9600);
  time = millis(); // Prendo il tempo
}

void loop(){
  if(millis()>=time+1000){   // Scandisco i secondi
    secondi--;
    if (secondi <= 0){
      secondi=60; 
      on = true; // fa partire il conteggio di 10 secondi
      starttime = millis();
    }

    if(millis()>=time+1000){
      Serial.println(secondi);
      Serial.println("");
      Serial.print(stato);
    }
    time=millis();   
  }

  if (on){
    if(millis() - starttime >= 10000){
      stato=1;
      on = false; // disattiva il conteggio
    }
  }
}

Spiega per bene cosa ti serve… :wink:

Ciao Ragazzi, ho anch’io un problema con il millis(), non voglio intromettermi nell’argomento così brutalmente quindi se non è consono i moderatori sono liberissimi di cancellare o spostare la mia risposta/richiesta.

in soldoni, dopo aver letto svariati modi di utilizzare il millis() ed evitare l’overflow, il risultato migliore per il mio programma l’ho ottenuto seguendo la piccola guida di Leonardo (Milani):

Vi spiego in breve (anche se credo di essere stato abbastanza chiaro nel codice): ovviamente il problema si pone perchè cerco di lavorare in multitasking. Una parte del programma si occupa di gestire una ventola (fanr) in funzione di un delta Temp (fra due sensori: quello nel DTH11 (h) e un DS18B20 -sensors.getTempCByIndex(0) ). Intanto che il programma esegue questo semplice comando deve rilevare la temperatura media fra i due sensori e nel caso A (temp < di 21°) accende una resistenza e una ventola, nel caso B (temp >= a 21°) spegne la resistenza e esegue un ciclo (quello che vorrei gestire con il millis() ) che consiste nell’accendere una ventola (vent) per una durata di 10s e tenerla spenta per una durata di 30s. Caricando il programma che segue verificando le condizioni, scopro che nel caso A resistenza e ventola si accendono (beh li è facile), nel caso B la resistenza si spegne, la ventola rimane accesa per un tempo sicuramente maggiore di 10s (all’incirca 12) e rimane spenta forse per 3/5s… Perdonatemi se dal codice si evince qualche errore stupido ma sono proprio agli inizi, mi troverei più a mio agio a revisionare una turbina della macchina da bendato con una mano legata dietro la schiena e un gatto che si fà le unghie sulla mia gamba (non so se rendo l’idea) :stuck_out_tongue:

// Definizione Temperatura e Umidità impostata:

#define imptemp 21
#define imphum 50

//SENSORE DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>

//SENSORE DHT11
#include "DHT.h"
#define DHTPIN 6     // what pin we're connected to
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);

//UTENZE

int fanr = 10; //Ventola piccola ricircolo
int ledr = 11; //Led Rosso
int ledg = 8; //Led Verde
int ledb = 12; //Led Blu
int res = 4; // resistenza
int vent = 7; //ventola
int pompa = 5; //ventola
int evap = 2; //evaporatore

// Il terminale data del sensore è connesso alla porta 9 di Arduino
#define ONE_WIRE_BUS 9

// Imposta la comunicazione oneWire per comunicare con un dispositivo compatibile
OneWire oneWire(ONE_WIRE_BUS);

// Passaggio oneWire reference alla Dallas Temperature. 
DallasTemperature sensors(&oneWire);


extern unsigned long timer0_millis;

unsigned long previousMillis1 = 0; //will store last time vent was updated
unsigned long interval1 = 10000; //interval accensione ventola
unsigned long previousMillis2 = 0;
unsigned long interval2 = 30000;
unsigned int counter = 0;


void setup()
{

// Avvio librerie
sensors.begin();
Serial.begin(9600);



// definizione INPUT e OUTPUT
pinMode(fanr, OUTPUT); 
pinMode(ledr, OUTPUT); 
pinMode(ledg, OUTPUT);
pinMode(ledb, OUTPUT);
pinMode(res, OUTPUT);
pinMode(vent, OUTPUT);
pinMode(pompa, OUTPUT);
pinMode(evap, OUTPUT);

}

oid loop()
{ 
  
  float h = dht.readHumidity(); //Valore Umidità DHT11
  float tb = dht.readTemperature(); //Valore temperatura DHT11
  sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura al sensore DS18B20

  
//se deltaT fra T1 e T2 è compreso frà -50 e 2° la ventola è al 10% e il led blu è acceso
  if ((sensors.getTempCByIndex(0) - tb) >=-50 && (sensors.getTempCByIndex(0) - tb) <=2 ) {
  analogWrite(fanr, 40);
  digitalWrite(ledb,HIGH);
  digitalWrite(ledr,LOW);
  digitalWrite(ledg,LOW);
  }
  
    //se deltaT fra T1 e T2 è compreso frà 2° e 5° la ventola è al 50% e il led verde è acceso
  if ((sensors.getTempCByIndex(0) - tb) >=2 && (sensors.getTempCByIndex(0) - tb) <=5 )
  {
  analogWrite(fanr, 127);
  digitalWrite(ledg,HIGH);
  digitalWrite(ledr,LOW);
  digitalWrite(ledb,LOW);
  }
  
  //se deltaT fra T1 e T2 è maggiore di 5° la ventola è al 100% e il led rosso è acceso
  if ((sensors.getTempCByIndex(0) - tb) >5 )
  {
  analogWrite(fanr, 255);
  digitalWrite(ledr,HIGH);
  digitalWrite(ledb,LOW);
  digitalWrite(ledg,LOW);
  }
 
  
  Serial.print("Tempo: ");
  Serial.println (millis()/1000);
  
  Serial.print("media: ");
  Serial.println ((sensors.getTempCByIndex(0) + tb)/2); // media
  
 
  

if (((sensors.getTempCByIndex(0) + tb)/2) <imptemp)  //se la temperatura media è minore di quella impostata (imptemp) parte la ventola e la resistenza
  {
  digitalWrite(res, HIGH);
  digitalWrite(vent,HIGH);
  }
  

 
  if (((sensors.getTempCByIndex(0) + tb)/2) >= imptemp) //se la temperatura media è maggiore/uguale a quella impostata (imptemp) parte la ventola per 10s e rimane spenta 30s, la resistenza è spenta
  {
    
// la resistenza si spegne    
  digitalWrite(res, LOW);
  
//nelle condizioni di cui sopra la ventola si accende per 10sec (interval1 10000)
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis1 > interval1) 
  {
    previousMillis1 = currentMillis; 
    digitalWrite(vent,HIGH);
   }
   
  //nelle condizioni di cui sopra la ventola rimane spenta per 30sec (interval1 20000)
  
  currentMillis = millis();
  if (currentMillis - previousMillis2 > interval2) 
  {
    previousMillis2 = currentMillis;
   digitalWrite(vent,LOW);
  }
  
 }
}

PS: ci sarebbe un’altra parte di codice che gestisce altre funzioni in funzione dell’umidità e risolve l’overflow (dato che è un sistema che rimane acceso 24h su 24, ma per ora mi interessa risolvere la questione millis(), il resto lo risolvo di conseguenza.

Grazie mille,

a presto!

Tu la fai semplice ma in realtà non è così semplice ;) Hai bisogno di 2 variabili di stato in cui salvare quello che stai eseguendo in un certo momento e lo stato della ventola. Nella prima variabile devi salvare se sei nel periodo di accensione o di disattivazione della ventola, mentre nella seconda salvi lo stato della ventola stessa.

Ricapitoliamo: 1) controlli la temperatura 2) se >= X, allora controlli se devi accendere o spengere la ventola 3) se devi accenderla, controlli se è spenta 4a) se è spenta, la accendi e memorizzi lo stato, poi aggiorni l'operazione 4b) se è accesa prosegui 5) se devi spengerla, controlli se è accesa 6a) se è accesa, la spengi e memorizzi il suo stato, poi aggiorni l'operazione 6b) se è spenta prosegui

Grazie mille Leonardo, immaginavo riguardasse proprio la logica del processo. Tendo sempre a farle più semplici di quello che sono!

Ora in qualche buco di tempo oggi metto giù un diagramma di flusso con i tuoi suggerimenti e provo a rileggere il tuo tutorial, così dovrei schiarirmi le idee. Magari vi allego poi il diagramma di flusso così vediamo se almeno la logica riesco a sistemarla (anche se praticamente hai espresso esattamente lo scopo del programma). 8)

Scusa pas600 se mi sono intromesso ma spero possa essere d’aiuto anche la discussione sul mio problema!

Ciao Leonardo, grazie ai tuoi consigli e con qualche accorgimento ho risolto, anche se penso che sia possibilissimo risolvere la cosa in maniera brillante alleggerendo il codice… :sweat_smile: penso di aver fatto dei giri che si potranno sicuramente risolvere con qualche comando specifico che non conosco :stuck_out_tongue:

// Definizione Temperatura e Umidità impostata:

#define imptemp 21
#define imphum 50

//SENSORE DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>

//SENSORE DHT11
#include "DHT.h"
#define DHTPIN 6     // what pin we're connected to
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);

//UTENZE

int fanr = 10; //Ventola piccola ricircolo
int ledr = 11; //Led Rosso
int ledg = 8; //Led Verde
int ledb = 12; //Led Blu
int res = 4; // resistenza
int vent = 7; //ventola
int pompa = 5; //ventola
int evap = 2; //evaporatore


// Il terminale data del sensore è connesso alla porta 9 di Arduino
#define ONE_WIRE_BUS 9

// Imposta la comunicazione oneWire per comunicare con un dispositivo compatibile
OneWire oneWire(ONE_WIRE_BUS);

// Passaggio oneWire reference alla Dallas Temperature. 
DallasTemperature sensors(&oneWire);


extern unsigned long timer0_millis;

int ventState = LOW;

unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
unsigned long interval1 = 15000; 
unsigned long interval2 = 50000; 
unsigned int counter = 0;



void setup()
{

// Avvio librerie
sensors.begin();
Serial.begin(9600);



// definizione INPUT e OUTPUT
pinMode(fanr, OUTPUT); 
pinMode(ledr, OUTPUT); 
pinMode(ledg, OUTPUT);
pinMode(ledb, OUTPUT);
pinMode(res, OUTPUT);
pinMode(vent, OUTPUT);
pinMode(pompa, OUTPUT);
pinMode(evap, OUTPUT);
 


}



void loop()
{ 
  
  float h = dht.readHumidity(); //Valore Umidità DHT11
  float tb = dht.readTemperature(); //Valore temperatura DHT11
  sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura al sensore DS18B20

  
//se deltaT fra T1 e T2 è compreso frà -50 e 2° la ventola è al 10% e il led blu è acceso
  if ((sensors.getTempCByIndex(0) - tb) >=-50 && (sensors.getTempCByIndex(0) - tb) <=2 ) {
  analogWrite(fanr, 40);
  digitalWrite(ledb,HIGH);
  digitalWrite(ledr,LOW);
  digitalWrite(ledg,LOW);
  }
  
    //se deltaT fra T1 e T2 è compreso frà 2° e 5° la ventola è al 50% e il led verde è acceso
  if ((sensors.getTempCByIndex(0) - tb) >=2 && (sensors.getTempCByIndex(0) - tb) <=5 )
  {
  analogWrite(fanr, 127);
  digitalWrite(ledg,HIGH);
  digitalWrite(ledr,LOW);
  digitalWrite(ledb,LOW);
  }
  
  //se deltaT fra T1 e T2 è maggiore di 5° la ventola è al 100% e il led rosso è acceso
  if ((sensors.getTempCByIndex(0) - tb) >5 )
  {
  analogWrite(fanr, 255);
  digitalWrite(ledr,HIGH);
  digitalWrite(ledb,LOW);
  digitalWrite(ledg,LOW);
  }
 
  /*
  Serial.print("Tempo: ");
  Serial.println (millis()/1000);
  
  Serial.print("media: ");
  Serial.println ((sensors.getTempCByIndex(0) + tb)/2); // media
  */
 
  

if (((sensors.getTempCByIndex(0) + tb)/2) <imptemp)  //se la temperatura media è minore di quella impostata (imptemp) parte la ventola e la resistenza
  {
  digitalWrite(res, HIGH);
  digitalWrite(vent,HIGH);
  }
  

 
  if (((sensors.getTempCByIndex(0) + tb)/2) >= imptemp) //se la temperatura media è maggiore/uguale a quella impostata (imptemp) parte la ventola per 15s e rimane spenta 50s, la resistenza è spenta
  {
  // la resistenza si spegne    
  digitalWrite(res, LOW);
  
   //dico alla ventola di seguire lo stato iniziale (int ventState = LOW;)
  digitalWrite(vent,ventState);  
  


  // prendo il tempo
  unsigned long currentMillis = millis();
  
  //se il delta tempo è maggiore dell'interval1 (15s) e la ventola è accesa
  if ((currentMillis - previousMillis1 > interval1) && (ventState == HIGH)) 
  {
  //azzera i contatori
  previousMillis1 = currentMillis;
  previousMillis2 = currentMillis; 
 //se la ventola è accesa spegnila 
  if (ventState == HIGH)// <---sembrerebbe necessario, se lo tolgo non funziona; anche se a rigor di logica viene da pensare che se il programma arriva qui il ventState è per forza == HIGH
  ventState = LOW;
// scrivi lo stato della ventola
  digitalWrite(vent,ventState);
  }
  
  // prendo il tempo
  currentMillis = millis();
  
  //se il delta tempo è maggiore dell'interval2 (50s) e la ventola è spenta
  if ((currentMillis - previousMillis2 > interval2) && (ventState == LOW))
  {
  //azzera i contatori
  previousMillis1 = currentMillis;
  previousMillis2 = currentMillis;
  
  //se la ventola è spenta accendila
  if (ventState == LOW) // <---sembrerebbe necessario, se lo tolgo non funziona; anche se a rigor di logica viene da pensare che se il programma arriva qui il ventState è per forza == LOW
  ventState = HIGH;
  
  // scrivi lo stato della ventola
  digitalWrite(vent,ventState);
  }
  
  
  
 //lettura stato ventola
  Serial.print("ventState: ");
  Serial.println (ventState);
  
  //letture differenze di tempo
  Serial.print("T1: ");
  Serial.println ((currentMillis - previousMillis1)/1000);
  Serial.print("T2: ");
  Serial.println ((currentMillis - previousMillis2)/1000);
  
 }
 //lettura Temperatura media
 Serial.print("Tmedia: "); 
 Serial.println ((sensors.getTempCByIndex(0) + tb)/2);
}

Ho dato una aggiustatina.

// Definizione Temperatura e Umidità impostata:
const int imptemp = 21;
const int imphum = 50;

//SENSORE DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>

//SENSORE DHT11
#include "DHT.h"
#define DHTPIN 6     // what pin we're connected to
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);

//UTENZE
const int fanr = 10; //Ventola piccola ricircolo
const int ledr = 11; //Led Rosso
const int ledg = 8; //Led Verde
const int ledb = 12; //Led Blu
const int res = 4; // resistenza
const int vent = 7; //ventola
const int pompa = 5; //ventola
const int evap = 2; //evaporatore

// Il terminale data del sensore è connesso alla porta 9 di Arduino
#define ONE_WIRE_BUS 9

// Imposta la comunicazione oneWire per comunicare con un dispositivo compatibile
OneWire oneWire(ONE_WIRE_BUS);

// Passaggio oneWire reference alla Dallas Temperature.
DallasTemperature sensors(&oneWire);

// extern unsigned long timer0_millis;

boolean ventState = LOW;

unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const unsigned long interval1 = 15000;
const unsigned long interval2 = 50000;
unsigned int counter = 0;

void setup() {
  // Avvio librerie
  sensors.begin();
  Serial.begin(9600);

  // definizione INPUT e OUTPUT
  pinMode(fanr, OUTPUT);
  pinMode(ledr, OUTPUT);
  pinMode(ledg, OUTPUT);
  pinMode(ledb, OUTPUT);
  pinMode(res, OUTPUT);
  pinMode(vent, OUTPUT);
  pinMode(pompa, OUTPUT);
  pinMode(evap, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis(); // prendo il tempo

  const float H = dht.readHumidity(); //Valore Umidità DHT11
  const float Tdht = dht.readTemperature(); //Valore temperatura DHT11

  sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura al sensore DS18B20
  const float Tds = sensors.getTempCByIndex(0);
  const float Delta = Tds - Tdht;
  const float Media = (Tds + Tdht) / 2;

  //se deltaT fra T1 e T2 è compreso frà -50 e 2° la ventola è al 10% e il led blu è acceso
  if (Delta >= -50 && Delta < 2 ) {
    SetFanLed(16, LOW, LOW, HIGH);
  }
  else
    //se deltaT fra T1 e T2 è compreso frà 2° e 5° la ventola è al 50% e il led verde è acceso
    if (Delta >= 2 && Delta <= 5 )
    {
      SetFanLed(50, LOW, HIGH, LOW);
    }
    else
      //se deltaT fra T1 e T2 è maggiore di 5° la ventola è al 100% e il led rosso è acceso
      if (Delta > 5 )
      {
        SetFanLed(100, HIGH, LOW, LOW);
      }

  /*
  Serial.print("Tempo: ");
  Serial.println (millis()/1000);

  Serial.print("media: ");
  Serial.println ((sensors.getTempCByIndex(0) + tb)/2); // media
  */

  //se la temperatura media è minore di quella impostata (imptemp) parte la ventola e la resistenza
  if (Media < imptemp)
  {
    digitalWrite(res, HIGH);
    digitalWrite(vent, HIGH);
  }
  else
    //se la temperatura media è maggiore/uguale a quella impostata (imptemp) parte la ventola per 15s e rimane spenta 50s, la resistenza è spenta
  {
    //se il delta tempo è maggiore dell'interval1 (15s) e la ventola è accesa
    if ((ventState == HIGH) && (currentMillis - previousMillis1 > interval1))
    {
      //azzera i contatori
      previousMillis1 = currentMillis;
      previousMillis2 = currentMillis;
      ventState = LOW;
    }

    //se il delta tempo è maggiore dell'interval2 (50s) e la ventola è spenta
    if ((ventState == LOW) && (currentMillis - previousMillis2 > interval2))
    {
      //azzera i contatori
      previousMillis1 = currentMillis;
      previousMillis2 = currentMillis;
      ventState = HIGH;
    }

    digitalWrite(res, LOW); // la resistenza si spegne
    digitalWrite(vent, ventState);

    //lettura stato ventola
    Serial.print("ventState: ");
    Serial.println (ventState);

    //letture differenze di tempo
    Serial.print("T1: ");
    Serial.println ((currentMillis - previousMillis1) / 1000);
    Serial.print("T2: ");
    Serial.println ((currentMillis - previousMillis2) / 1000);
  }

  //lettura Temperatura media
  Serial.print("Tmedia: ");
  Serial.println (Media, 1);
}// End Loop

void SetFanLed(int fanperc, int Red, int Green, int Blue)
{
  analogWrite(fanr, fanperc * 2.55);
  digitalWrite(ledr, Red);
  digitalWrite(ledb, Blue);
  digitalWrite(ledg, Green);
}

Controlla se funziona. :grin:
Se devi modificare tramite pulsanti temperatura e umidità, togli il const. Altrimenti il compilatore si arrabbia.

Ti ringrazio PaoloP! :) Stasera vado a casa e butto un occhio, così imparo qualcosa di nuovo, anche perchè devo implementare la parte di gestione dell'umidificatore.

Se devi modificare tramite pulsanti temperatura e umidità, togli il const. Altrimenti il compilatore si arrabbia.

Immaginavo, per ora la gestione temperatura e umidità sarà fissata con parametri costanti pre-caricati sul programma, poi sulla macchina definitiva implementerò un piccolo LCD con i tasti in modo da poter cambiare qualche impostazione.

Poi stasera ti dò un feedback del programma.

Intanto GRAZIE! 8) XD

Controlla se funziona. smiley-mr-green

Provato adesso, funziona alla grande!

ho imparato anche qualche trucchetto "void(SetFanLed) " :P grazie,

e con assoluto piacere vedo che non hai modificato i millis che erano gli unici che mi inquietavano, mi hai corretto le letture e le medie dei sensori semplificando i termini (GRAZIE! :P)

mi hai aggiunto come già detto il SetFanLed che semplifica la scrittura degli stati ventola e led (i led molto probabilmente verranno tolti quando implementerò lo schermo LCD :-P comunque mi piace come l'hai gestito)

ti chiederei solo una cortesia (proprio se e quando hai tempo e soprattutto se hai voglia): mi scriveresti un commentino a fianco alla modifica in modo che possa capire il perchè di alcune modifiche (tipo il boolean ventState = LOW;)

chiudo qui perchè mi sà che sto andando offtopic :P

Grazie ancora Leo e Paolo, magari domenica vi faccio il filmato di ciò che è saltato fuori se domani tra un tagliando e una commissione riesco a scrivere la parte sulla gestione umidità!

visto che il linguaggio di programmazione di Arduino è il C ed il C++. Ti consiglio di procurarti qualche guida su questi linguaggi.
Inizia dal C.
Nella sezione Megatopic trovi un topic “link utili” dagli uno sguardo.

Il tipo boolean in Arduino a differenza dell’int occupa solo un byte di memoria.
Visto che la variabile può contenere solo due valori (HIGH e LOW) è uno spreco di memoria. :wink:

Perdonami ma ho scritto il codice modificandolo di getto e per recuperare le modifiche dovrei confrontare i due listati perché nel mentre ho risposto ad altri 30 post e non ricordo le modifiche fatte. :wink:

Fai le domante sui passaggi più oscuri.