Go Down

Topic: millis o unixtime? (Read 2804 times) previous topic - next topic

leo72

Se parliamo della secTimer, questo non è il modo per usarla  :P

Non so da dove tiri fuori quella variabile "timer", però per leggere i secondi devi usare il metodo readTimer, com'è evidenziato dall'esempio allegato.

Ora, se possibile, potresti o pubblicare il codice completo del setup() oppure dirci cos'è timer?

PS:
la LiquidCrystal non mi pare usi i timer, per cui non dovrebbe interferire con secTimer. Però non ho mai usato le 2 lib in combinazione, non so se al suo interno ha qualcos'altro.

zioTonino

le librerie sono tante perchè devono gestire:
- menu su lcd
- monitor lcd adafruit
- rtc adafruit
- secTimer

ovviamente non è finito, suggerimenti/critiche (costruttive) sono ben accetti :)

Code: [Select]

#include <MenuBackend.h>    //MenuBackend library - copyright by Alexander Brevig
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
#include <RTClib.h>
#include <secTimer.h>

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

RTC_DS1307 RTC;
secTimer myTimer;

// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

uint8_t buttons;

//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
MenuItem menu1Item1 = MenuItem("Item1");
MenuItem menuItem1SubItem1 = MenuItem("Item1SubItem1");
MenuItem menuItem1SubItem2 = MenuItem("Item1SubItem2");
MenuItem menu1Item2 = MenuItem("Item2");
MenuItem menuItem2SubItem1 = MenuItem("Item2SubItem1");
MenuItem menuItem2SubItem2 = MenuItem("Item2SubItem2");
MenuItem menu1Item3 = MenuItem("Item3");

int boa1[5], boaR[5];
int conta = 0;

boolean flagPompa = LOW;

unsigned long timer, rifCiclo;




// SETUP ***************************************************************************************
void setup()
{

  RTC.begin();

  myTimer.startTimer();

  if (! RTC.isrunning()) {
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  lcd.begin(16, 2);

  //configure menu
  menu.getRoot().add(menu1Item1);
  menu1Item1.addRight(menu1Item2).addRight(menu1Item3);
  menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
  menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2);
  menu.toRoot();

  pinMode(2, INPUT);
  pinMode(3, INPUT);

  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);


  rifCiclo = myTimer.readTimer();




// LOOP *******************************************************************************************
void loop()
{
  DateTime now = RTC.now();

  timer = myTimer.readTimer();

  //stampaOrario();

  ControlloLivello();

  //buttons = lcd.readButtons();

  //navigateMenus();  //in some situations I want to use the button for other purpose (eg. to change some settings) 

} //loop()...



void ControlloLivello(){

  //boa1 UP --> LIVELLO OK ACQUARIO --> LOW
  //boaR UP --> LIVELLO OK TANICA --> LOW

  if (timer == rifCiclo + conta){
    boa1[conta] = digitalRead(2);
    boaR[conta] = digitalRead(3);
  }

  lcd.setCursor(0,0);

  for(int i = 0; i < 5; i = i + 1){
    lcd.print(boa1[i]);
  }

  lcd.print("/");

  for(int i = 0; i < 5; i = i + 1){
    lcd.print(boaR[i]);
  }


  if(conta >= 4) {

    if (boaR[0] == LOW && boaR[1] == boaR[0] && boaR[2] == boaR[0] && boaR[3] == boaR[0] && boaR[4] == boaR[0]){

      if (boa1[0] == HIGH && boa1[1] == boa1[0] && boa1[2] == boa1[0] && boa1[3] == boa1[0] && boa1[4] == boa1[0]){

        lcd.setBacklight(BLUE);
        digitalWrite(5, HIGH);
        lcd.setCursor(12,0);
        lcd.print("AVVIO    ");
      }

      else{

        lcd.setBacklight(GREEN);
        digitalWrite(5, LOW);
        lcd.setCursor(12,0);
        lcd.print("OK   ");

      }

    }
    else {
      lcd.setBacklight(RED);
      digitalWrite(5, LOW);
      lcd.setCursor(12,0);
      lcd.print("ERRORE ");

    }
  }
 
  if (conta >= 4){
    conta = 0;
    rifCiclo = myTimer.readTimer();
  }
  else       
    conta = timer - rifCiclo;

}


void stampaOrario(){

  DateTime now = RTC.now();

  lcd.setCursor(0,0);
  stampa(now.hour());
  lcd.print(":");
  stampa(now.minute());
  lcd.print(":");
  stampa(now.second());
  lcd.print("        ");
}

void stampaData(){

  DateTime now = RTC.now();

  lcd.setCursor(0,0);
  stampa(now.day());
  lcd.print("/");
  stampa(now.month());
  lcd.print("/");
  lcd.print(now.year());
}

