Help creating MIDI to pulse output generator for DCO

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

The code you posted does not correctly parse MIDI input. It also tries to read more Serial input than might be available.

See my answer in another recent thread on the topic:

Your digitalWrite calls should not be inside of the MIDI parsing code, now they're only executed once for each MIDI message, which is not what you want. Consider using PWM on a hardware timer instead.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.