Go Down

Topic: Calcolo del tempo istruzione Millis() Genuino 1 (Read 1 time) previous topic - next topic

LUCAP86

Salve a tutti,

mi chiamo Luca e sono nuovo del forum. Ho acquistato da poco un GENUINO 1 per dilettarmi nel fare delle prove. Una delle prime cose che mi necessita fare è quella di gestire il tempo. In sostanza in presenza di un ingresso devo attendere un certo tempo ed alzare un uscita. Non voglio utilizzare le istruzioni delay() in quanto vorrei non pregiudicare le funzioni del controllore per un tempo che potrebbe essere tanto lungo pertanto ho analizzato la possibilità di utilizzare la millis(). Mi sono creato un semplice "if" che ha il compito di storicizzare il tempo di millis() quando viene premuto il pulsante, tuttavia sembra che il sistema non sia in grado di salvarmi il tempo e di conseguenza non riesco più a fare quello che mi necessita. Di fatto ho lavorato in questo modo:

if (Ingresso == HIGH and memoria_app == 0){
    HistoricalTimeForAlarm = CurrentSecond;
    digitalWrite(ArduinoRun, HIGH);
    memoria_app = 1;
    }


dove "Ingresso" è lo stato del mio pulsante e "memoria_app" è una variabile int che mi serve per interbloccare l'if ed entrarci dentro una sola volta CurrentSecond è un "unsigned int" ed è uguale a millis()/1000. "memoria_app" verrà poi riportata a zero non appena viene rilasciato il pulsante.

Poi mi faccio la differenza con il tempo attuale e lo comparo con un preset di mio interesse, ebbene non mi funziona e non capisco dove sbaglio.

P.S.: sto utilizzando la versione 1.8.1 dell'IDE su W7 PRO

Grazie
Luca

SukkoPera

#1
Mar 17, 2017, 12:50 am Last Edit: Mar 17, 2017, 06:48 am by gpb01
Posta il codice intero.

--- (... mi raccomando, in conformità al regolamento, punto 7, racchiuso tra i tag CODE che, in fase di edit, ti inserisce il bottone </> ... primo a sinistra) - gpb01
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

gpb01

>LUCAP86:  essendo il tuo primo post, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie.

Guglielmo
Search is Your friend ... or I am Your enemy !

LUCAP86

#3
Mar 17, 2017, 07:17 am Last Edit: Mar 17, 2017, 08:02 am by gpb01
Ecco il codice

Code: [Select]

//Definizione variabili globali
const int ArduinoRun = 2;
const int LetturaPulsante = 3;
const int LedPulsante =13;
const int LedAllarme = 4;
bool PulsantePremuto;

//Area gestione varibili Globali
bool MemoriaAvvioConteggio; //Variabile da utilizzare per storicizzare il tempo di sistema arduino
unsigned long MillisForAlarm = 5; //Setpoint di allarme definito per 30 sec. (prova)
unsigned long HistoricalTimeForAlarm;
unsigned long TimeElapsedForAlarm;
int memoria_app;
unsigned long CurrentSecond = millis()/1000;

void setup() {

Serial.begin(9600);

  // Definizione delle tipologie di variabili
pinMode(ArduinoRun, OUTPUT);
pinMode(LetturaPulsante, INPUT);
pinMode(LedPulsante, OUTPUT);
pinMode(LedAllarme,OUTPUT);

}

void loop() {
  
  
  //Attivazione LED di RUN per indicare che la scheda elabora il programma
  //digitalWrite(ArduinoRun, HIGH);
  // put your main code here, to run repeatedly:
  PulsantePremuto = digitalRead(LetturaPulsante);
  //Serial.println(PulsantePremuto);

//Ciclo "if" pergestione Led di segnalazione utilizzo Acqua
if (PulsantePremuto == HIGH){
    digitalWrite(MemoriaAvvioConteggio,HIGH);
    digitalWrite(LedPulsante, HIGH);
    }
else {
    digitalWrite(LedPulsante, LOW);
    digitalWrite(MemoriaAvvioConteggio,LOW);
     }

//Ciclo "if" per registrazione tempo "milles" (sistema)
if (PulsantePremuto == HIGH and memoria_app == 0){
    HistoricalTimeForAlarm = CurrentSecond;
    digitalWrite(ArduinoRun, HIGH);
    memoria_app = 1;
    }
  //Serial.println(CurrentSecond);


   if (CurrentSecond - HistoricalTimeForAlarm > MillisForAlarm && memoria_app == 1){
        digitalWrite(LedAllarme, HIGH);
        }
    else {
        digitalWrite(LedAllarme, LOW);
        memoria_app = 0;
         }
  
 
//Fine programma
  
}


