calcolare il tempo trascorso tra impulsi

salve a tutti prima di chiedere ho provato a fare un mio codice

//variabili tempo
unsigned long ti=0; //tempo iniziale
unsigned long tf=0; //tempo finale
unsigned long tt=0; //delta tempo
void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, INPUT);
  Serial.begin(9600);
}
void loop() {
  //primo ciclo da quando si accende per definire il tempo del primo impulso
  if(ti==0){
    while(digitalRead(12)!=HIGH){
    }
    ti=millis();
    while(digitalRead(12)!=LOW){
    }
  }
  //ciclo secondo
  while(digitalRead(12)!=HIGH){
  }
  tf=millis();
  tt=tf-ti;
  Serial.print(tt);
  Serial.print("  ");
  ti=tf;
  while(digitalRead(12)!=LOW){
  }

}

praticamente ho un segnale che ogni tanto mi da un impulso che dura poco quello che dovrei fare è contare il tempo che passa tra l'inizio di un impulso e l'inizio di uno nuovo che sarà poi a sua volta l'inizio di un nuovo calcolo. appena finisce un ciclo cioè passano 2 impulsi mi deve stampare il tempo

in sostanza devo sapere il tempo tra impulso 1 e 2 poi tra 2 e 3 e via così notare che i tempi devo partire e finire tra gli inizi dei 2 impulsi no tra la fine del primo e l'inizio del 2

il mio codice non funziona lasciatelo proprio perdere che fa ridere, sapete come posso fare??

piccolo esempio per capirsi

ciao hai guardato la funzione pulsein

stefano

Il pulsein tiene il programma fermo in attesa di impulso, io non lo userei, il millis va benissimo se ti è sufficiente un minimo di 20 ms , non credo che con tutte le istruzioni da eseguire il micro sia in grado nel loop di rilevare tempi più bassi, altrimenti devi andare ad agire sugli interrupt per ottenere valori molto più bassi.

ciao

mi tiene il programma fermo in che modo ?? esempio stupido se nel frattempo voglio lampeggiare un led esso si ferma?

potresti provare a risolverlo in maniera più elegante ed efficiente con un interrupt;

in pratica quando ti arriva l'impulso sul pin, viene generato un interrupt che fa eseguire una funzione che ti salva in una variabile globale il valore di ritorno della millis. prima di salvare il valore però fai la differenza con il suo valore precedente, in modo di calcolare il tempo trascorso.. esempio:

long tempo_trascorso;
long durata;

void routine_di_servizio_interrupt(){
   durata=millis()-tempo_trascorso;
   tempo_trascorso=millis();
}

void setup(){
     attachInterrupt(numero_del_pin,routine_di_servizio_interrupt,RISING);

in questo modo nella variabile globale durata hai il tempo trascorso dell'ultimo impulso...

mi sembra che potrebbe andare se non fosse che dovrei avere un tempo un po più preciso quello che ho adesso è una cosa nel ordine dei secondi

ma gli impulsi che devi misurare che durata minima hanno?

con gli interrupt è il metodo con cui riesci ad arrivare a tempi di misurazione più bassi in teoria...

usando la millis() entrano in gioco i tempi di durata del loop. In pratica un loop deve durare MENO della (almeno metà) durata del segnale alto o basso più corto. Pena non accorgersi del segnale.

gli interrupt da parte loro devono mantenersi leggeri o sminchiano i timer, quindi hai il problema del loop snello. dall'altra parte hai il problema che quindi i dati sono da elaborare nel loop, anche perchè molte funzioni all'intrno di una interrupt sono impossibili (in pratica tutto ciò che usa altri interrupt, come aggiornamento dei timer(i timer restano alla data di inizio interrupt, e il tempo perso non viene recuperato...), aggiornamento PWM(rimane il segnale di entrata in interrupt), e il discorso non è nemmeno così facile. Diciamo che la via che reputo migliore è creare un buffer circolare di tempi-durata (dati grezzi, le elaborazioni rallenterebbero l'interrupt), l'interrupt riempie il buffer, e il riempimento del buffer deve avvenire in un tempo maggiore necessario ad un completo ciclo di loop più completa elaborazione di tutti i dati nel buffer.

mi sembra che potrebbe andare se non fosse che dovrei avere un tempo un po più preciso quello che ho adesso è una cosa nel ordine dei secondi

direi che il tuo problema è affrontabile con la millis, se nel tuo codice non usi delay o cicli molto pesanti computazionalmente, difficilmente il loop superera la durata di qualche centinaio di microsecondi (0.01 millisecondi, o 0.00001 secondi)

la precisione che puoi ottenere con gli interrupt è di circa 4microsecondi, dato che il timer si incrementa di 4micosec alla volta

ilmandorlone: mi tiene il programma fermo in che modo ?? esempio stupido se nel frattempo voglio lampeggiare un led esso si ferma?

Si proprio fermo, nessuna istruzione viene eseguita finchè il pulsein non rileva l'impulso e non dice cosa fare. Non ho mai usato questa istruzione, sinceramente mi trovo meglio col millis().

ciao

Fai una piccola prova. Collega 2 led ai pin 10 e 11 dell'Arduino, poi copia questo sketch:

const byte LED1 = 10;
const byte LED2 = 11;

void setup() {
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
}

void loop() {
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, LOW);
    delay(10000); //10 secondi
    digitalWrite(LED2, HIGH);
    digitalWrite(LED1, LOW);
    delay(1000);
}

E poi guarda se il secondo led si accende in contemporanea al primo led oppure con uno scarto.

const byte LED2 = 11; :grin:

pablos: const byte LED2 = 11; :grin:

+1

:) ragazzi vi presento la mia idea commentate se ci sono dubbi domande lamentele o insulti :)

int xm=0; //segnale_memoria
long tt; //tempo_trascorso
long tm; //tempo_memoria
void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, INPUT);
  Serial.begin(9600);
}
void loop() {
  
  if(digitalRead(12)==HIGH){
    if(xm==0){
      xm=1;
      //---------
      tt=millis()-tm;
      Serial.print(tt);
      Serial.print("       ");
      tm=millis();
      //---------
    }
  }
  if(digitalRead(12)==LOW){
    if(xm==1){
      xm=0;
    }
  }
  //...... continua il tuo codice
}

direi che è ottimo mi è venuto in mente stà notte e ora l'ho realizzato :) PRO -non blocca il codice al massimo lo rallenta per poco -spostando quello che c'è tra le 2 //--- sotto il xm=0; puoi calcolare il tempo fra la fine dei 2 impulsi -è in grado di contare impulsi più brevi di 20 ms credo e più grandi di 3 minuti -restituisce una variabile che ha una precisione al ms CONTRO -rallenta di poco il codice e se mettete de delay nel vostro codice che viene dopo rallentate il ciclo

meglio di così si muore

leo72: Fai una piccola prova. Collega 2 led ai pin 10 e 11 dell'Arduino, poi copia questo sketch:

const byte LED1 = 10;
const byte LED2 = 11;

void setup() {    pinMode(LED1, OUTPUT);    pinMode(LED2, OUTPUT); }

void loop() {    digitalWrite(LED1, HIGH);    digitalWrite(LED2, LOW);    delay(10000); //10 secondi    digitalWrite(LED2, HIGH);    digitalWrite(LED1, LOW);    delay(1000); }




E poi guarda se il secondo led si accende in contemporanea al primo led oppure con uno scarto.

dimenticavo l'ho provato ma non so cosa c'entra @leo ??