Ultrasonic Keyboard

> 2 min read

It’s time to make some music using the ultrasonic sensor! This is a project that I derived from the previous tutorial, the Ultrasonic Rangefinder.

Overview

ard_usMsc1

How can we make music using the ultrasonic sensor? By adding a piezo speaker, we will assign certain tones to the various range of distance detected by the ultrasonic sensor, which will be generated using the piezo speaker.

For this project, I will be constraining the distance range detected by the ultrasonic sensor from 0cm to 50cm. Hence, when the ultrasonic sensor detects distances exceeding 50cm, no tone will be produced. After constraining the distance value, I mapped the range from 0 to 12. Base on calculations, there will be a tonal change for every approximately 4.1667cm apart the respective distances.

However, there are certain problems that we will encounter. For example, the sensitivity of the ultrasonic sensor will decrease as the distance between it and a small object increases, as the small object will not be able to reflect the ultrasonic signals back to the sensor.

ard_usMsc2

NOTE:  As for the programming part, we will have to create the pitches.h file for the tones to be generated. This can be done by pressing on the “down” arrow beside the main program tab & click “New Tab”.  Name the new file as pitches.h.

ard_add_file

 

Parts

  • Ultrasonic Sensor x 1
  • Piezo speaker x 1
  • Arduino Uno x 1
  • Jumper wires x 1

 

Schematics

ultrasonic_music

Demo

After testing the sensor, I attempted to play “Happy Birthday” in the following demo.

 

Code

// this constant won't change.  It's the pin number
// of the sensor's output:
const int pingPin = 10;

#include <SoftwareSerial.h>
#include "pitches.h"


int notes[] = {
 NOTE_C4  ,
 NOTE_CS4 ,
 NOTE_D4  ,
 NOTE_DS4 ,
 NOTE_E4  ,
 NOTE_F4  ,
 NOTE_FS4 ,
 NOTE_G4  ,
 NOTE_GS4 ,
 NOTE_A4  ,
 NOTE_AS4 ,
 NOTE_B4  ,
 NOTE_C5  ,
 };
  
void setup() {
  // initialize serial communication:
Serial.begin(9600);
}

void loop()
{
  // establish variables for duration of the ping, 
  // and the distance result in inches and centimeters:
  long duration, inches, cm;

  // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  // The same pin is used to read the signal from the PING))): a HIGH
  // pulse whose duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // convert the time into a distance
  cm = microsecondsToCentimeters(duration);
  
  if(cm>50){
    //turn off sound
noTone(12);
  }else{
 cm = constrain(cm, 0, 50);
  }
 cm = map(cm, 0, 50, 0, 12);
  tone(12, notes[cm], 500);
 
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
 

  delay(10);
}


long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}

 

You may also like...