Ultrasonic sensor as a music instrument.

Hello.
I have a huge trouble my project. I decided to create an instrument based on ultrasonic sensor (HC-SR04). I want to set music sounds to specific distances (for example: from 0 to 10 cm note C, from 11 to 20 cm note B, etc). I created by trial and error this code but there is a problem.
I want to play each sound constantly but Arduino generates it every time when ultrasonic sensor works (by delay(1000) function).
Can somebody fix this code for me (or just say how to do it)?
I thi

const int note=1;

boolean notePlaying[note];  
boolean midiMode=true;
int Trig = 10;

int Echo = 3;

long EchoTime;

int  Distance;

int  MaximumRange = 60;

int  MinimumRange = 2;

void setup()

{

  Serial.begin(115200); 

  pinMode(Trig, OUTPUT);

  pinMode(EchoTime, INPUT);

}

void loop()

{
  {
    digitalWrite(Trig, LOW); 
    delayMicroseconds(2); 
    digitalWrite(Trig, HIGH);
    delayMicroseconds(10);
    digitalWrite(Trig, LOW);
    EchoTime = pulseIn(Echo, HIGH);
    Distance = EchoTime / 58;


    delay(1000);
  } 
  if (Distance >= MaximumRange || Distance <= MinimumRange)

  {
    Serial.println("Poza zakresem"); 

    midiMessage(0x80, 1, 0x4A, 0);                          
    notePlaying[0x4A]=false;
    midiMessage(0x80, 1, 0x3C, 0);                          
    notePlaying[0x3C]=false; 
  } 

  else  

  {

    if(Distance < 20)


    {

      midiMessage(0x90, 1, 0x3C, 100);                          
      notePlaying[0x3C]=true;
      midiMessage(0x80, 1, 0x4A, 0);                          
      notePlaying[0x4A]=false;

    }


    if(Distance >= 20)

    {

      midiMessage(0x90, 1, 0x4A, 100);                          
      notePlaying[0x4A]=true;
      midiMessage(0x80, 1, 0x3C, 0);                          
      notePlaying[0x3C]=false;
    } 




    Serial.print("Odleglosc: ");
    Serial.println(Distance);

  }

}

void midiMessage(int commandByte, int channelByte, int data1Byte, int data2Byte) {
  if(midiMode){
    Serial.write(commandByte);
    Serial.write(channelByte);
    Serial.write(data1Byte);
    Serial.write(data2Byte);
  }
  else{
    if(commandByte==0x90){
      Serial.print("Note On message: note ");
    }
    else if(commandByte==0x80){
      Serial.print("Note Off message: note ");
    }
    Serial.print(data1Byte);
    Serial.print(", velocity ");
    Serial.println(data2Byte);
  }
}

get rid of the delay?

and get rid of the extraneous { }

Without this function ultrasonic sensor works as fast as it can, so Arduino also generates sounds in this tempo.

Code it so another sound won’t play until another distance range has been detected.

And your conditions overlap each other so it’ll try to play 2 notes
Like distance < 2 and distance < 20 both will play if distance = 1.
You have to code that smarter.

This sort of range based question seems to get asked a lot on the forum, so I thought I’d write some code to do it using a lookup table (struct)

The struct contains min, max and function pointers.

The code (in setup) iterates through the ranges array looking for a range match and when it finds a match it calls the function referenced by the function pointer funct, passing in the actual value.

The code assumes that there are not any overlapping ranges (but there can be gaps in the ranges)

If you want overlapping ranges etc, removed the break; from the inner for loop, but it will run a bit slower as it will need to iterate through all elements in the ranges array.

struct range
{
  int minVal;
  int maxVal;
  void (*funct)(int);
};

#define NUM_RANGES 2

// declare and initialise the the range data array min, max and the function to call 
range ranges[NUM_RANGES] =
{
  { 0, 5 ,&rangeFunction1},
  { 10, 15 ,&rangeFunction2}
};

// Some example functions
void rangeFunction1(int theValue)
{
  Serial.print("rangeFunction1  value is ");
  Serial.print(theValue);
}
void rangeFunction2(int theValue)
{
  Serial.print("rangeFunction2 value is ");
  Serial.print(theValue);
}




void setup()
{

  // initialize serial communication at 9600 bits per second:
  Serial.begin(115200);


  for(int testVal=-1;testVal<20;testVal++)
  {
    Serial.print(testVal);
    Serial.print(" ");
    for(int i=0;i<NUM_RANGES;i++)
    {

      if (testVal>=ranges[i].minVal && testVal<=ranges[i].maxVal)
      {
        ranges[i].funct(testVal);
        break;// break from i for loop
      }
    }
    Serial.println("");
  }
}


// the loop routine runs over and over again forever:
void loop() {


}

PS. The code can probably be tidied up, but I think its working OK :wink:

@mistergreen
Can you explain me how to do that?
I create something like that but it also generates sounds when sensor is working.
http://screenshooter.net/100056191/ajqehhr

    Distance = EchoTime / 58;
    if (Distance < 20)
    {Distance1 = Distance = 5;}
    if (Distance >= 20)
    {Distance2 = Distance = 30;}

Now I should put in the code something what will generate continuous sound until the state will be not changed (5 and 30), but how?

@rogerClark
I completely don’t know what should I do with this code :frowning:

you'd need to set the midi device to play continuous notes. You know the hardware better than me.

I have no idea how to do that :frowning:
Can somebody fix this code for me and make that Arduino will generate continuous sound until a state will change?

There is another code (more simple). It is generating sound to buzzer but as previous Arduino generates sound every time when ultrasonic sensor works. Maybe on this code somebody can explain me how to do what I want?

int Trig = 10;
int Echo = 3;
long EchoTime;
int  Distance;
int  MaximumRange = 100;
int  MinimumRange = 2;

void setup()

{

  Serial.begin(9600); 

  pinMode(Trig, OUTPUT);

  pinMode(EchoTime, INPUT);

}

void loop()

{
  digitalWrite(Trig, LOW); 
  delayMicroseconds(2); 
  digitalWrite(Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);
  EchoTime = pulseIn(Echo, HIGH);
  Distance = EchoTime / 58;

  if (Distance >= MaximumRange || Distance <= MinimumRange)

  {
    Serial.println("Poza zakresem");  
  } 
  else  

  {

    if (Distance < 15)
    {
      tone(8, 880, 500);
    } 

    if (Distance >= 15)
    {
      tone(8, 440, 500);

    } 

    if (Distance >= 35)
    {
      tone(8, 220, 500);

    } 

    if (Distance >= 70)
    {
      tone(8, 110, 500);

    }


    Serial.print("Odleglosc: ");
    Serial.println(Distance);

  }
  delay(500);
}

Bump

Any help?

bump

up

Still need help =(

Still need help

You still need to explain what your problem is. You have a sensor that you can apparently read. You have some idea what to do with the data (some requirements). You need to explain what the problem is. Why can't you implement the requirements?

If the problem is that you don't have any requirements, that is not something we can help you with.