funzione millis()

Salve, se volessi sfruttare l'arduino come timer che si attiva quando premo un pulsante e si disattiva quando un sensore riceve un certo segnale come potrei fare ? intendo dal punto di vista di programmazione. Grazie. Valerio.

Metti nel loop una lettura continua del pulsante. Nel momento in cui il pulsante viene chiamato, lanci una routine che legge il sensore finché non ricevi il dato.

Usa i while per creare dei cicli da cui esci solo al verificarsi di una certa condizione.

valvale97: Salve, se volessi sfruttare l'arduino come timer che si attiva quando premo un pulsante e si disattiva quando un sensore riceve un certo segnale come potrei fare ? intendo dal punto di vista di programmazione. Grazie. Valerio.

Sei molto criptico. Non capisco cosa fa un timer se lo fai partire e viene spento da un evento esterno.

Ciao Uwe

Sei molto criptico. Non capisco cosa fa un timer se lo fai partire e viene spento da un evento esterno.

Probabilmente vuol fare un fotofinish :) Insomma, molto probabile che vuole misurare un tempo dallo START manuale a uno STOP di qualche sensore.

ciao

pablos:

Sei molto criptico. Non capisco cosa fa un timer se lo fai partire e viene spento da un evento esterno.

Probabilmente vuol fare un fotofinish :) Insomma, molto probabile che vuole misurare un tempo dallo START manuale a uno STOP di qualche sensore.

ciao

@pablos dindindin abbiamo un vincitore

ma la funzione delay(xxx); influenza la funzione millis(); ?

La funzione millis non è influenzata dal delay, ma durante l'esecuzione il codice rimane "bloccato" su quella riga per tot millisecondi.

valvale97: ma la funzione delay(xxx); influenza la funzione millis(); ?

no, anzi direi che delay è figlia di millis() :grin:

Mi spiace, ma delay si basa su micros() ;)

void delay(unsigned long ms)
{
    uint16_t start = (uint16_t)micros();

    while (ms > 0) {
        if (((uint16_t)micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}

Ok, ma se io assegno ad una variabile:

unsigned long time1= millis();

e poi alla fine del loop() metto un delay(xxxxx); questo mi altera il valore di "time1" ?

Spetta un attimo. Delay è un comando che istruisce la CPU del micro a fermarsi ed attendere che passi un certo lasso di tempo. Millis è una funzione che restituisce il numero di ms trascorsi dall'avvio del micro.

L'una non influenza l'altra ma entrambe dipendono da un contatore interno all'Atmega328, un contatore a 32 bit che tiene il conto dei millisecondi. E' lui che va in overflow, per la cronaca.

Tornando al tuo problema, quando sei ad esegure il tuo delay semplicemente non puoi fare altro per cui non puoi neanche controllare quanto tempo è trascorso leggendo millis.

quindi ponendo che il delay è di 10ms mi ritroverò la variabile time1 con 10ms in più. Giusto ?

se il tuo programma è questo:

void loop() { unsigned long time1=millis(); delay(10); .....CHECK.... }

Poniamo che il contatore interno sia a 0. Al 1° avvio, time1=millis=0. A "CHECK" millis sarà time1+millis ossia 10.

ok , ho capito grazie dell'aiuto. Valerio.

valvale97: quindi ponendo che il delay è di 10ms mi ritroverò la variabile time1 con 10ms in più. Giusto ?

no, il valore restituito da millis() è una COPIA del timer in quell'istante. Se fosse un puntatore, allora non cambierebbe solo quando chiami delay, ma cambierebbe insieme ad ogni millisecondo :-)

lesto:

valvale97: quindi ponendo che il delay è di 10ms mi ritroverò la variabile time1 con 10ms in più. Giusto ?

no, il valore restituito da millis() è una COPIA del timer in quell'istante. Se fosse un puntatore, allora non cambierebbe solo quando chiami delay, ma cambierebbe insieme ad ogni millisecondo :-)

Millis di suo non è niente, è una funzione che restituisce il valore del contatore. Di per sé non è neanche una copia.

Nell'esempio da me esposto dove si "legge" millis, si può dire che dopo aver fatto un delay(10), rileggendo millis si può verificare che siano passati 10 ms. BIsogna solo intendersi sui termini ;)

ma non puoi usare millis per vedere quanto tempo è trascorso?

int start;
int flag;
void loop(){
if(not flag && digitalRead(BOTTONE))){
     start=millis();
     flag=1;
     }
if(il_sensore_riceve_il segnale){
     start-=millis();
     flag=0;
}
}

alla fine di tutto nella variabile start hai il tempo trascorso tra la pressione del pulsante e il sensore che riceve il segnale; la variabile flag serve per non incrementare la variabile start se il pulsante resta premuto..mi sembra che era quello che chiedevi :)

Hai ragione devo ancora impararli certi termini :P

ora ho completato il codice:
ma non capisco perchè mi restituisce sempre time_tot = 0

#include <LiquidCrystal.h>
const int bt_pin = 6;
const int on_led = 7;
const int off_led = 8;
const int relay_pin = 9;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int last_bt_state = 0; 
int state_bt = 0;
int press = 2;
unsigned long time1;
unsigned long time2;
unsigned long time_tot;
int sensor_pin = A0;
int sensor_value = 0;
void setup()
{
pinMode(bt_pin,INPUT);
pinMode(on_led,OUTPUT);
pinMode(off_led,OUTPUT);
pinMode(relay_pin,OUTPUT);
Serial.begin(9600);
lcd.begin(16,2);
}

void loop()
{
  sensor_value = analogRead(sensor_pin);
  state_bt = digitalRead(bt_pin);
  if(state_bt == HIGH && last_bt_state == LOW)
  {
    press++;
  }
  if((press%2) == 0)
  {
    lcd.clear();
    digitalWrite(relay_pin,HIGH);
    digitalWrite(on_led,HIGH);
    digitalWrite(off_led,LOW);
    lcd.setCursor(0,1);
    lcd.print("ON");
  }
  if((press%2) != 0)
  {
    digitalWrite(relay_pin,LOW);
    digitalWrite(off_led,HIGH);
    digitalWrite(on_led,LOW);
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("OFF"); 
    time1 = millis();
  }
  if(sensor_value <1000)
  {
    time2 = millis();
    time_tot = time2-time1;
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(time_tot,DEC);
    delay(10000);
  }
  last_bt_state = state_bt;
  Serial.println(time_tot,DEC); 
}

uhmmm perchè if(sensor_value <1000) non è mai vera? mettici dentro un Serial.println(“vero”); e vedi se ci entri mai…