Sonar and MIDI Mapping

So, you set sonarnote to mappedPulse, then play 30 to 89 anyway?

I want the notes it plays to be realtime depending on the sonar distance.

I basically want to change this:

// play notes from F#-0 (30) to F#-5 (90):
   for (sonarnote = 30; sonarnote < 90; sonarnote++) {
     //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
     noteOn(0x90, sonarnote, 0x45);
     delay(10);
     //Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
     noteOn(0x90, sonarnote, 0x00);   
     delay(10);
   }

So it plays notes based on what the sensor is mapping.

I don't know if any of this is right!!

I don't know if any of this is right!!

Can't your ear tell you? You need to turn up the volume on your device. I can't hear it!

Right... thank you all for your help. I have got it basically working with this code, but I have a few more refinements that I would like help with.

//Feel free to use this code.
//Please be respectful by acknowledging the author in the code if you use or modify it.
//Author: Bruce Allen
//Date: 23/07/09

//Digital pin 7 for reading in the pulse width from the MaxSonar device.
//This variable is a constant because the pin will not change throughout execution of this code.

const

int pwPin = 7;
int pulse = 0;
int mappedPulse = 0;
int prevPulseVal = 0;
int prevnote = 0;


//variables needed to store values

byte note = 0;            // The MIDI note value to be played

void setup() {
  //This opens up a serial connection to shoot the results back to the PC console
  Serial.begin(31250);
}


void loop() {
  
  pinMode(pwPin, INPUT);
    //Used to read in the pulse that is being sent by the MaxSonar device.
  //Pulse Width representation with a scale factor of 147 uS (microseconds) per Inch.

  pulse = pulseIn(pwPin, HIGH);         //read input from potentiometer
  
  Serial.println(pulse);
  
   mappedPulse = map(pulse, 827, 15000, 0, 127);  //map value to 0-127

  if (pulse>827){

   noteOn(0x90, mappedPulse, 127); //Control Change (Ch 1), Controller 7 - default control for volume.
   delay(500);
   noteOn(0x80, mappedPulse, 0);
   
  } else {
    
    noteOn(0x80, mappedPulse, 0);
    delay(500);
    
  }
   
 }

 //  plays a MIDI note.  Doesn't check to see that
 //  cmd is greater than 127, or that data values are  less than 127:
 void noteOn(byte cmd, byte data1, byte data2) {
   Serial.write( byte(cmd) );
   Serial.write( byte(data1) );
   Serial.write( byte(data2) );
 }

The code above does this:

If the sonar is more than a specific distance away, it will play a note. After 500 ms, it will put the note off. This loops, which means that if it's over a certain distance away, a note will be played every 500ms, even if it's the same note repeating.

How can I change to do the following:

When the sonar is more than a specific distance away it will play a note. The note will play forever until the distance is changed. For example, if I'm 30cm away, an F# will play. If I stay at this exact distance, another note will not play until I change my distance, let's say to 32cm, then a G note will play. How can I do this.

I know that I need to store a value for the previous note, but I'm not sure how to go about doing it.

Thanks

I know that I need to store a value for the previous note, but I'm not sure how to go about doing it.

No. You need to store the previous distance. On each pass through loop, compare the current distance to the previous distance. If different, send a noteOff command, based on the old distance, and a noteOn command, based on the new distance. Then, make the old distance equal the new distance.

Put the code for getting mappedPulse in a function:

int readPulse(int aPin)
{
  int mapVal = 0;
  pinMode(aPin, INPUT);
  //Used to read in the pulse that is being sent by the MaxSonar device.
  //Pulse Width representation with a scale factor of 147 uS (microseconds) per Inch.

  unsigned long pulseTime = pulseIn(aPin, HIGH);         //read input from potentiometer
  
  Serial.println(pulseTime);
  
  mapVal = map(pulseTime, 827, 15000, 0, 127);  //map value to 0-127
  return mapVal;
}

Get rid of a bunch of global values that don't need to be global, like pulse.

Call the function, in loop():

int currNote;
int prevNote = 0;

void loop()
{
   currNote = readPulse(pwPin);
   if(currNote != prevNote)
   {
     // Turn off the old note
     // Turn on the new note
   }
   prevNote = currNote;
}