utilizzo pulsein

ciao sto usando la funzione pulsein() per misurare la lunghezza di impulsi con questo sketch

/*programma da utilizzare per test con un solo sensore
unsigned long durata[0],val;
int elemento=2;

void setup() 
{
  val=0;
  durata[0]=0;
   pinMode(2,INPUT);

   Serial.begin(9600);
}

void loop()
{
   durata[0]=pulseIn(elemento,HIGH,500);

   if (durata[0]>1) 
   {
   delay(1);
    val++;

      Serial.print("d ");
    Serial.println(durata[0]);
     Serial.print("val ");
     Serial.println(val);
   }
}

questo è un esempio di output:

d 9
val 1
d 21
val 2
d 9
val 3
d 13
val 4
d 5
val 5

nonostante con l'oscilloscopio veda degli impulsi bassi della durata di almeno 100 millisec alcuni sfuggono al programma, il segnale da leggere è regolarmente alto che va basso in occasione dell'evento, perchè devo usare pulsein() HIGH? qualche suggerimento

grazie stefano

con pulseIn HIGH leggi la durata del segnale ALTO. in oltre se non erro hai impostato un timeout. di 500MICROsecondi

ciao grazie @lesto io ho un segnale regolarmente HIGH e l'evento manda LOW il segnale ma non vedo niente su serial monitor è questo che mi disorienta rispetto a quello che mi dici e che pensavo che fosse, comunque adesso faccio prove con timeout minori

stefano

minori? semmai maggiori! 1millisecondo sono 1000microsecondi...

ciao si hai ragione, come al solito scrivo pensando alla cosa successiva

grazie stefano

Perché non usare gli interrupt di cambio di stato dei pin? Leggi attatchInterrupt() nel reference.

Potresti fare così. 1) azzeri un contatore 2) attivi l'interrupt sul cambio di stato che vuoi monitorare 3) ad ogni interrupt, incrementi un contatore 4) con millis, controlli che sia passato un certo intervallo di tempo e poi fermi l'interrupt 5) prelevi il valore del contatore e torni al punto 1)

Facendo la media fra tempo trascorso e impulsi conteggiati, hai la tua frequenza

ciao grazie @leo72 purtroppo il progetto finale prevede il monitoraggio di 6 canali se ci riesco, per il calcolo della frequenza dei passaggi seguirò i tuoi passi

stefano

Con pulseIn blocchi il codice in ascolto su un pin, per cui gli altri 5 sono in fila ad attendere il loro turno mentre i segnali su di essi vanno persi.

La soluzione allora è usare gli interrupt di cambio di stato PcInt. Non so se per l'Arduino c'è una libreria pronta, oppure devi scrivere il codice a mano.

ciao grazie @leo72 supponevo che ci fosse questo problema, il passaggio da H a L rappresenta il passaggio di un oggetto e ho misurato tempi di passaggio di circa 100ms in questo tempo, durante il quale il segnale è L, non riesco a fare la lettura degli altri 5 canali? diversamente cosa significa "usare gli interrupt di cambio di stato PcInt."

stefano

stefa24: ciao grazie @leo72 supponevo che ci fosse questo problema, il passaggio da H a L rappresenta il passaggio di un oggetto e ho misurato tempi di passaggio di circa 100ms in questo tempo, durante il quale il segnale è L, non riesco a fare la lettura degli altri 5 canali?

No. La PulseIn resta in esecuzione finché non è trascorso il tempo di timeout oppure non è arrivato prima un impulso.

diversamente cosa significa "usare gli interrupt di cambio di stato PcInt."

Ogni pin del micro ha un interrupt sul cambio di stato impostabile dall'utente. Attivando l'interrupt non devi monitorare tu il pin: è l'interrupt che in background lo fa per te, non interrompendo l'esecuzione del codice (non è proprio così ma si può approssimare a grandi linee in questo modo).

Non so se esiste la funzione per l'Arduino già "precotta" (non mi pare), altrimenti devi operare manualmente impostando tutto da codice manipolando i registri. Nel datasheet del 328, pagg. 58-72, trovi le spiegazioni degli interrupt e di come manipolare i registri per attivarli/disattivarli/gestirli. Però è roba di "alta scuola", non è facile se non sei già un po' addentro a queste cose.

ciao grazie @leo72 quindi devo dividere i 100ms in 6 e usare il valore come timeout, per pcint non ho fatto la scuola alta, ho trovato questa discussione http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1288131711

stefano

Sì, leggi bene ed anche la pagina che linkano: http://www.arduino.cc/playground/Main/PcInt

ciao grazie le pagine sono interessanti come primi tentativi volevo provare la soluzione hardware, la capisco meglio per ora

stefano

ciao
il grafico dell’impulso che analizzo e quello rosso, il la durata del segnale che vorrei leggere è quello L, non capisco perchè devo impostare pulsein() H per avere l’incremento della variabile dentro IF

stefano

20120120-0001.bmp (1.83 MB)

se vuoi leggere la durata del segnale L, allora devi mettere L! prova e magari posta l'output (senza if)

qualche info in più http://arduino.cc/en/Reference/PulseIn

ciao
grazie
@lesto ho fatto ma l’allegato è un L da 5.3ms come output ho 1usec, cercando nel forum ho visto che ci sono anche soluzioni hardware, CD4078

stefano

long val;
unsigned long durata;
int elemento=2;

void setup() 
{

  val=0;
  durata=0;
   pinMode(2,INPUT);

   Serial.begin(9600);
}

void loop()
{
   durata=pulseIn(elemento,LOW,500);

   //if (durata>1) 
   //{

   // val++;

      Serial.print("d ");
    Serial.println(durata);
 //    Serial.print("val ");
   //  Serial.println(val);

  // }
}
d 0
d 0
d 0
d 0
d 0
d 0
d 0
d 1
d 0
d 0
d 0
d 0
d 0
d 0
d 0
d 0
d 0

5.3ms

la pulseIn rimane in attesa dell'impulso per 1 secondo, poi rinuncia, avvengono le serial e poi ritorna in attesa...

più o meno quantoi tempo trascorre tra un segnale low e l'altro? dovrai metterlo come tempo di time-out

ciao grazie @lesto il programma come è adesso aspetta 500 usec fa il serial e poi ricomincia, il tempo tra un L e l'altro purtroppo è variabile, il funzionamento non è quello che viene spiegato, inoltre la durata mi serve per discriminare quale operazione fare o non fare per questo mi serve almeno un IF

stefano

con queste premesse è meglio un interrupt...

ciao grazie @lesto ho letto in giro e sembra che ci sia un bug nel pulsein andrò di hardware

stefano