Go Down

Topic: rilevare e misurare tempo fra due eventi eventi (Read 132 times) previous topic - next topic

mikiti

ciao,

vorrei rilevare l'attivazione di un sistema mediante il rilevamento dello stato del led di on/off (un led rosso che si accende, se on, o si spegne, se off) e misurare quanto tempo passa fra uno stato e l'altro.
Sono ancora un neofita, ho fatto alcuni dei classici esperimenti con arduino (uno) ma non ho ancora provato il modulo RTC.
Il tempo potrei misurarlo con la funzione millis() (o sbaglio?). Ma non capisco come fare le seguenti cose:
1 - intanto, monitorare quel led (che resta acceso per pochissimo tempo, praticamente lampeggia): ha senso mettere un delay di 1 ms (vorrei usare una fotoresistenza con un semplice ciclo if) o c'è un modo più efficiente per il rilevamento? il led non si accende con frequenza inferiore a 1 ms ma potrebbe accendersi fra 0 e 1 ms...
2 - come memorizzo due stati (due tempi)?

grazie a quanti diranno la loro

gpb01

1. come leggi se il LED è acceso o spento?

2. "... il led non si accende con frequenza inferiore a 1 ms ma potrebbe accendersi fra 0 e 1 ms ... " cosa significa questa frase? In quale range è la "frequenza" di lampeggio che devi misurare ?

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

docdoc

#2
Nov 17, 2017, 10:07 am Last Edit: Nov 17, 2017, 10:10 am by docdoc
Il tempo potrei misurarlo con la funzione millis() (o sbaglio?).
Si, certo.

Quote
1 - intanto, monitorare quel led (che resta acceso per pochissimo tempo, praticamente lampeggia): ha senso mettere un delay di 1 ms (vorrei usare una fotoresistenza con un semplice ciclo if) o c'è un modo più efficiente per il rilevamento? il led non si accende con frequenza inferiore a 1 ms ma potrebbe accendersi fra 0 e 1 ms...
Se è per quello che penso, ossia un misuratore di consumo leggendo il led del contatore (giusto? ;) ), è fattibile.

Non credo si accenda per solo un 1ms, non lo vedresti neanche, quindi credo tu ti possa non preoccupare di questo.

In ogni caso i delay() sono da evitare, nel tuo caso userai un interrupt, ossia dici ad Arduino di far partire una funzione quando il segnale di un pin cambia (indifferentemente da HIGH a LOW o viceversa), oppure puoi anche tracciare solamente la singola transizione LOW-HIGH o HIGH-LOW.
Trovi varie info QUI (reference), oppure QUI (un tutorial con esempio).

Quote
2 - come memorizzo due stati (due tempi)?
Due variabili, poi confronti i tempi. Ma prima sperimenta seguendo quel tutorial, inizia a scrivere un primo tuo sketch, poi se hai difficoltà posta qui quello che hai fatto e potremo aiutarti!

EDIT: dimenticavo, appena avrai descritto meglio cosa vuoi fare (se è il contatore o meno) e avrai chiaro il discorso interrupt() possiamo passare a capire come puoi leggere il LED ossia con quale "sensore" farlo, da collegare ad un pin digitale del tuo Arduino.
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito ;-) **

Etemenanki

Il led fa parte, suppongo, di una macchina a cui non puoi accedere ... quindi per rilevarne lo stato, dovrai schermarlo dalla luce ambiente e leggerlo con un fototransistor o un fotodiodo (non una fotoresistenza, perche' hanno tempi di risposta molto piu lunghi, in media da 10 a 20 mS di tempo di salita e da 20 a 30 mS di tempo di discesa, e se gli eventi da leggere sono cosi brevi, te li perderesti)

Poi potresti leggerlo con un'ingresso interrupt (niente delay, bloccano il programma) ... nella ISR setti una variabile a millis quando si accende, e poi quando si spegne calcoli quanto tempo e' passato ... senza accesso alle connessioni del dispositivo (e senza neppure sapere che dispositivo sia), c'e' poco altro da farci, credo ...
"Sopravvivere" e' attualmente l'unico lusso che la maggior parte dei Cittadini italiani,
sia pure a costo di enormi sacrifici, riesce ancora a permettersi.

mikiti

grazie per le info.

Il sistema su cui vorrei fare le acquisizioni è una specie di contatore (è un vecchio calorimetro di laboratorio che ha un led di stato che lampeggia per segnalare l'esecuzione di alcune funzioni).

Come giustamente mi è stato fatto notare, se gli impulsi durassero meno di 1 ms probabilmente non sarebbero visibili.
Vorrei usare una fotoresistenza perchè ho già fatto qualche prova (col tester) e mi sembra sia adatta allo scopo. Ho provato a registrare la caduta di resistenza e a fare una successiva elaborazione ma vorrei qualcosa di più immediato. Idealmente vorrei poter visualizzare i dati e memorizzarli su sd (fase successiva).

La frase "...la frequenza è..." l'ho formulata male, scusate: volevo semplicemente dire che il flash dura poco ma usando un certo delay, per quanto piccolo, rischio comunque di perdere il segnale (ma 1 ms è davvero piccolo).
Comunque darò un'occhiata agli interrupt e farò qualche prova.

vi farò sapere.
Se avete altri consigli da darmi, ovviamente, apprezzerò.

docdoc

#5
Nov 17, 2017, 04:12 pm Last Edit: Nov 17, 2017, 04:12 pm by docdoc
il flash dura poco ma usando un certo delay, per quanto piccolo, rischio comunque di perdere il segnale (ma 1 ms è davvero piccolo). Comunque darò un'occhiata agli interrupt e farò qualche prova.
Per avere la precisione migliore DEVI usare gli interrupt.

Poi credo che a te basti anche un solo evento (es. LOW->HIGH, ossia "RISING" negli interrupt), non ti interessa sapere quanto tempo è rimasto acceso il led immagino, per cui è tutto molto semplice, nella routine dell'interrupt (chiamata "ISR") semplicemente registri il momento dell'evento e alzi un flag, e nel loop() quindi appena vedi che il flag è alto fai quello che devi fare.

Una cosa del genere (l'ho scritto al volo, non prenderlo per intero e non necessariamente per buono):

Code: [Select]
#define LEDPIN 3
volatile byte state = LOW;
volatile unsigned long curBlinkTime = 0;
static unsigned long lastBlinkTime = 0;

void setup() {
   ...
  attachInterrupt(digitalPinToInterrupt(LEDPIN), ledBlink, RISING);
   ...
}

void ledBlink() {
  curBlinkTime = millis();
  state = HIGH;
}

void loop() {
  if ( state == HIGH ) {
    unsigned long intervallo = curBlinkTime - lastBlinkTime;
    lastBlinkTime = curBlinkTime;
    state = LOW;
    ... faccio qualcosa...
  }
   ...
}


PS: se Arduino deve restare acceso per svariati giorni, occhio che millis() misura il tempo dall'accensione e ad un certo punto ricomincia da zero. Per gestire questa cosa puoi vedere QUI.
Alex "docdoc" - ** se ti sono stato d'aiuto, un punto karma sarà gradito ;-) **

Go Up