Hi!
I'm new to this board, so greetings to everybody!
I have a problem with midi. I use an Arduino Uno with Tom Scarff's midi interface and all i wanna do is to "simply" transmit midi messages from my FCB1010 pedalboard to my keyboard.
I wrote my own programm to deal with it, because i don't understand most of the midi libraries due to my insufficient knowledge of C/C++. So I kept it very simple and without System Exclusive receive.
I implemented an option to replace midi messages, for example ControlChange 14 with Databyte2 = 0 is replaced by a SystemExclusive message to add more possibilities to control my keyboard.
Actually, that works fine if I monitor the serial port via the aduino software. But when i connect it to my pedalboard and my keyboard, it works sometimes, but often there are errors. For example, one expression pedal controls volume (CC#7) and when i start to move it, it works fine until i move it a little bit faster or too long. If so, my sound is interrupted.
I have no idea why, so if you guys have any idea, please let me know!
Here is my code:
// Note Off
#define NoteOff 0
// Note On
#define NoteOn 1
// AfterTouch Poly
#define ATPoly 2
// Control Change
#define CC 3
// Program Change
#define PC 4
// AfterTouch Channel
#define ATChannel 5
// Pitch Bend
#define PitchBend 6
// System Exclusive
#define SysEx 7
// Variables
int Channel = 0;
int Type = 0;
int Switch = 0;
int Replaced = 0;
byte MIDIchannel;
byte Status = 0;
byte Running = 0;
byte currentByte = 0;
byte Data = 0;
byte Data1 = 0;
byte Data2 = 0;
void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
digitalWrite(3, LOW); // GND 0 Volt supply to opto-coupler
digitalWrite(2, HIGH); // +5 Volt supply to opto-coupler
pinMode(4, INPUT); // Set Inputs for 4 way DIP Switch
pinMode(5, INPUT);
pinMode(6, INPUT);
pinMode(7, INPUT);
digitalWrite(4, HIGH); // Set inputs Pull-up resistors High
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
// Read 4-way DIP switch
MIDIchannel=digitalRead(4) + (digitalRead(5)<<1) + (digitalRead(6)<<2) + (digitalRead(7)<<3);
Serial.begin(31250);
Serial.flush();
}
// Loop begin
void loop () {
getStatus();
switch (Type) {
case 4: // 1 Byte Message
case 5:
if (Data == 0) {
getData();
}
Data1 = Data;
if (Running == 0) {
replacer(Status, Data1, Data2);
if (Replaced == 0) {
sndMSG1(Status, Data1);
Running = Status;
Status = 0;
Data1 = 0;
Data2 = 0;
}
}
else {
replacer(Status, Data1, Data2);
if (Replaced == 0) {
sndMSG1_run(Status, Data1);
Running = Status;
Status = 0;
Data1 = 0;
Data2 = 0;
}
}
break;
case 0: // 2 Bytes Message
case 1:
case 2:
case 3:
case 6:
if (Data == 0) {
getData();
}
Data1 = Data;
getData();
Data2 = Data;
if (Running == 0) {
replacer(Status, Data1, Data2);
if (Replaced == 0) {
sndMSG2(Status, Data1, Data2);
Running = Status;
Status = 0;
Data1 = 0;
Data2 = 0;
}
}
else {
replacer(Status, Data1, Data2);
if (Replaced == 0) {
sndMSG2_run(Status, Data1, Data2);
Running = Status;
Status = 0;
Data1 = 0;
Data2 = 0;
}
}
break;
}
}
// Loop end
// MIDI-Routing
void replacer(byte Status, byte Data1, byte Data2) {
Replaced = 0;
// Replace CC-14-0 with Karma On / Off
if (Status == 176 && Data1 == 14 && Data2 == 0 && Switch == 0) {
// Karma On
Switch = 1;
Replaced = 1;
Serial.print(0xF0, BYTE);
Serial.print(0x42, BYTE);
Serial.print(0x30, BYTE);
Serial.print(0x75, BYTE);
Serial.print(0x41, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x0D, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x04, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x01, BYTE);
Serial.print(0xF7, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}
else if (Status == 176 && Data1 == 14 && Data2 == 0 && Switch == 1) {
// Karma On
Switch = 0;
Replaced = 1;
Serial.print(0xF0, BYTE);
Serial.print(0x42, BYTE);
Serial.print(0x30, BYTE);
Serial.print(0x75, BYTE);
Serial.print(0x41, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x0D, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x04, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0x00, BYTE);
Serial.print(0xF7, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}
// Replace NoteOn-C0-100 with Sustain
if (Status == 144 && Data1 == 0 && Data2 == 100) {
Replaced = 1;
Serial.print(176, BYTE);
Serial.print(64, BYTE);
Serial.print(110, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}
else if (Status == 144 && Data1 == 0 && Data2 == 0) {
Replaced = 1;
Serial.print(176, BYTE);
Serial.print(64, BYTE);
Serial.print(10, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}
}
// get Statusbyte
void getStatus() {
currentByte = 0; // Reset
if (Serial.available() == 128) {
Serial.flush();
}
while (!Serial.available()) {
}
if (Serial.available() > 0) {
currentByte = Serial.read();
}
while (currentByte == 254) { // Active Sensing
Serial.print(currentByte, BYTE);
while (!Serial.available()) {
}
if (Serial.available() > 0) {
currentByte = Serial.read();
}
}
if (currentByte == Running && Running != 0) {
Status = Running;
return;
}
while (currentByte < 128) { // Statusbyte?
while (!Serial.available()) {
}
if (Serial.available() > 0) {
currentByte = Serial.read();
}
}
Status = currentByte;
Channel = (Status&0x0F)+1;
Type = ((Status&0x70)>>4)&0x07;
Running = 0;
}
// get Databyte
void getData() {
currentByte = 0; // Reset
if (Serial.available() == 128) {
Serial.flush();
}
while (!Serial.available()) {
}
if (Serial.available() > 0) {
currentByte = Serial.read();
}
while (currentByte == 254) { // Active Sensing
Serial.print(currentByte, BYTE);
while (!Serial.available()) {
}
if (Serial.available() > 0) {
currentByte = Serial.read();
}
}
while (currentByte > 127) { // Databyte?
while (!Serial.available()) {
}
if (Serial.available() > 0) {
currentByte = Serial.read();
}
}
Data = currentByte;
}
// send Messages
void sndMSG1(byte Status, byte Data1) {
// Send, save Status for Running Status and delete
Serial.print(Status, BYTE);
Serial.print(Data1, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}
void sndMSG2(byte Status, byte Data1, byte Data2) {
// Send, save Status for Running Status and delete
Serial.print(Status, BYTE);
Serial.print(Data1, BYTE);
Serial.print(Data2, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}
void sndMSG1_run(byte Status, byte Data1) {
// Send, save Status for Running Status and delete
Serial.print(Data1, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}
void sndMSG2_run(byte Status, byte Data1, byte Data2) {
// Send, save Status for Running Status and delete
Serial.print(Data1, BYTE);
Serial.print(Data2, BYTE);
Running = Status;
Status = 0;
Data = 0;
Data1 = 0;
Data2 = 0;
}