Hi. I'm trying to make a arduino based DCO. the first step I need to do it make code that takes a midi input, converts the MIDI noteByte to a frequency, then sends out a 100uS pulse on a digital out pin at the frequency determined by the noteByte. This sounds simple but i'm having a lot of trouble doing it. The main issue I come up with is I can't get the arduino notebyte variable to be carried over to the output. I feel like my code needs a lot of work. the noteByte to frequency equation I know is right and works (i tried it with a dummy AnalogRead pot variable and the whole DCO output worked but the arduino lags and I don't get the desired frequencies). I've also heard timer interrupts are a better more accurate way to do this sort of thing but I haven't been able to understand how they work yet. If someone can help me make code that works that would be great. Here's my code:
float commandByte;
float noteByte;
float velocityByte;
byte noteOn = 144;
float frequency;
void setup() {
Serial.begin(31250);
pinMode(13, OUTPUT);
pinMode(12, INPUT);
}
void checkMIDI() {
do {
if (Serial.available()) {
commandByte = Serial.read();//read first byte
noteByte = Serial.read();//read next byte
velocityByte = Serial.read();//read final byte
if (commandByte == noteOn) {
frequency = 440 * pow(2, (noteByte - 69) / 12);
float highTime = 100;
float lowTime = ((1000000 / frequency) - highTime);
digitalWrite(13, HIGH);
delayMicroseconds(highTime);
digitalWrite(13, LOW);
delayMicroseconds(lowTime);
}
}
}
while (Serial.available() > 2);//when at least three bytes available
}
void loop() {
checkMIDI();
//for debugging
if (digitalRead(12) == HIGH) {
Serial.print("MIDI BYTE: ");
Serial.print(noteByte);
Serial.print(" FREQUENCY: ");
Serial.println(frequency);
}
}