Pages: 1 [2]   Go Down
Author Topic: Sonar and MIDI Mapping  (Read 1318 times)
0 Members and 1 Guest are viewing this topic.
Newcastle Upon Tyne
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Studying Interactive Media Design at Northumbria University's School of Design.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm not sure what you mean.  This is all the code I have:

Code:
//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;

//variables needed to store values

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

long pulse;


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);
  Serial.println(pulse);
  delay(500);
 
  mappedPulse = map(pulse, 827, 15000, 0, 127);  //map value to 0-127
 
}

 //  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) );
 }
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45985
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  mappedPulse = map(pulse, 827, 15000, 0, 127);  //map value to 0-127
You can't just start using a variable without defining it's type.

What will you do if the pulse time is less than 827 or greater than 15000?
Logged

Newcastle Upon Tyne
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Studying Interactive Media Design at Northumbria University's School of Design.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

How do I define it's type?

Would you be able to change the whole code that I post just before?
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3114
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
byte mappedPulse = map(pulse, 827, 15000, 0, 127);  //map value to 0-127

Before you go much further, google 'c tutorial' and learn the basics.
Logged

Newcastle Upon Tyne
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Studying Interactive Media Design at Northumbria University's School of Design.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've put this together:

Code:
//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;

//variables needed to store values

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

long pulse;


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);
  Serial.println(pulse);
  delay(500);
 
  byte mappedPulse = map(pulse, 827, 15000, 0, 127);  //map value to 0-127
 
  sonarnote = mappedPulse;
 
  // 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);
   }
 
}

 //  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) );
 }

I just want to have it so it play a high note when you are close to the sensor and a low note when you are away.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24308
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Newcastle Upon Tyne
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Studying Interactive Media Design at Northumbria University's School of Design.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

I basically want to change this:

Code:
// 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!!
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45985
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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!
Logged

Newcastle Upon Tyne
Offline Offline
Newbie
*
Karma: 0
Posts: 17
Studying Interactive Media Design at Northumbria University's School of Design.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
//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
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 547
Posts: 45985
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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:
Code:
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():
Code:
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;
}
Logged

Pages: 1 [2]   Go Up
Jump to: