Timer

Sto cercando di scrivere il codice di un timer senza delay che non mi blocchi il mondo mentre è in esecuzione!

int offset = millis()/1000;
void setup(){
  Serial.begin(9600);
  Serial.println("Counter ");

}

void loop()
{
 counter(10);
 
}

void counter (int time){
  int timer=0;
  timer = time - (millis()/1000-offset);
  Serial.println(timer);
  if(timer ==0){
    digitalWrite(13,HIGH);
    timer =0;
  }
}

l'idea era quella di leggere millis() all'inizio e sottrarlo al valore di millis al tempo in cui chiamo la funzione. in questo modo ho il valore assoluto del tempo della durata della funzione. Decremento quindi la variabile time della durata dell'esecuzione della funzione e ottengo un conteggio alla rovescia. Più facile a farsi che a dirsi, però il problema è che mi sfora. Ho provato a mettere dei cicli while, condizioni con if else nulla... non c'è verso di fermare il conteggio se non resettando arduino! avete idee migliori? è anche vero che io potrei settarmi il timer quando finisce lui mi accende il led e il suo lavoro sarebbe finito lì! però è leggermente scomodo... anche se boh, si può lavorare anche così no?

questo codice andrà nel timer per il bromografo... devo sempre creare il menù del display, ho ricablato tutta la tastierina quindi userò quella per navigare nel menù. sarà una figata :smiley:

Comunque con questo codice io metto la mia basetta, fotoincido, lui conta alla rovescia arriva a 0 stacca i neon e devo resettare per fotoincidere di nuovo... boh... potrebbe andare?

secondo me

millis()/1000

non ha senso, se ti servono i microsecondi c'è la funzione micros()

Federico, millis()/1000 dovrebbe restituire i secondi, non i microsecondi, perchè se hai ad esempio millis()=1300, lo dividi per 1000 e viene 1.3 secondi!

syn

Federico, millis()/1000 dovrebbe restituire i secondi, non i microsecondi, perchè se hai ad esempio millis()=1300, lo dividi per 1000 e viene 1.3 secondi!

syn

già infatti!

ops! Giusto!!!! che prila, vabbè perdonatemi! ;D
...ecco perchè non aveva senso XD

Secondo me, se ho ben capito il problema, ti conviene scrivere un codice un po' più versatile, in modo da poter avviare il conteggio più volte consecutive, e mettere della logica di controllo nel loop principale (per esempio vedere se un interruttore è aperto o chiuso) per decidere cosa fare dal momento che il counter raggiunge lo zero. In questo modo puoi fermarti del tutto o aspettare un po' e far partire di nuovo il bromografo solo modificando l'interruttore! Dovrebbe essere fattibile!

syn

eh si ora provo a fare un circuitino... magari scrivo uno pseudo menù. potrebbe essere utile esporre con 2 neon invece di 4? perchè 2 relee li devo mettere in tutti i modi solo che posso decidere di pilotarli sia singolarmente che contemporaneamente! poi mi dovrebbe avanzare un pin eventualmente per un buzzer o cose del genere!

Per quello lascio la parola ai più esperti... comunque ti consiglio di scrivere il codice, fare un circuitino di test con qualche led e interruttore, poi se tutto funziona ci metti un attimo a collegare i relè!

sisi ho avuto un attimo da uscire ma ora mi metto a costruirlo!

@Federico Vanzati, il tuo codice per il menù degli lcd crystal è fantastico.. solo che lo sto riadattando alle mie esigenze...
ora come ora sto studiando la libreria metro ma non è che sia comodissima... ora provo in questo codice che è abbastanza a stati finiti, prima l'ho provata in un loop! vediamo uhuhu

ecco il codice senza il timer implementato è un po' allo scazzo ahahah

