Adding the ultrasonic sensor

Hi everyone.

In this post I’ll show the new circuit from the addition of the ultrasonic sensor, the code I uploaded to the Arduino to drive it, and a video to demonstrate its functioning.

Here is the circuit.

 
Nothing much going on here, the HC-SR04 needs 5V, so it's connected to the 5V pin, and obviously to ground. The Trig and Echo pins of the sensor are connected directly to two of the digital pins of the Arduino, D11 and D12.
 

An ultrasonic sensor works like this:

1 – You send a short pulse to trigger the vibration of the transducer. Like ringing a bell.
2 – The sound waves produced by the transducer travel, hit something and are reflected, travelling back to the sensor, and making the transducer vibrate again. For this sensor there are two separate transducers, one for production, one for reception.
3 – The transducer, because of the vibration, produces a current, which is a function of the distance travelled by the sound waves.
4 – Read out that current and, knowing the function f(current)=distance, you have your distance!

 
The sensor I’m using is quite smart, and instead of returning a continuous current to be read out and processed – the function f(current) = distance is easily nonlinear – it returns a digital signal, where the duration of the high value is linearly proportional to the distance of the sensed obstacle. Which makes things much easier.
 
To make things even easier, there’s a nice ready-to-use ultrasonic sensor library for Arduino which supports the HC-SR04. Cool!
 
Here’s a video demonstration of the project at this point.
 

 

And here’s the code I used, adapted from the basic example of the New Ping library.
// ------------------------------------------------------------------------
// This code reads the ultrasonic sensor about 20 times per second, and makes the motor vibrate 
// in inverse proportion to the distance (the less the distance, the more the vibration).
// Also, to take out some noise, the last six readings are averaged.
// The code is adapted from the New Ping library basic example.
// ------------------------------------------------------------------------

#include 

#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

#define MOTOR_PIN 3 // Arduino pin tied to motor control.

#define N_READINGS 6 // Number of readings to average to get rid of some noise.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

int read_array[N_READINGS]; //Array that stores the last N_READINGS to average

int read_count = 0;
float ave_distance = 0;

void setup() {
  for (int i=0; i<N_READINGS; i++){ // Initialize readings to 0
    read_array[i] = 0;
  }
}

void loop() {
  
  if(read_count>N_READINGS-1) read_count=0;
  
  delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  
  int distance = uS / US_ROUNDTRIP_CM; // Compute distance from known constant (defined in New Ping library).
  
  read_array[read_count] = distance; // Populate readings array.
  
  int sum = 0; // needed for average
  for (int i=0; i<N_READINGS; i++){
    sum += read_array[i];
  }
  ave_distance = sum/float(N_READINGS); //average of last n readings
  
  
  if (ave_distance < 100 && distance!=0){ // 0 corresponds also to distance over sensor limit
    analogWrite(MOTOR_PIN, 255-int(ave_distance*1.6)); //1.6 is found empirically, by experimenting
  }
  else{
    analogWrite(MOTOR_PIN, 0); // needed, otherwise the pin will keep sending the last value sent
  }
  
  read_count++;
}
The code is pretty straightforward, there isn’t much to explain I guess. The 1.6 value I used to adjust the amount of vibration of the motor was obtained experimentally, by trial and error. It is high enough so that the motor still vibrates when the distance is at the maximum. If a lower value were to be used, then the motor wouldn’t receive enough current to start vibrating at distances near the limit.I’m starting to think that maybe having a vibration motor is not that great an idea. Its expressive range is very limited, as you can listen from the video, the vibration doesn’t seem to change much from the nearest distance to the farthest. Also, it consumes a great deal power, which I could use to add more sensors to the glasses.
To explore other options, I bought two piezoelectric transducers, which should need very very little power, and much more control over their vibration is possible.For the next post, I’ll experiment with the piezoelectric tranducers. I think it won’t be a circuit post, as a piezoelectric transducer only needs a resistor, and nothing more, as far as I understand. Instead, given that there’s more things you can do with a piezoelectric transducer, like controlling amplitude and frequency of vibration, more attention will be given to the code.I’ll keep you posted!

BAT NAVIGATOR
arduino bat navigator

This conversation is happening on Twitter

Leave a comment

Use the hashtag #AddingTheUltrasonic0629, and mention me with @GCarmantini if you want a direct reply.