Il problema che ho riscontrato è che se avvicino troppo la mano i valori durata e distanza si azzerano, e ciò ha senso MA rimangono nulli se tolgo la mano, se resetto arduino e se ricarico il codice a meno che non stacco da breadboard il sensore e lo ricollego.
Lo stesso problema si presenta se il sensore rileva una distanza (o tempo superiore alla sua sensibilità).
Per valori intermedi non riscontro problemi.
Il codice da me utilizzato è il seguente:
//HC RS04 Sensore ultrasuoni
int triggerPort = 7;
int echoPort = 8;
void setup() {
pinMode( triggerPort, OUTPUT );
pinMode( echoPort, INPUT );
Serial.begin( 9600 );
Serial.println( "Sensore ultrasuoni: ");
}
void loop() {
//porta bassa l'uscita del trigger
digitalWrite( triggerPort, LOW );
//invia un impulso di 10microsec su trigger
digitalWrite( triggerPort, HIGH );
delayMicroseconds( 10 );
digitalWrite( triggerPort, LOW );
long duration = pulseIn( echoPort, HIGH );
long r = 0.034 * duration / 2;
Serial.print( "durata: " );
Serial.print( duration );
Serial.print( " , " );
Serial.print( "distanza: " );
//dopo 38ms è fuori dalla portata del sensore
if( duration > 38000 ) Serial.println( "fuori portata");
else { Serial.print( r ); Serial.println( "cm" );}
//aspetta 1.5 secondi
delay( 1500 );
}
il problema si verifica anche a diversi valori sia maggiori che minori di 84 e si risolve solo nel momento in cui il sensore viene rimosso e successivamente rimontato nella breadboard.
Non si risolve nei seguenti modi:
ricaricando il codice
resettando la scheda arduino
Modificato ma senza risultati non riesco a capire quale possa essere il problema!
Dal monitor seriale si vedono i diversi valori cambiare fino a quando non ne scrive altri per qualche secondo e poi da solo valori nulli!
Il sensore funziona come dovrebbe grazie all'introduzione del timeout per il pulseIn.
Se ho capito bene il timeout specificato impone al pin Echo di rilevare ogni tot. Giusto?
Per chi non ha noti l'utilizzo di UL nella formula di pulseIn lascio questo link.
Il codice di prova da me utilizzato lo potete trovare qua con tanto di spiegazione del funzionamento del sensore HC-SR04
Lascio anche il codice finale modificato grazie al gentilissimo cyberhs:
/*HC RS04 Sensore ultrasuoni
Il sensore utilizza due capsule Trigger e Echo, la prima emette un segnale
acustico che una volta riflesso è captato da Echo.
*/
//Dichiarazione delle costanti Trigger e Echo
const unsigned int triggerPort = 9;
const unsigned int echoPort = 8;
void setup() {
pinMode( triggerPort, OUTPUT ); //Trigger emette
pinMode( echoPort, INPUT ); //Echo riceve
Serial.begin( 9600 ); //Inizializzo la comunicazione seriale
Serial.println( "Sensore ultrasuoni: ");
}
void loop() {
//porta bassa l'uscita del trigger
digitalWrite( triggerPort, LOW );
delayMicroseconds( 10 );
//invia un impulso di 10microsec su trigger
digitalWrite( triggerPort, HIGH );
delayMicroseconds( 10 );
digitalWrite( triggerPort, LOW );
delayMicroseconds( 200 );
unsigned long duration = pulseIn( echoPort, HIGH, 1000000UL );
float r = float(duration / 58); // Converte il tempo di volo in spazio, 58 è il valore suggerito dal datasheet
( echoPort, LOW );
Serial.print( "durata: " );//Mostra i risultati ottenuti sul monitor seriale
Serial.print( duration );
Serial.print( " , " );
Serial.print( "distanza: " );
//dopo tot tempo di volo: è fuori dalla portata del sensore
if( duration > 20000 )
Serial.println( "fuori portata");
else {
Serial.print( r ); Serial.println( "cm" );
}
//aspetta 1.5 secondi
delay( 1500 );
}
Perchè il compilatore prima divide un long con un int (quindi no virgole) e poi lo converte in float.
Ha senso o così:
...= float(duration) / 58.0;
Poi fare duration/58 oppure 0.034 * duration / 2 il calcolo è molto simile
perchè equivale a "duration* 34/2000" quindi "duration * 1/58.82" => "duration/58.82" quasi uguale