#include <LiquidCrystal.h>
#include <Tone.h>
Tone notePlayer;
int ledPin = 5;
#define ENTER  0  //Pin a cui e' collegato il tasto enter
#define ESC  1  //Pin a cui e' collegato il tasto esc
#define PIU  2  //Pin a cui e' collegato il tasto piu
#define MENO 3  //Pin a cui e' collegato il tasto meno
#define SHIFT 4 // Pin a cui e' collegato il tasto shifta
#define BACKLIGHT 6  //Pin (PWM) usato per regolare la retroilluminazione
boolean piu = HIGH, meno = HIGH, enter, esc;  //Variabili associate ai quattro pulsanti nella modalita' scorrimento pagine
boolean piu_set = HIGH, meno_set = HIGH, shift_set = HIGH;  //Variabili associate ai quattro pulsanti nella modalita' settaggio
boolean set = LOW;  //Entra nella modalita' settaggio
unsigned int n_piu, n_meno, n_shift;  //Conta quante volte vengono premuti i tasti piu e meno
unsigned int cont_pag = 0;  //Identificativo della pagina da visualizzare
/*========================================================================== Variabili di temporizzazione =======================================================================*/
long tempo_btn = 0, debounce = 300;  //Tempo tra due letture successive di un bottone (300 ms)
long tempo_home = 0, back_home = 300000;  //Trascorsi 5 minuti (300000 secondi) si torna alla schermata principale
long tempo_backlight = 0, delay_backlight = 120000;  //Trascorsi 120 secondi da quando non vengono premuti tasti si spegne la retroilluminazione
/*===============================================================================================================================================================================*/

LiquidCrystal lcd(7,8,9,10,11,12);


void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.clear();
  notePlayer.begin(13);
  pinMode(BACKLIGHT, OUTPUT);

}
void loop(){
backlight();

  enter = analogRead(ENTER);
  esc = analogRead(ESC);

  if(set == LOW)
  {
    piu = analogRead(PIU);
    meno = analogRead(MENO);
  }

  if(piu == LOW && millis() - tempo_btn > debounce && cont_pag >= 0 && cont_pag < 6)
  {
    tempo_btn = millis();
    cont_pag++;
    if(cont_pag == 6)
      cont_pag = 0;
  }

  if(meno == LOW && millis() - tempo_btn > debounce && cont_pag > 0 && cont_pag < 6)
  {
    tempo_btn = millis();
    cont_pag--;
  }

  if(esc == LOW && millis() - tempo_btn > debounce)  //Quando premo "esc" torno alla schermata HOME
  {
    tempo_btn = millis();
    cont_pag = 0;
    set = LOW;
  }

  switch (cont_pag)
  {
  case 0:    //Schermata Presentazione && Test
  lcd.println("CALAMARO");
  presentazione_truzza();
  break;

  case 1:
        lcd.println("TIMER");
         lcd.clear();
      break;

  case 2:   // Schermata Impostazione TInverno
    lcd.setCursor(0,0);
    lcd.print("IMPOSTA TIMER");
    if(enter == LOW && millis() - tempo_btn > debounce)  //Premendo "enter" si entra nella sotto-modalita'
    {
      tempo_btn = millis();
      set = !set;
    }

    if(set == HIGH)
    {   
      //Abilita l'ingresso in modalita' configurazione
      n_piu = 0;
      n_meno = 0;
        n_shift = 0;
      //Abilita i tasti "piu" e "meno" in modalita' incremento/decremento
      piu_set = analogRead(PIU);
      meno_set = analogRead(MENO);
        shift_set = analogRead(SHIFT);
        
      if(piu_set == HIGH && millis() - tempo_btn > debounce)  //Incremento "variabile" se premo tasto "piu"
      {
        tempo_btn = millis();
        n_piu++;
        piu_set = !piu_set;
        // if( variabile < valore1 )
        // Incremento variabile
      }

      if(meno_set == HIGH && millis() - tempo_btn > debounce)  //Decremento "variabile" se premo tasto "meno"
      {
        tempo_btn = millis();
        n_meno++;
        meno_set = !meno_set;
        //  if( variabile > valore2 )
        // Deceremento variabile
      }
      if(shift_set == HIGH && millis() - tempo_btn > debounce){  //Aumento shift se lo tengo premuto
        lcd.setCursor(0,n_shift);
        lcd.noCursor();
        delay(500);
         // Turn on the cursor:
        lcd.cursor();
        delay(500);
        n_shift +=1;
        if(n_shift == 3) n_shift =0;
        }
    }
lcd.clear();
    break;

  case 3:
        lcd.print("Case 3"); //non implementato per ora
        delay(125);
    // codice pag nr. 3
        lcd.clear();
      break;

  case 4:
        lcd.print("Case 4"); //non implementato per ora
    //codice pag nr. 4
      delay(125);
      lcd.clear();
      fading();
      break;

  case 5:
        lcd.print("Case 5"); // non implementato per ora
        // codice p$ag nr.5
        delay(125);
        lcd.clear();
      break;

  }
}
void fading(){
  {
  int a=0;
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=1) { 
     if(fadeValue%64==0){
           if(a%2==0){
            notePlayer.play(NOTE_A2);
            a+=1;
            }
            else {   
            notePlayer.stop();
            a+=1;
       }
    }
    analogWrite(ledPin, fadeValue);         
    delay(5);
   } 

  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1) { 
     if(fadeValue%64==0){
           if(a%2==0){
            notePlayer.play(NOTE_A2);
            a+=1;
            }
            else {   
            notePlayer.stop();
            a+=1;
       }
    }
    analogWrite(ledPin, fadeValue);         
    delay(5);
      } 
    }
}
void backlight()
{
  boolean b1, b2, b3, b4;

  b1 = analogRead(PIU);
  b2 = analogRead(MENO);
  b3 = analogRead(ENTER);
  b4 = analogRead(ESC);


  if( b1 == LOW || b2 == LOW || b3 == LOW || b4 == LOW )
  {
    digitalWrite(BACKLIGHT, HIGH);
  }
  if( millis() - tempo_home > back_home )
  {
    tempo_home = millis();
    digitalWrite(BACKLIGHT, LOW);
  }
  if( millis() - tempo_backlight > delay_backlight )
  {
    tempo_backlight = millis();
    set = LOW;
    cont_pag = 0;
  }
}  

