Im fairly new to Arduino programming, but Im getting there. I have so far tried all of the midi-in programs on this thread, but what I really want to do is get the Arduino to play a simple square wave, for every note sent via MIDI.
I originally thought of using joshatkins MIDI to CV/gate converter, to control an external oscillator, but surely the Arduino should be able to generate simple tones. Does anyone know how to go about modifying the CV/ate converter code to do this?
/* 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;
}
}
Thanks