Arduino - trigger to MIDI

trouby

....
hiho programmierer,
habe da einige 80s drumcomputer, die ich ins modularsetup einbinden möchte.
Quelle: 16 TTL Trigger IN 1 ms 4V - also 2 Eingangsbytes.
Ziel: note on, note off :)
Das Doepfer CTM64 hab ich probiert, die 5 ms Abfrageschleife ist zu lang, ist bei 16tel schon unsauber.
Der arduino Uno ist zu klein, das megadrum zu gross.
hab mir schon einen überblick über arduino-midi verschafft. programmieren ist lange her :)

Die trigger sollen direkt abgefragt werden (auch merkerpuffer), per FIFO note-on, dann FIFO note-off.
es dürften max. 8 trigger gleichzeitig laufen. pro midikommando 1 ms, ich weiss.

welcher günstige arduino mit usb ist dafür geeignet?
16 eingangsbits, >1 ausgangsbit, seriell, usb.

befehl ist: serial.write()
 
Programme sind fertig, war einfacher als gedacht :) Bilder vom Interface folgen später.
case: 19" 1U; Amphenol Klinkenbuchsen, alternierendes Layout.
Das Delay von 1 Sekunde dient der Stummschaltung der Eingänge beim Einschalten. Ohne Pause würde jedes Instrument 1x getriggert.
Hier der Code:

// Trigger to MIDI - Roland TR-909

#include <MIDI.h>

bool trig[11];
bool mem[11];
byte drum[11]={38,45,37,42,51,49,46,39,48,41,35};
// SD LT HT CP OH CC RC CH RS MT BD
byte x;

void setup() {
pinMode(2,INPUT); //SD
pinMode(3,INPUT); //MT
pinMode(4,INPUT); //RS
pinMode(5,INPUT); //CH
pinMode(6,INPUT); //RC
pinMode(7,INPUT); //CC
pinMode(8,INPUT); //OH
pinMode(9,INPUT); //CP

pinMode(10,INPUT); //HT
pinMode(11,INPUT); //LT
pinMode(12,INPUT); //BD

Serial.begin(31250);

for (x=0;x<11;x++){
trig[x]=LOW;
mem[x]=LOW;
}
delay(1000);
}

void loop() {
trig[0]=digitalRead(2);
trig[1]=digitalRead(3);
trig[2]=digitalRead(4);
trig[3]=digitalRead(5);
trig[4]=digitalRead(6);
trig[5]=digitalRead(7);
trig[6]=digitalRead(8);
trig[7]=digitalRead(9);
trig[8]=digitalRead(10);
trig[9]=digitalRead(11);
trig[10]=digitalRead(12);

for (x=0;x<11;x++){
if (trig[x]==HIGH){
if (mem[x]==LOW){
Serial.write(144);
Serial.write(drum[x]);
Serial.write(127);
mem[x]=HIGH;
}}
if (trig[x]==LOW){
if (mem[x]==HIGH){
Serial.write(128);
Serial.write(drum[x]);
Serial.write(0);
mem[x]=LOW;
}}}}

------

// Trigger to MIDI - Alesis HR-16

#include <MIDI.h>

bool trig[16];
bool mem[16];
byte drum[16]={48,41,65,67,68,62,63,45,49,46,42,38,35,39,44,51};
// CH T3 P1 P3 P4 P2 T4 T2 CC OH CH SD BD CP MH RC
byte x;

void setup() {
pinMode(2,INPUT); //T1
pinMode(3,INPUT); //T3
pinMode(4,INPUT); //P1
pinMode(5,INPUT); //P3
pinMode(6,INPUT); //P4
pinMode(7,INPUT); //P2
pinMode(8,INPUT); //T4
pinMode(9,INPUT); //T2

pinMode(10,INPUT); //CC
pinMode(11,INPUT); //OH
pinMode(12,INPUT); //CH
pinMode(A0,INPUT); //SD
pinMode(A1,INPUT); //BD
pinMode(A2,INPUT); //CP
pinMode(A3,INPUT); //MH
pinMode(A4,INPUT); //RC

Serial.begin(31250);

for (x=0;x<16;x++){
trig[x]=LOW;
mem[x]=LOW;
}

delay(1000);
}

void loop() {
trig[0]=digitalRead(2);
trig[1]=digitalRead(3);
trig[2]=digitalRead(4);
trig[3]=digitalRead(5);
trig[4]=digitalRead(6);
trig[5]=digitalRead(7);
trig[6]=digitalRead(8);
trig[7]=digitalRead(9);
trig[8]=digitalRead(10);
trig[9]=digitalRead(11);
trig[10]=digitalRead(12);
trig[11]=digitalRead(A0);
trig[12]=digitalRead(A1);
trig[13]=digitalRead(A2);
trig[14]=digitalRead(A3);
trig[15]=digitalRead(A4);

for (x=0;x<16;x++){
if (trig[x]==HIGH){
if (mem[x]==LOW){
Serial.write(144);
Serial.write(drum[x]);
Serial.write(127);
mem[x]=HIGH;
}}
if (trig[x]==LOW){
if (mem[x]==HIGH){
Serial.write(128);
Serial.write(drum[x]);
Serial.write(0);
mem[x]=LOW;
}}}}
 
Nur ne Kleinigkeit:

Das hier

Code:
if ( x == a) {
if ( y == c) {
doit();
}}

ist das selbe, wie das hier


Code:
if ( x == a && y == c ) {
doit();
}
.

Wenn du das in zehn Jahren noch mal anpacken musst, ist die zweite Fassung einfach besser lesbar, vor allem dann, wenn du den Code nicht einrückst.
 
80s drumcomputer, die ich ins modularsetup einbinden möchte
warum über den Umweg Midi?
Analog Trigger > Midi > Midi > Analog Trigger?
Das gibt unnötige Latenz.
Doepfer CTM64 hab ich probiert, die 5 ms Abfrageschleife ist zu lang, ist bei 16tel schon unsauber
Midi hat fast immer Jitter, wenn nicht Dein Arduino, bestimmt der Empfänger.

Zu Deinem Code, falls Du das Timing genauer machen möchtest:
Da Du die die Programmierung vereinfachende Arduino IDE Sprache für Dummies und kein Assembler nutzt und diese quasi nochmal zusätzlich auf C aufgesetzt ist, verstecken sich in solchen Befehlen, wie digitalRead() oder digitalWrite() viele unnötige Programmzeilen:

Um die unnötigen und zeitraubenden Routinen bei jeder Portabfrage weg zu lassen kannst Du am schnellsten die Ports direkt abfragen

wenn Du mal nach fast digitalRead Arduino suchst ...

https://hekilledmywire.wordpress.co...tion-using-the-digital-ports-tutorial-part-3/





Eleganter könntest Du es noch mit Interrupts machen, die Auslösen, sobald ein Eingangspin sich ändert.
 
Zuletzt bearbeitet:
2bit - das stimmt, hatte compilerprobleme.
und ja, der sketch ist noch nich formatiert.
nur von trigger nach midi. möchte die drumboxen nicht modden. finger weg von der 909, war teuer :P
die variable mem dient ambivalent zur flankenabfrage. die loop-zeit ist mir unbekannt, meine triggerpulse sind 1 ms lang und es funktioniert.
ein midigramm braucht ~ 1ms zur übertragung; dürfte kaum auffallen als beim CTM64.
ein jam steht noch aus :)
 


News

Zurück
Oben