midi in

Narbotic adds midi in to my wishlist of urgently to be done stuff. I have been playing with the idea for midi-out on arduino, but this seems a pretty good solution for finally adding the midi capabilities to my WSG and my WP-20. This should also eliminate my needs for a hardware sequencer, although I’d love to build one.

arduino-midi-in by narbotic
arduino-midi-in by narbotic

The main thing I hove to achieve is being able to turn the knobs on my synths faster. This way I can really program presets, or sequence them. Probably I will be able to break some stuff too…

I’m also archiving the code from the post for later use

hi guys,
i just got an arduino two days ago in hopes of making a midi -> din sync, cv/gate, and dcb converter.  i have midi in to cv/gate and din sync working.  thought i’d share the code so far if anyone is interested.  you should be able to process any desired midi message pretty easily by modifying the processMIDI() function.  i also give the error in hz for each output cv note since the pwm outputs are only 256-bit.  the only external circuitry is a low pass filter on the pwm output (to get a constant cv voltage) and a nte3093 optoisolator on the midi input.

josh

/* MIDI to CV/Gate converter

Error in HZ due to 256-bit resolution of PWM (f_desired – f_synthesized)
————————————————————————
0  A0
0.0988  A#0
-0.2105  B0
-0.1113  C1
0  C#1
0.1245  D1
-0.2652  D#1
-0.1402  E1
0  F1
0.1569  F#1
-0.3341  G1
-0.1767  G#1
0  A1
0.1977
-0.4210
-0.2226
0
0.2490
-0.5304
-0.2805
0
0.3138
-0.6682
-0.3534
0  A2
0.3953
-0.8419
-0.4452
0
0.4981
-1.0607
-0.5610
0
0.6275
-1.3365
-0.7068
0  A3
0.7906
-1.6838
-0.8905
0
0.9961
-2.1215
-1.1219
0
1.2550
-2.6729
-1.4135
0  A4
1.5812
-3.3676
-1.7809
0
1.9922
-4.2430
-2.2438
0
2.5101
-5.3458
-2.8270
0  A5
*/

int gatePin = 4;
int cvPin = 5;
int statusLED = 13;
int midiEnable = 2;
byte notes[] = {0,4,9,13,17,21,26,30,34,38,43,47,
51,55,60,64,68,72,77,81,85,89,94,98,
102,106,111,115,119,123,128,132,136,140,145,149,
153,157,162,166,170,174,179,183,187,191,196,200,
204,208,213,217,221,225,230,234,238,242,247,251,255};
int tempo = 1;

void setup() {
pinMode(gatePin, OUTPUT);
pinMode(cvPin, OUTPUT);
pinMode(statusLED, OUTPUT);
pinMode(midiEnable, OUTPUT);
Serial.begin(31250);
digitalWrite(midiEnable, HIGH);
}

void loop() {
readMIDI();
}

// play a note out to cv
void note(byte note, byte velocity) {
analogWrite(cvPin, notes[note-9]);
if(velocity == 0) {
digitalWrite(gatePin, LOW);
} else {
digitalWrite(gatePin, HIGH);
}
}

void blink(int repeat) {
for(int i=0; i<repeat; i++) {
digitalWrite(statusLED, HIGH);
delay(5);
digitalWrite(statusLED, LOW);
delay(1);
}
}

void readMIDI() {
byte incomingMessage[] = {0,0,0};
byte incomingByte = 0;

if(Serial.available() > 0) {
incomingByte = Serial.read();
delay(3);  // not sure why i need to delay here, but doesn’t work w/o it
if(incomingByte >= 240) {
readSystem(incomingByte);
} else {
incomingMessage[0] = incomingByte;
}
if(Serial.available() > 0) {
incomingByte = Serial.read();
if(incomingByte >= 240) {
readSystem(incomingByte);
} else {
incomingMessage[1] = incomingByte;
}
if(Serial.available() > 0) {
incomingByte = Serial.read();
if(incomingByte >= 240) {
readSystem(incomingByte);
} else {
incomingMessage[2] = incomingByte;
}
}
}
}

processMIDI(incomingMessage);
}

void readSystem(byte incomingByte) {
byte incomingMessage[] = {0,0,0};

// read in the system message
incomingMessage[0] = incomingByte;
if(Serial.available() > 0) {
incomingMessage[1] = Serial.read();
if(Serial.available() > 0) {
incomingMessage[2] = Serial.read();
}
}

processMIDI(incomingMessage);
}

void processMIDI(byte incomingMessage[]) {
switch(incomingMessage[0]) {
case B10010000:  // Note on, channel 1
note(incomingMessage[1], incomingMessage[2]);
break;
case B10000000:  // Note off, channel 1
note(incomingMessage[1], 0);
break;
case B11111000:  // Time code
tempo++;
if(tempo == 24) {
blink(1);
tempo = 0;
}
break;
}
}

Leave a Reply

Your email address will not be published. Required fields are marked *