int debug = 0;
int in_breath;
int in_learn;
int in_active;
int out_midi;
int learning = 0;
int active = 0;
long debounce = 200; // the debounce time, increase if the output flickers
int learnInPin = 6; // the number of the input pin
int learnState = HIGH; // the current state of the output pin
int learnReading; // the current reading from the input pin
int learnPrevious = LOW; // the previous reading from the input pin
long learnTime = 0; // the last time the output pin was toggled
int learnOutPin = 8;
int activeInPin = 7; // the number of the input pin
int activeState = LOW; // the current state of the output pin
int activeReading; // the current reading from the input pin
int activePrevious = HIGH; // the previous reading from the input pin
long activeTime = 0; // the last time the output pin was toggled
int activeOutPin = 9;
int breathMin = 1024;
int breathMax = 0;
void setup() {
if (debug) {
Serial.begin(9600);
} else {
Serial.begin(31250);
}
pinMode(learnInPin, INPUT);
pinMode(activeInPin, INPUT);
pinMode(learnOutPin, OUTPUT);
pinMode(activeOutPin, OUTPUT);
}
void readLearn()
{
learnReading = digitalRead(learnInPin);
// if we just pressed the button (i.e. the input went from LOW to HIGH),
// and we've waited long enough since the last press to ignore any noise...
if (learnReading == HIGH && learnPrevious == LOW && millis() - learnTime > debounce) {
// ... invert the output
if (learnState == HIGH)
learnState = LOW;
else {
learnState = HIGH;
breathMax = 0;
breathMin = 1023;
}
// ... and remember when the last button press was
learnTime = millis();
}
learnPrevious = learnReading;
if (learnState == HIGH) {
learning = 1;
} else {
learning = 0;
}
}
void readActive()
{
activeReading = digitalRead(activeInPin);
// if we just pressed the button (i.e. the input went from LOW to HIGH),
// and we've waited long enough since the last press to ignore any noise...
if (activeReading == HIGH && activePrevious == LOW && millis() - activeTime > debounce) {
// ... invert the output
if (activeState == HIGH)
activeState = LOW;
else
activeState = HIGH;
// ... and remember when the last button press was
activeTime = millis();
}
activePrevious = activeReading;
if (activeState == HIGH) {
active = 1;
} else {
active = 0;
}
}
void printDebug() {
if (learning) {
Serial.print("LEARN");
} else {
Serial.print("learn");
}
Serial.print("\t");
if (active) {
Serial.print("ACTIVE");
} else {
Serial.print("active");
}
Serial.print("\t");
Serial.print((long)breathMin,DEC);
Serial.print("\t");
Serial.print((long)breathMax,DEC);
Serial.print("\t");
Serial.print((long)in_breath,DEC);
Serial.print("\t");
Serial.print((long)out_midi,DEC);
Serial.print("\t");
Serial.println();
}
void doLEDS() {
if (learning) {
digitalWrite(learnOutPin,HIGH);
} else {
digitalWrite(learnOutPin,LOW);
}
if (active) {
digitalWrite(activeOutPin,HIGH);
} else {
digitalWrite(activeOutPin,LOW);
}
}
void doLearn() {
if (in_breath < breathMin) {
breathMin = in_breath;
}
if (in_breath > breathMax) {
breathMax = in_breath;
}
}
void doMIDIcalc() {
float v = ((float)in_breath - (float)breathMin)/((float)breathMax - (float)breathMin);
out_midi = v * 128;
if (out_midi < 0) {
out_midi = 0;
}
if (out_midi > 127) {
out_midi = 127;
}
}
void loop() {
in_breath = analogRead(0);
readLearn();
readActive();
doLEDS();
doMIDIcalc();
if (learning) {
doLearn();
}
if (active && !debug) {
midi_volume(1, out_midi);
}
if (debug) {
printDebug();
}
delay(100);
}
void midi_volume(byte channel, byte vol) {
Serial.print(0xB0 | (channel & 0xf), BYTE); // control change command
Serial.print(0x01, BYTE); // volume command
Serial.print(vol & 0x7f, BYTE); // volume 0-127
}