Radar HC-SR04

Buongiorno a tutti,
chiedo aiuto a voi perchè sono abbastanza disperato: ho voluto provare a realizzare il radar con Arduino e il sensore HC-SR04, seguendo il tutorial al link Arduino sonar radar.
Il codice funziona e anche abbastanza bene, però, provando a modificarlo in modo tale da riuscire a sfruttare tutta la portata del segnale, dà alcuni problemi. Per quanto riguarda processing, non ce ne è nessuno: una volta aggiustati i parametri tutto è andato a dovere.
La cosa che mi lascia perplesso è invece il comportamento del sensore che misura correttamente sotto i 150 cm, ma al di sopra abbassa la distanza a 152-155 cm. Ora: il problema non è il sensore, poichè provatolo a parte funziona fino ai 400-450 cm.
Vi allego di seguito lo sketch di Arduino:

#include <Servo.h>

const int trigPin = 10;
const int echoPin = 11;

//long duration;
int distance;

Servo myServo; // Creates a servo object for controlling the servo motor
void setup() 
{
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input
  Serial.begin(9600);
  myServo.attach(12); // Defines on which pin is the servo motor attached
}
void loop() 
{
  for(int i=15;i<=165;i++){  
  myServo.write(i);
  delay(30);
  distance = calculateDistance();// Calls a function for calculating the distance measured by the Ultrasonic sensor for each degree
  
  Serial.print(i); // Sends the current degree into the Serial Port
  Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
  Serial.print(distance); // Sends the distance value into the Serial Port
  Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing IDE for indexing
  }
  // Repeats the previous lines from 165 to 15 degrees
  for(int i=165;i>15;i--){  
  myServo.write(i);
  delay(30);
  distance = calculateDistance();
  Serial.print(i);
  Serial.print(",");
  Serial.print(distance);
  Serial.println(".");
  }
  delay(30);
}
// Function for calculating the distance measured by the Ultrasonic sensor
int calculateDistance()
{ 
  digitalWrite(trigPin, LOW); 
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH); 
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  long duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
  Serial.println(duration);
  distance = 0.034*duration/2;
  return distance;
}

Con il risultato:

26,151.7784
27,132.9564
28,162.7666
29,130.9495
30,161.7716
31,131.7671
32,130.7665
33,130.7721
34,131.7690
35,130.12794
36,217.7646
37,129.7639
38,129.7645
39,129.7690
40,130.7722
41,131.17193
42,292.7595
43,129.7664
44,130.7646
45,129.7616
46,129.7672
47,130.16872
48,286.7651
49,130.7646
50,129.7641
51,129.7640
52,129.7667
53,130.15254
54,259.7684
55,130.7667
56,130.7649
57,130.7694
58,130.13890
59,236.7681
60,130.7725
61,131.11312
62,192.8865
63,150.8910
64,151.8898
65,151.8915
66,151.8891
67,151.8897
68,151.8909
69,151.8901
70,151.8916
71,151.8888
72,151.8902
73,151.8898
74,151.8920
75,151.8884
76,151.8907
77,151.8913
78,151.8904

Allego anche il sorgente del test su sensore singolo, con il quale il sensore funziona perfettamente:

const int triggerPort = 10;
const int echoPort = 11;
 
void setup() 
{
pinMode(triggerPort, OUTPUT);
pinMode(echoPort, INPUT);
pinMode(led, OUTPUT);
Serial.begin(9600);
Serial.print("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 durata = pulseIn(echoPort, HIGH);
 
	long distanza=0.034*durata/2;
 
	Serial.print("distanza: ");
 
	//dopo 38ms è fuori dalla portata del sensore
	if(durata>38000)
		Serial.println("Fuori portata   ");
	else
	{ 
		Serial.print(distanza); 
		Serial.println(" cm     ");
	}
 
//Aspetta 1000 microsecondi
delay(1000);
}

Grazie mille per il vostro aiuto!

Ciao Tobsss,

avendo anch'io un HC-SR04 ho eseguito pari pari il tuo sketch (senza servo installato) con un delay di 1000 ed ho il seguente risultato puntando sul muro opposto della stanza:

113,224.13242
114,225.13262
115,225.13197
116,224.13617
117,231.171033
118,2907.19716
119,335.19604
120,333.19640
121,333.19586
122,332.19602
123,333.19617
124,333.173305
125,2946.7219
126,122.7538

come vedi ci sono differenze anche di 100 cm (lasciamo stare i 2907 che muovendo a mano il sonar avrò fatto casino) che secondo me sono dovute all'influenza dei vari oggetti che ho attorno (prima del muro)...

Ciao Orso,
grazie mille per la tua risposta. Anche a me era venuto questo dubbio e ho provato a puntarlo anche fuori dalla finestra (nessun ostacolo prima di 20-25 m), ma senza che cambiasse nulla.
Ripeto che la cosa strana è che facendo funzionare lo sketch che include solamente il sensore, funziona molto bene...
L'unico dubbio che mi viene è che potrebbe interferire il servo, magari assorbendo troppa corrente (anche se mi sembra strano perché ho collegato due condensatori da 100microF tra +5V e massa).
Grazie

Ciao...ho fatto una prova aggiungendo il servo...aumenta i due delay da 30 a 40 ...

Ciao, anche io ho sperimentato che sopra il 150cm il sensore da parecchi risultati errati.
Il primo consiglio che posso darti è usare questa libreria:
http://playground.arduino.cc/Code/NewPing

Il secondo è ripetere la misura più volte e filtrare i segnali ricevuti con un algoritmo. Il più semplice è prendere la misurazione mediana, la libreria NewPing ha un metodo ping_median() che fa proprio questo.

Grazie mille a tutti!

Comunque io ho SEMPRE avuto problemi con gli SR04, da allora non ne acquisto più e prendo al loro posto gli SRF05 che sono molto più affidabili per cui ti consiglio di passare a quelli!

Tra l'altro a suo tempo realizzai una libreria per getire entrambi, se può servirti è qui:

http://forum.arduino.cc/index.php?topic=327280.msg2266657

Ciao!