So, mein Arduino ist da und ich habe am WE schon ein bisschen herumgespielt... Mit Erfolg! Meine Freundin konnte meine Begeisterung nicht ganz verstehen, als ich mich freute, dass sich die Programmnummern ändern, wenn ich auf einen Button drücke, aber ich hab mich gefreut!
So, mal von vorne....
Ich habe vor, als erstes ein paar Tests zu machen um das Arduino und die MIDI-Kommunikation zu verstehen. Daher möchte ich das alles in kleine Teilschritte aufsplitten. Der Aufbau sollte möglichst einfach gehalten sein. Also nur 1 Button usw....
MIDI-BEFEHLE SENDEN
1. Per Schalter die Programme/Presets ändern --> Program Changes (PC) senden
2. Per Schalter Controller-Werte senden
3. Per Expression-Pedal Controller-Werte senden
EMPFANGEN (MIDI-Messages vom Axe-FX empfangen und auswerten)
3. Effekt-Block Status empfangen und per LED anzeigen (an/aus/nicht vorhanden)
4. TAB-Tempo Messages empfangen und per LED anzeigen
5. Tuner-Messages
ADD-ONs
Das macht alles dann Sinn für eine komplette MIDI-Leiste und umfangreicher Software.
6. Programm-Nummer anzeigen oder falls möglich auch größere Displays ansteuern
7. Programmieren des MIDI-Boards inkl. Speichern der Einstellungen
So der Plan....
Und Punkt 1. ist erledigt!
Punkt 2 im Grunde auch, aber dafür hab ich noch kein schönes Programm geschrieben. Ich habe bisher alles mit meinem alten Boss GX-700 getestet. Ich habe mich noch nicht ans Axe-FX getraut! ;-) Aber im Detail.... Ich habe diese Schaltung mit dem Arduino umgesetzt:
Und folgendes Programm dazu geschrieben.
Code:
/*
AxeFX.de DIY-MFC
Test 1: Senden eines Program Change Befehls
*/
byte ledPin = 13; // (OnBoard)-LED zur Kontrolle - leuchtet beim druecken
byte button = 42; // Pin-Nummer des Test-Buttons
byte stdChannel = 10; // MIDI-Kanal auf dem gesendet wird (in dem Fall Kanal 10)
byte buttonState = 0;
byte lastState = 0;
byte counter = 0;
void setup() {
// MIDI baud rate setzen:
Serial.begin(31250);
pinMode(button, INPUT); // Button PIN
pinMode(ledPin, OUTPUT); // LED-Pin ist 13 => OnBoard LED
digitalWrite(ledPin, LOW); // LED ausschalten
// Sende Test-Initial-PC
sendProgramChange(stdChannel, 39);
}
void loop() {
// Button auslesen
int buttonState = digitalRead(button);
// Ueberprüfen, ob der Status des Buttons sich geaendert hat
// (von gedrueckt zu nicht gedrueckt oder umgekehrt)
// Nur dann soll etwas passieren. Andernfalls werden staendig PCs gesendet
// wenn der Button gedrueckt wird.
if(buttonState != lastState) {
// Aktueller Button-Status merken
lastState = buttonState;
if(buttonState == HIGH) {
// Wenn der Button gedrueckt wurde...
counter++; // ... PC-Zaehler hochzaehlen!
// Vor einem Ueberlauf pruefen
// als Beispiel: max. bis Programm 11
if(counter > 10) {
// ...dann Zaehler zuruecksetzen
counter = 0;
}
// PC senden
sendProgramChange(stdChannel, counter);
// on-board LED einschalten
digitalWrite(ledPin, HIGH);
delay(200); // kurze Pause zum entprellen des Tasters (manchmal sendet dieser falsche Daten)
} else {
// bei nicht gedruecktem Button LED deaktivieren!
digitalWrite(ledPin, LOW);
}
}
}
// ==== MIDI FUNCTIONS ====
/*
** Sendet einen Program Change Befehl
**
** Arguments:
** --------------
** midiChannel MIDI-Kanal-Nummer auf dem gesendet werden soll
** prgNo Programm zu welchem gewechselt werden soll
*/
void sendProgramChange(byte midiChannel, byte prgNo) {
Serial.write(0xc0 + midiChannel - 1); // Program-Change Befehl senden (verknuepft mit dem uebergebenen MIDI-Channel
Serial.write(prgNo); // Programm-Nummer senden
}
In der Schaltung ist ein zusätzlicher Widerstand (10kOhm) am Schalter. Darüber werden Einstreuungen eliminiert, die entstehen und so vorgaukeln, dass der Schalter gedrückt wurde. Das habe ich aus einem Arduino-Tuorial gelernt! ; -)
Im Loop wird immer auf den letzten Button-Status geprüft, damit hier nur ein Befehl gesendet wird, wenn der Button gedrückt wird. Andernfalls würde andauernd ein PC gesendet werden. Zusätzlich ist nach dem Senden des PC-Befehls noch ein Delay (200ms) eingefügt. Mein kleiner Test-Taster sendet ab und an mal kurzzeitig kein Signal, obwohl ich ihn gedrückt halte. Das Arduino-Programm würde das dann als kurz loslassen und wiederdrücken interpretieren und sendet zwei PCs ganz kurz hintereinander. Zum Entprellen des Schalters habe ich das Delay eingefügt.
Das empfinde ich aber nicht als besonders gute Lösung, da das Programm hier halt immer kurz angehalten wird und das System träger reagiert. Gibt es hier nicht evtl. eine Lösung mit einem Kondensator um diesem Verhalten entgegenzuwirken? Oder kommt dieses Verhalten tatsächlich nur, weil mein kleiner Taster so schlecht ist?
AUSBLICK
Zur Planung eines kompletten MIDI-Boards habe ich mich auch bereits ein paar Gedanken gemacht. Wenn das Ganze so umgesetzt werden sollte ählnich der MFC, sollte pro Taster eine LED vorhanden sein, die rot, grün und ausgeschaltet sein kann (Status-LEDs für AUS, EIN, NICHT VORHANDEN). Solche LEDs gibt es, das ist nicht das Problem. Allerdings haben diese LEDs 3 Beinchen und nicht nur 2 wie die normalen LEDs. Aktuell plane ich noch vollständig ohne Multiplexer zu arbeiten, einfach, weil das Arduino bereits eine Menge Anschlüsse besitzt, aber auch, weil ich (noch) keine Ahnung vom Multiplexing habe. Aber das kann sich ja noch ändern.
Daher die Frage: Gibt es eine Methode, wie mit nur einem PIN drei Zustände an einer LED darstellen kann? Das wäre dann perfekt. Ansonsten gehen recht viele PINs verloren allein für die Status-LEDs.
Zusätzlich gehen noch PINs verloren, wenn Displays eingebaut werden sollen, wie z.B.
dieses hier. Das benötigt 4 PINs.
Zusammenfassend kann man sagen, dass man mit einem Arduino Mega 54 Digitale In oder Outs hat und 16 Analoge-Inputs.
Die 16 Analogen-Inputs würden (wenn ich das richtig verstehe!!) max. 16 Expression-Pedale ermöglichen.
Die 54 Digitalen In/Outs sind für MIDI-Transmissions, Switche und LEDs aufzuteilen.
Pin 0+1 fallen dort weg für die MIDI-Transmissions.
Pin 2-27 könnte man für die LEDs nutzen
Pin 28-53 könnte für die Switche genutzt werden.
Dies würde eine MIDI-Leiste mit 26-Buttons mit 26 (einfarbigen) LEDs bedeuten. Die LEDs könnten in diesem Beisiel nur ein oder ausgeschaltet sein. Hier können keine 3-Status wie bei der MFC angezeigt werden!!!
Soll noch ein kleines Display (s.o.) genutzt werden, dann gehen ein paar Pins verloren. In meinem Beispiel würde für eine 4-Stellige 7-Segment Anzeige 4 Pins (bedeutet 2 Buttons und 2 LEDs) benötigt werden.
Ich finde das schon krass gut, was mit diesen recht einfachen Mitteln möglich ist!!!
Bei Rot/Grün LEDs wäre folgende Kombination möglich:
Pin 0+1 fallen dort weg für die MIDI-Transmissions.
Pin 2-33 könnte man für die LEDs nutzen
Pin 34-49 könnte für die Switche genutzt werden.
Pin 50-53 wären dann sogar noch frei für ein Display
Dies würde eine MFC mit 16 Switche bedeuten.
Ich bin schwer begeistert!!!
Falls ich irgendwelche Fehler gemacht haben sollte, korrigiert mich bitte!
Ich halte euch hier auf dem laufenden.
Meine Fritzing-Files für das Arduino gibt es übrigens hier:
http://cloud.axefx.de/public.php?service=files&t=863e5d41055241f029a323b4e3ca3454