MIDI lab - a MIDI Theremin
I built a simple MIDI "theremin", using an ultrasonic rangefinder.
I had an initial false start, when I soldered the leads on the MIDI connector incorrectly.Once resolved, everything worked fine. Click here for a picture of the MIDI connector.
The picture also shows a multi-colored LED, which I am testing for another project.
Keep reading past the link for the code for the MIDI theremin.
/*
Ultra-basic MIDI theremin, using a MaxBotix rangefinder
Reads an analog sensor and uses value to generate a MIDI note.
*/
// Constants
#define rangeFinderPin 0
#define sensorMin 10
#define sensorMax 120
#define sensorTrigger 127
#define midiMin 40
#define midiMax 120
#define midiDuration 100
// Variables
int rangeFinderValue = 0;
int note = 0;
void setup() {
Serial.begin(31250);
}
void loop() {
rangeFinderValue = analogRead(rangeFinderPin);
if (rangeFinderValue > sensorMin && rangeFinderValue < sensorTrigger) {
delay(midiDuration); // this delay is to crop out the high transition
rangeFinderValue = analogRead(rangeFinderPin); // re-read
note = scale(rangeFinderValue, sensorMin, sensorMax, midiMin, midiMax);
noteOn(0x90, note, 127);
delay(midiDuration);
//Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
noteOn(0x90, note, 0x00);
// delay(midiDuration);
}
}
int scale(int inputValue, int inputMin, int inputMax, int outputMin, int outputMax) {
long temp = (outputMax-outputMin)*(inputValue-inputMin);
return constrain(temp/(inputMax-inputMin)+outputMin,outputMin,outputMax);
}
// 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(char cmd, char data1, char data2) {
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}