void presentazione_truzza(){
  for (int positionCounter = 0; positionCounter < 8; positionCounter++) {
    int fadeValue = map(positionCounter, 0,7,0,255);
    analogWrite(ledPin, fadeValue);
    analogWrite(BACKLIGHT, fadeValue);
    lcd.scrollDisplayRight(); 
    delay(250);
  }   
    for (int positionCounter = 0; positionCounter < 8; positionCounter++) {
    int fadeValue = map(positionCounter, 0,7, 255, 0);
    analogWrite(ledPin, fadeValue);
    analogWrite(BACKLIGHT, fadeValue);
    lcd.scrollDisplayLeft(); 
    delay(250);
  }
}

no via la presentazione_truzza è talmente truzza che va tolta!

Grande!
Sono sotto esami ed ho poco tempo libero in queste settimane, però sto cercando di fare una funzione per implementare i sottomenù, anche se c'è sempre qualcosa che non va!!

Se migliori qualcosa o inventi qualche funzione carina fammi sapere, magari poi trasformiamo tutto in libreria e sarà utile in tanti progetti :wink:

io sarei contento se riuscissi a fare un timer!

#include <LiquidCrystal.h>
#include <Tone.h>
#include <Metro.h>
int timer = 0;
Tone notePlayer;
Metro contatore = Metro(250); 
int ledPin = 5;
#define ENTER  0  //Pin a cui e' collegato il tasto enter
#define ESC  1  //Pin a cui e' collegato il tasto esc
#define PIU  2  //Pin a cui e' collegato il tasto piu
#define MENO 3  //Pin a cui e' collegato il tasto meno
#define SHIFT 4 // Pin a cui e' collegato il tasto shifta
#define BACKLIGHT 6  //Pin (PWM) usato per regolare la retroilluminazione

