segunda-feira, 6 de julho de 2009

Arduino Midi Drum

Esta é a programação da minha batera Midi feita com Arduino.

Pelo menos eu acho que esta é a programação.
#define ledPin     13  // for midi out status
// what midi channel we're sending on
#define drumchan           1
#define PIEZOTHRESHOLD 100
#define MAXIMUMINTERVAL 40
#define switchA 7
#define switchB 6

// Definicao para os piezos
//  - Definicao padrao : int piezoNotesA[6] = {35,38,42,41,51,49};
// Definicao para meu drumkit do Hydrogen
//int piezoNotes[6] = {37,39,57,47,62,63};
int piezoNotes[6] = {35,38,42,41,51,49};
int piezoPins[6]   = {0,1,2,3,4,5};
int piezoState[6] = {0,0,0,0,0,0};
int leitura1[6] = {0,0,0,0,0,0};
int leitura2[6] = {0,0,0,0,0,0};
long piezoInterval[6] = {0,0,0,0,0,0};

long currentTime = 0;
int val,t, i, piezoAtual;
long switchInterval = 0;

void setup() {
pinMode(switchA, INPUT);
pinMode(switchB, INPUT);
digitalWrite(switchA, HIGH);  // turn on internal pullup
digitalWrite(switchB, HIGH);  // turn on internal pullup

pinMode(ledPin, OUTPUT);
Serial.begin(31250);   // set MIDI baud rate
i = 0;
piezoAtual = 0;
}

void loop() {
piezoAttack(i);
drumkitSetup();
i++;
if(i == 7) i = 0;
}

// Funcao que define leitura dos switch
void drumkitSetup(){
currentTime = millis();
// So le a cada 1/2 segundo
if(currentTime - switchInterval <>35 ){
piezoNotes[piezoAtual]--;
} else{
piezoNotes[piezoAtual] = 81;
}
digitalWrite(switchB, HIGH);
}
switchInterval = currentTime;
}

// Funcao que define a nota do piezo
void piezoAttack(int i){
currentTime = millis();
// So faz uma leitura deste piezo a cada MAXIMUMINTERVAL millisegundos
if(currentTime - piezoInterval[i] <= MAXIMUMINTERVAL){       return;     }     // Eh feito duas leituras de maneira a tentar determinar o comportamento da onda     leitura1[i] = analogRead(piezoPins[i]);     leitura2[i] = analogRead(piezoPins[i]);      // Toda vez que abaixar em relacao ao threshold, desliga a nota     if ( leitura2[i] <> leitura2[i]){
piezoState[i] = 0;
}
// Se a segunda leitura for maior que a primeira, o som esta diminuindo, ou seja, eh o ataque da nota. Ligue a nota.
if(piezoState[i] == 0 && leitura2[i] > leitura1[i] && leitura2[i] >=PIEZOTHRESHOLD &&  leitura1[i] >= PIEZOTHRESHOLD){
noteOff(1,piezoNotes[i],0);
noteOn(1,piezoNotes[i],leitura2[i]/8 );
piezoAtual = i;
piezoState[i] = 1;
}
piezoInterval[i] = currentTime;
}

// Send a MIDI note-on message.  Like pressing a piano key
// channel ranges from 0-15
//  Ou seria channel << 4?
void noteOn(byte channel, byte note, byte velocity) {
  midiMsg( (0x90 | channel), note, velocity);
}

// Send a MIDI note-off message.  Like releasing a piano key
void noteOff(byte channel, byte note, byte velocity) {
  midiMsg( (0x80 | channel), note, velocity);
}
// Send a general MIDI message
void midiMsg(byte cmd, byte data1, byte data2) {
    digitalWrite(ledPin,HIGH);  // indicate we're sending MIDI data
    Serial.print(cmd, BYTE);
    Serial.print(data1, BYTE);
    Serial.print(data2, BYTE);
//    Serial.print(cmd);
//    Serial.print(" ");
//    Serial.print(int(data1));
//    Serial.print(" ");
//    Serial.print(int(data2));
//    Serial.println("");
  digitalWrite(ledPin,LOW);
}

 
Fotos










Algumas fontes tardias....

2 comentários:

Anônimo disse...

Olá!
Gostaria de saber se é possível interpretar um arquivo .mid no Arduino e converter em códigos para enviar a um sintetizador.
Abrir arquivos via cartão SD é fácil. Enviar códigos de notas e instrumentos também. Você saberia interpretar o arquivo .mid para "capturar" tais comandos?

Grande abraço!

Schiavoni disse...

Há várias APIs para a leitura de arquivo MIDI como, por exemplo, a do PortMedia. É possível ler tais arquivos manualmente sendo isto mais trabalhoso devido as várias versões de MIDI e algumas incompatibilidades no arquivo gerado por algumas ferramentas. Resumindo, é possível sim.