I am trying to translate MIDI Control Change messages to volts in order to control the filter cutoff frequency of a synthesizer of mine (Korg MS10).
In particular, I am trying to listen to CC 19 and map it to a voltage.
Looking at this reference...
MIDI messages table:
Message Status Data 1 Data 2
Note Off 8n Note Number Velocity
Note On 9n Note Number Velocity
Polyphonic Aftertouch An Note Number Pressure
Control Change Bn Controller Number Data
Program Change Cn Program Number Unused
Channel Aftertouch Dn Pressure Unused
Pitch Wheel En LSB MSB
Key
n is the MIDI Channel Number (0-F)
LSB is the Least Significant Byte
MSB is the Least Significant Byte
There are several different types of controller messages.
and in particula at his line ...
Message Status Data 1 Data 2
Control Change Bn Controller Number Data
... I was almost sure that the "Controller Number" was my "19". Looks like it's not the case.
Here is the sketch:
//set at your will ...
#define MIDI_CHANNEL 0 //the MIDI channel you want your box to listen to (0 = 1, 1 = 2 etc.)
#define CC_NUMBER 19 //MIDI CC number - Filter Cutoff
byte CCPin = 6; // 978Hz (pin D5 and D6 in ATmega 8, 168 or 328)
byte messageByte;
byte data1;
byte data2;
byte CCByte;
byte CCValue;
byte midi_CC = 0xB0 + MIDI_CHANNEL;// control change (in general 0xBn, with n = 0-F for channels 1-16)
int CCOut;
void setup() {
pinMode(CCPin, OUTPUT);
Serial.begin(31250);//baud rate for MIDI
}
void loop() {
do{
if (Serial.available()){
MIDIread();
if (messageByte == midi_CC){
CCByte = data1;
CCValue = data2;
if(CCByte == CC_NUMBER){
CCOut = constrain(map(CCValue, 0, 127, 0, 255), 0, 255);
analogWrite(CCPin, CCOut);
}
}
}
}
while (Serial.available() > 2);//when at least three bytes available
}
void MIDIread(){
messageByte = Serial.read();//read first byte
data1 = Serial.read();//read next byte
data2 = Serial.read();//read final byte
}
My tests showed that this condition here:
if(CCByte == CC_NUMBER)
... is never satisfied. If i remove that condition, every single CC makes Arduino output a (RC D/A) voltage out of pin D6, so the circuit is ok.
any thought?
I am almost sure I am misleading that "Controller Number " I see there: it must be referred to something else, not the CC i set.
thanks Grumpy. Sorry for being noob, but am I losing a byte by checking for Serial.available() or where? I am not a coder so some easy task could be not that easy for me
but am I losing a byte by checking for Serial.available()
No.
That code looks to see if their is one or more bytes in the serial buffer. Let's say their is one. Then it calls the MIDIread function that proceeds to read three bytes irrespective of whether their are three bytes to read. I think you can see that is not want you want to do.
Remove the do .... while structure it is not doing what you think it is doing, and replace the if (Serial.available()) with if (Serial.available()>2)
Again true but you have to consider if the application is going to receive any. If it can't do anything with a two byte message then their is no need to send one nor make provisions for it appearing.
You don't always need a full MIDI message parsing system, to insist on one from a beginner just in case, I think makes things too complex to begin with and can frighten off learners. I would advise either matching your parsing code with what you expect or use a libiary with full parsing. However, in the Arduino world I believe libraries are used way too much and mainly stop people learning the fundamentals of the craft.