boolean piu = HIGH, meno = HIGH, enter, esc;  //Variabili associate ai quattro pulsanti nella modalita' scorrimento pagine
boolean piu_set = HIGH, meno_set = HIGH, shift_set = HIGH;  //Variabili associate ai quattro pulsanti nella modalita' settaggio
boolean set = LOW;  //Entra nella modalita' settaggio
unsigned int n_piu, n_meno, n_shift;  //Conta quante volte vengono premuti i tasti piu e meno
unsigned int cont_pag = 0;  //Identificativo della pagina da visualizzare
/*========================================================================== Variabili di temporizzazione =======================================================================*/
long tempo_btn = 0, debounce = 200;  //Tempo tra due letture successive di un bottone (300 ms)
long tempo_home = 0, back_home = 300000;  //Trascorsi 5 minuti (300000 secondi) si torna alla schermata principale
long tempo_backlight = 0, delay_backlight = 120000;  //Trascorsi 120 secondi da quando non vengono premuti tasti si spegne la retroilluminazione
/*===============================================================================================================================================================================*/

LiquidCrystal lcd(7,8,9,10,11,12);


void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.clear();
  notePlayer.begin(13);
  pinMode(BACKLIGHT, OUTPUT);

}
void loop(){
backlight();
menu();

  switch (cont_pag)
  {
  case 0:
    lcd.setCursor(0,0);
    lcd.print("Home");
    lcd.setCursor(0,1);
    lcd.print("premi ");
    delay(100);
    lcd.clear();
  break;

  case 1:
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("setta il timer");
  lcd.setCursor(0,1);
  lcd.print(settimer());
    delay(100);
  break;

  case 2:
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Timer");
    lcd.setCursor(0,1);
    lcd.print(timer);
    if(contatore.check()==1) fading();
  break;

  case 3:
  break;

  case 4:
  break;

  case 5:
  break;

    }
  }


void fading(){
  {
  int a=0;
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=1) { 
     if(fadeValue%64==0){
           if(a%2==0){
            notePlayer.play(NOTE_A2);
            a+=1;
            }
            else {   
            notePlayer.stop();
            a+=1;
       }
    }
    analogWrite(ledPin, fadeValue);         
    delay(5);
   } 

  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=1) { 
     if(fadeValue%64==0){
           if(a%2==0){
            notePlayer.play(NOTE_A2);
            a+=1;
            }
            else {   
            notePlayer.stop();
            a+=1;
       }
    }
    analogWrite(ledPin, fadeValue);         
    delay(5);
      } 
    }
}
void backlight()
{
  boolean b1, b2, b3, b4;

  b1 = analogRead(PIU);
  b2 = analogRead(MENO);
  b3 = analogRead(ENTER);
  b4 = analogRead(ESC);


  if( b1 == LOW || b2 == LOW || b3 == LOW || b4 == LOW )
  {
    digitalWrite(BACKLIGHT, HIGH);
  }
  if( millis() - tempo_home > back_home )
  {
    tempo_home = millis();
    digitalWrite(BACKLIGHT, LOW);
  }
  if( millis() - tempo_backlight > delay_backlight )
  {
    tempo_backlight = millis();
    set = LOW;
    cont_pag = 0;
  }
}  

void menu(){
  enter = analogRead(ENTER);
  esc = analogRead(ESC);

  if(set == LOW)
  {
    piu = analogRead(PIU);
    meno = analogRead(MENO);
  }

  if(piu == LOW && millis() - tempo_btn > debounce && cont_pag >= 0 && cont_pag < 6)
  {
    tempo_btn = millis();
    cont_pag++;
    if(cont_pag == 6)
      cont_pag = 0;
  }

  if(meno == LOW && millis() - tempo_btn > debounce && cont_pag > 0 && cont_pag < 6)
  {
    tempo_btn = millis();
    cont_pag--;
  }

  if(esc == LOW && millis() - tempo_btn > debounce)  //Quando premo "esc" torno alla schermata HOME
  {
    tempo_btn = millis();
    cont_pag = 0;
    set = LOW;
  }
}

