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