--- devi usare l'apposito bottone per inserire i tag CODE altrimenti li inserisci sbagliati (come hai fatto). Per questa volta ho corretto io. - gpb01

SukkoPera

Il problema è che probabilmente tu pensi che in ogni istante CurrentSecond valga millis()/1000, mentre di fatto ha sempre lo stesso valore, ovvero 0, perché viene valutata solo una volta all'avvio del programma, per come hai scritto tu.

Devi inizializzare la variabile ogni volta all'inizio del loop() oppure trasformarla in una funzione.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

LUCAP86

Ho provveduto ad inserirla all'inizio di LOOP, tuttavia il risultato non cambia, c'è qualcosa che mi sfugge sul come il sistema gestisce le tag per come sono abituato io il codice mi sembra ok, ma la cosa non mi funziona. Esiste la possibilità di entrare in debug on-line su arduino per capire che osa sta facendo?

SukkoPera

Tag?

Posta lo sketch modificato.

No, niente debug purtroppo.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

LUCAP86

Ecco il codice:

Code: [Select]
//Definizione variabili globali
const int ArduinoRun = 2;
const int LetturaPulsante = 3;
const int LedPulsante =13;
const int LedAllarme = 4;
bool PulsantePremuto;

//Area gestione varibili Globali
bool MemoriaAvvioConteggio; //Variabile da utilizzare per storicizzare il tempo di sistema arduino
unsigned long MillisForAlarm = 5; //Setpoint di allarme definito per 30 sec. (prova)
unsigned long TimeElapsedForAlarm;



void setup() {

Serial.begin(9600);

  // Definizione delle tipologie di variabili
pinMode(ArduinoRun, OUTPUT);
pinMode(LetturaPulsante, INPUT);
pinMode(LedPulsante, OUTPUT);
pinMode(LedAllarme,OUTPUT);

}

void loop() {
 unsigned long HistoricalTimeForAlarm;
 unsigned long CurrentSecond = millis()/1000;
 unsigned long SecondForAlarm = 5;
 int memoria_app;
 
 
  //Verifico che arduino abbia iniziato l'esecuzione del codice
  digitalWrite(ArduinoRun, HIGH);
   
  PulsantePremuto = digitalRead(LetturaPulsante);


if (PulsantePremuto == HIGH){
     digitalWrite(LedPulsante, HIGH);
    }
else {
    digitalWrite(LedPulsante, LOW);
    memoria_app = 0;
     }

//Ciclo "if" per registrazione tempo "milles" (sistema)
if (PulsantePremuto == HIGH and memoria_app == 0){
    HistoricalTimeForAlarm = CurrentSecond;
    delay(50);
    memoria_app = 1;
    }
  //Serial.println(CurrentSecond);

   if (CurrentSecond - HistoricalTimeForAlarm > MillisForAlarm && memoria_app == 1){
        digitalWrite(LedAllarme, HIGH);
        }
    else {
        digitalWrite(LedAllarme, LOW);
        memoria_app = 0;
         }
 
 
//Fine programma
 
}


Per visualizzare il valore delle tag in certi punti del codice posso utilizzare solo l'istruzione print??

Grazie
Luca

nid69ita

#8
Mar 17, 2017, 06:17 pm Last Edit: Mar 17, 2017, 06:20 pm by nid69ita
unsigned long HistoricalTimeForAlarm;   messo dentro alla loop  non è per nulla Historical.  ^-^

Metti le dichiarazioni globali, fuori e prima di setup() e loop()
Anche unsigned long CurrentSecond;
Quindi a inizio:  unsigned long CurrentSecond, HistoricalTimeForAlarm;

poi nella loop solo:   CurrentSecond = millis()/1000;

Leggi un libro di C, sezione dichiarazione variabili, "scope (parola inglese) e visibilità".
my name is IGOR, not AIGOR

LUCAP86

Ciao e grazie delle indicazioni, ho testato con le modifiche che mi hai suggerito e funziona.

Grazie
Luca

Go Up