void stampa(int i){

  if (i < 10)
    lcd.print("0");

  lcd.print(i);
}


void menuChanged(MenuChangeEvent changed){

  MenuItem newMenuItem=changed.to; //get the destination menu

  lcd.setCursor(0,1); //set the start position for lcd printing to the second row

  if(newMenuItem.getName()==menu.getRoot()){
    lcd.print("Menu            ");
  }
  else if(newMenuItem.getName()=="Item1"){
    lcd.print("imposta orario  ");
  }
  else if(newMenuItem.getName()=="Item1SubItem1"){
    lcd.print("imposta ora     ");
  }
  else if(newMenuItem.getName()=="Item1SubItem2"){
    lcd.print("imposta minuti  ");
  }
  else if(newMenuItem.getName()=="Item2"){
    lcd.print("imposta data    ");
  }
  else if(newMenuItem.getName()=="Item2SubItem1"){
    lcd.print("imposta giorno  ");
  }
  else if(newMenuItem.getName()=="Item2SubItem2"){
    lcd.print("imposta mese    ");
  }
  else if(newMenuItem.getName()=="Item3"){
    lcd.print("Item3           ");
  }
}



void menuUsed(MenuUseEvent used){

  /* IMPOSTA ORA E MINUTI */
  /**********************************************************************************/

  //imposta ora
  if (used.item == "Item1SubItem1"){

    while(buttons != BUTTON_SELECT){
      DateTime now = RTC.now();
      stampaOrario();

      lcd.setCursor(0,1); 
      lcd.print("SX(-1) DX(+1)");

      buttons = lcd.readButtons();

      if (buttons == BUTTON_LEFT){

        DateTime past (now.unixtime() - 1 * 3600L );

        RTC.adjust(DateTime(past.year(), past.month(), past.day(), past.hour(), past.minute(), past.second()));

        lcd.setCursor(0,1);
        lcd.print("ORA -1          ");
        delay(400);
      }


      if (buttons == BUTTON_RIGHT){

        DateTime future (now.unixtime() + 1 * 3600L );

        RTC.adjust(DateTime(future.year(), future.month(), future.day(), future.hour(), future.minute(), future.second()));

        lcd.setCursor(0,1); 
        lcd.print("ORA +1          ");
        delay(400);
      }

    }
  }


  //imposta minuti
  if (used.item == "Item1SubItem2"){

    while(buttons != BUTTON_SELECT){
      DateTime now = RTC.now();
      stampaOrario();

      lcd.setCursor(0,1); 
      lcd.print("SX(-1) DX(+1)");

      buttons = lcd.readButtons();

      if (buttons == BUTTON_LEFT){

        DateTime past (now.unixtime() - 1 * 60L );

        RTC.adjust(DateTime(past.year(), past.month(), past.day(), past.hour(), past.minute(),0));

        lcd.setCursor(0,1);
        lcd.print("MIN -1          ");
        delay(200);
      }


      if (buttons == BUTTON_RIGHT){

        DateTime future (now.unixtime() + 1 * 60L );

        RTC.adjust(DateTime(future.year(), future.month(), future.day(), future.hour(), future.minute(), 0));

        lcd.setCursor(0,1); 
        lcd.print("MIN +1          ");
        delay(200);
      }

    }
  }
  /**********************************************************************************/


  /* IMPOSTA GIORNO, MESE E ANNO */
  /**********************************************************************************/

  //imposta giorno
  if (used.item == "Item2SubItem1"){

    while(buttons != BUTTON_SELECT){

      DateTime now = RTC.now();
      stampaData();

      lcd.setCursor(0,1); 
      lcd.print("SX(-1) DX(+1)");

      buttons = lcd.readButtons();

      if (buttons == BUTTON_LEFT){

        DateTime past (now.unixtime() - 1 * 86400L );

        RTC.adjust(DateTime(past.year(), past.month(), past.day(), past.hour(), past.minute(), past.second()));

        lcd.setCursor(0,1);
        lcd.print("DAY -1          ");
        delay(150);
      }

      if (buttons == BUTTON_RIGHT){

        DateTime future (now.unixtime() + 1 * 86400L );

        RTC.adjust(DateTime(future.year(), future.month(), future.day(), future.hour(), future.minute(), future.second()));

        lcd.setCursor(0,1);
        lcd.print("DAY +1          ");
        delay(150);

      }
    }
  }
  /**********************************************************************************/

  menu.toRoot();  //back to Main
}





