Go Down

Topic: Sensore HC-SR04 e ciclo while (Read 301 times) previous topic - next topic

Firestarter83

Ciao docdoc, si hai assolutamente ragione.
Sto realizzando un Robot, la funzione Pulse in e' molto comoda ma purtroppo e' bloccante (l'attesa dell''echo)... c'è la possibilità di inserire il timeout, però mi piacerebbe farlo andare senza nessuna pausa... quale potrebbe essere l'alternativa alla Pulse In per calcolare la durata dell'Echo e determinare poi la distanza?
 C'è l'Interrupt, ma il micros() non avanzerebbe correttamente...

gpb01

#16
Feb 24, 2021, 05:03 am Last Edit: Feb 24, 2021, 05:03 am by gpb01
C'è l'Interrupt, ma il micros() non avanzerebbe correttamente...
In che senso scusa? :o

Normalmente in una ISR non ti metti certo ad aspettare ... leggi un valore e lo salvi, alzi una flag, incrementi un contatore, ecc. ecc., ma comunque la fai la più breve e la più rapida possibile ...

Spiega cosa intendevi.

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

Firestarter83

"Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be executed after the current one finishes in an order that depends on the priority they have. millis() relies on interrupts to count, so it will never increment inside an ISR. Since delay() requires interrupts to work, it will not work if called inside an ISR. micros() works initially but will start behaving erratically after 1-2 ms. delayMicroseconds() does not use any counter, so it will work as normal."

Mi ricordavo di aver letto qualcosa sulle Reference: micros() non si incrementa correttamente dopo 1-2 ma...
Allora: il sensore ad ultrasuoni, dopo aver inviato l'inpulso di Trigger, attende il ritorno del segnale, a quel punto il pin di Echo va ad High, ritorna low appena l'inpulso finisce, quindi potrei usare attachInterrupt CHANGE per determinare inizio e fine e calcolare il tempo trascorso per il calcolo della distanza... dovrebbe funzionare giusto? E a differenza della PulseIn non dovrebbe essere bloccante..

cotestatnt

quale potrebbe essere l'alternativa alla Pulse In per calcolare la durata dell'Echo e determinare poi la distanza?
Se stiamo parlando di ATmega328 (Arduino Uno, Nano, Mini), un modo per misurare con precisione la durata di un impulso è usare l'interrupt associato all'Input Capture Unit sul pin D8.
Purtroppo è una funzione molto poco documentata online e per un principiante potrebbe essere un po' ostica da digerire. 
Se vuoi approfondire, ti rimando ad uno dei post più completi (secondo me) disponibili online.
http://gammon.com.au/forum/?id=11504&reply=12#reply12

docdoc

Sto realizzando un Robot, la funzione Pulse in e' molto comoda ma purtroppo e' bloccante (l'attesa dell''echo)... c'è la possibilità di inserire il timeout, però mi piacerebbe farlo andare senza nessuna pausa...
Eh, però, perdonami, continuo a non capire per quale motivo tu abbia imposto (anzi "auto-imposto";) ) questo requisito. Se misuri distanze entro diciamo 5 metri, con la velocità del suono di 340 m/s, il tempo TOTALE per la lettura della distanza va tra 0.1 ms (distanze inferiori a 30 cm circa) e 30 ms (5 metri): tu hai necessità che il tuo robot non resti in attesa ed abbia realmente risposte (per altre attività) per tempi minori di 30 ms?

Ovviamente se il tuo problema è legato all'assenza di ostacoli (in tal caso il tempo di attesa si allunga), allora usa la pulseIn() con il parametro per specificare un timeout in modo che tu non vada ad attendere inutilmente per distanze maggiori di quelle per te necessarie, ad esempio:

Code: [Select]
...
#define SRF_TIMEOUT 30000UL // 30 ms
...
    // ping procedure
    digitalWrite( TrigPin, LOW );
    delayMicroseconds(2)
    digitalWrite( TrigPin, HIGH );
    delayMicroseconds(10);
    digitalWrite( EchoPin, LOW );  
    long pulseDuration = pulseIn( EchoPin, HIGH, SRF_TIMEOUT);
...
Alex "docdoc"
- "Qualsiasi cosa, prima di rompersi, funzionava"

Firestarter83

Grazie Cotestatnt per l'articolo, lo leggerò con attenzione,effettivamente e' molto avanzato per me...

Firestarter83

docdoc effettivamente ci avevo pensato anche io a questa cosa: e' inutile rilevare la n ostacolo a 5 metri, inserito il timeout per rilevare ostacoli più vicini, senza bloccare inutilmente il flusso del programma per troppo tempo...
Grazie
Giorgio

Go Up