int settimer(){
  int pelota =0;
  if(enter == LOW && millis() - tempo_btn > debounce)  //Premendo "enter" si entra nella sotto-modalita'
    {
      tempo_btn = millis();
      set = !set;
    }
    if(set == HIGH)
    {   
        //Abilita l'ingresso in modalita' configurazione
      n_piu = 0;
      n_meno = 0;
        n_shift = 0;
      //Abilita i tasti "piu" e "meno" in modalita' incremento/decremento
      piu_set = analogRead(PIU);
      meno_set = analogRead(MENO);
        shift_set = analogRead(SHIFT);
  if(piu_set == LOW && millis() - tempo_btn > debounce)  //Incremento "variabile" se premo tasto "piu"
      {
        tempo_btn = millis();
        n_piu++;
        piu_set = !piu_set;
          int piuate =+ int(n_piu);
          timer = n_piu*pelota;
          Serial.println(piuate);
          Serial.println(piu_set);
      }

      if(meno_set == LOW && millis() - tempo_btn > debounce)  //Decremento "variabile" se premo tasto "meno"
      {
        tempo_btn = millis();
        n_meno++;
        meno_set = !meno_set;
          int menate =+ (-1*n_meno);
          timer = menate*pelota;
          Serial.println(menate);
          Serial.println(meno_set);
      }
        if(shift_set == LOW && millis() - tempo_btn > debounce){  //Aumento shift se lo tengo premuto
           tempo_btn = millis();
           n_shift++;
           int shiftate =+ n_shift;
           if(shiftate>4) shiftate =0;
           shift_set = !shift_set;
           if(shiftate == 0) pelota = 1;
           if(shiftate == 1) pelota = 10;
           if(shiftate == 2) pelota = 100;
           if(shiftate == 3) pelota = 1000;
           Serial.println(pelota);
           Serial.println(n_shift);
  }        

  }
  // Serial.println(timer);
   return timer;
}

alleggerito il codice ma non riesco a creare una funzione che mi faccia tipo premo + aumentano le unità di uno
premo - diminuisco le unità di uno
shift cambia le unità decimali tipo premuto una volta vo a cambiare le decine 2 volte centinaia 3 volte migliaia.
in particolare la funzione è questa

int settimer(){
  int pelota =0;
  if(enter == LOW && millis() - tempo_btn > debounce)  //Premendo "enter" si entra nella sotto-modalita'
    {
      tempo_btn = millis();
      set = !set;
    }
    if(set == HIGH)
    {   
        //Abilita l'ingresso in modalita' configurazione
      n_piu = 0;
      n_meno = 0;
        n_shift = 0;
      //Abilita i tasti "piu" e "meno" in modalita' incremento/decremento
      piu_set = analogRead(PIU);
      meno_set = analogRead(MENO);
        shift_set = analogRead(SHIFT);
  if(piu_set == LOW && millis() - tempo_btn > debounce)  //Incremento "variabile" se premo tasto "piu"
      {
        tempo_btn = millis();
        n_piu++;
        piu_set = !piu_set;
          int piuate =+ int(n_piu);
          timer = n_piu*pelota;
          Serial.println(piuate);
          Serial.println(piu_set);
      }

      if(meno_set == LOW && millis() - tempo_btn > debounce)  //Decremento "variabile" se premo tasto "meno"
      {
        tempo_btn = millis();
        n_meno++;
        meno_set = !meno_set;
          int menate =+ (-1*n_meno);
          timer = menate*pelota;
          Serial.println(menate);
          Serial.println(meno_set);
      }
        if(shift_set == LOW && millis() - tempo_btn > debounce){  //Aumento shift se lo tengo premuto
           tempo_btn = millis();
           n_shift++;
           int shiftate =+ n_shift;
           if(shiftate>4) shiftate =0;
           shift_set = !shift_set;
           if(shiftate == 0) pelota = 1;
           if(shiftate == 1) pelota = 10;
           if(shiftate == 2) pelota = 100;
           if(shiftate == 3) pelota = 1000;
           Serial.println(pelota);
           Serial.println(n_shift);
  }        

  }
  // Serial.println(timer);
   return timer;
}

no via non ci riesco!
ora aperitivo e ci penserò domani!