void navigateMenus() {
  MenuItem currentMenu=menu.getCurrent();

  switch (buttons){
  case BUTTON_DOWN:
    if(!(currentMenu.moveDown())){  //if the current menu has a child and has been pressed enter then menu navigate to item below
      menu.use();
    }
    else{  //otherwise, if menu has no child and has been pressed enter the current menu is used
      menu.moveDown();
    }
    break;
  case BUTTON_SELECT:
    menu.toRoot();  //back to main
    break;
  case BUTTON_RIGHT:
    menu.moveRight();
    break;     
  case BUTTON_LEFT:
    menu.moveLeft();
    break; 
  case BUTTON_UP:
    menu.moveUp(); 
  }

  buttons=0; //reset the lastButtonPushed variable
}


leo72

Uh... dovresti metterti lì e controllare una per una le lib che usi che non vadano in conflitto fra di loro ma, soprattutto, che non usino il timer 2.

A questo punto parlo anche a mio sfavore, ma non ha senso usare la secTimer se hai un RTC esterno: usa quello per programmare gli interventi.

zioTonino


Uh... dovresti metterti lì e controllare una per una le lib che usi che non vadano in conflitto fra di loro ma, soprattutto, che non usino il timer 2.

A questo punto parlo anche a mio sfavore, ma non ha senso usare la secTimer se hai un RTC esterno: usa quello per programmare gli interventi.


ehm... cos'è un timer 2?

e come mi consiglieresti di utlizzare l'rtc esterno? confrontando nowunixtime()?

:)

leo72

Il timer 2 è il terzo dei 3 timer contenuti all'interno di un Atmega328. Il primo, il timer 0, è usato per le funzioni temporali di Arduino ed è ad 8 bit; il secondo è il timer 1, ed è a 16 bit; il terzo è il timer 2, ad 8 bit ancora, che uso per la secTimer.

Un timer è un contatore incrementato in HW, quindi in modo indipendente dal tuo codice. Al raggiungimento di un certo valore preimpostato oppure al suo overflow, può generare un interrupt, intercettando il quale si possono programmare dei compiti. Io uso l'overflow per aggiornare il contatore di secondi.

L'RTC esterno è un orologio. Se la lib ti fornire la funzione del tempo unix puoi usare quella per programmare intervalli nel futoro. Altrimenti imposti un orario nella forma oo:mm:ss e basta che confronti l'ora, minuti, secondi attuali con quella nel tuo allarme ed attivare la funzione desiderata allo scoccare dello stesso.

zioTonino

ciao,

io non devo programmare eventi nel futuro, vorrei solo leggere dei valori (input) e verificarli ad intervalli regolari: come posso fare?

un aiutino plz :P

leo72

1) Salvi l'orario
2) leggi l'orario
3) sono passati XX secondi/minuti dall'orario salvato?
4) sì, esegui la funzione programmata, poi torni ad 1)
5) no, torni a 2).

zioTonino


1) Salvi l'orario
2) leggi l'orario
3) sono passati XX secondi/minuti dall'orario salvato?
4) sì, esegui la funzione programmata, poi torni ad 1)
5) no, torni a 2).


Code: [Select]
setup:
time = now.unixtime();
rif = now.unixtime();

loop:
if (time == rif + 5){

// codice

}


così?

lesto

time e rif non vengono mai aggiorante. time dovrebbe essere aggioranta sempre, rif invece solo quando è eseguito il codice e si vuole impostare il tempo di prossima elaborazione
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

leo72


Code: [Select]
setup:
time = now.unixtime();
rif = now.unixtime();

loop:
if (time == rif + 5){

// codice

}


così?


Quasi. Come ha detto lesto, così time non viene aggiornata.

Code: [Select]
setup:
time = now.unixtime() + 5;

loop:
if (now.unixtime() > time) {
  // codice
  time = now.unixtime() + 5; //nuovo intervento
}
//altro codice


zioTonino


time e rif non vengono mai aggiorante. time dovrebbe essere aggioranta sempre, rif invece solo quando è eseguito il codice e si vuole impostare il tempo di prossima elaborazione


secondo voi c'è un modo per non dover ridefinire in ogni funzione il DateTime now = RTC.now() ?

ora il codice si presenta così:

Code: [Select]

setup:

DateTime now = RTC.now();
timer = now.unixtime() + 5;


loop:
  ControlloLivello();



void ControlloLivello(){
 
  DateTime now = RTC.now();
 
  //boa1 UP --> LIVELLO OK ACQUARIO --> LOW
  //boaR UP --> LIVELLO OK TANICA --> LOW

  if (now.unixtime() == timer){
    boa1[conta] = digitalRead(2);
    boaR[conta] = digitalRead(3);
  }

leo72


secondo voi c'è un modo per non dover ridefinire in ogni funzione il DateTime now = RTC.now() ?

Basta metterlo globale, ossia la sua dichiarazione la metti prima del setup().
In questo modo lo hai definito per tutto il programma.

Go Up