Sunday, July 19, 2009


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
}