Unopad - Controlador Arduino MIDI com Ableton
Componentes e suprimentos
| × | 1 | ||||
| × | 9 | ||||
| × | 1 |
Ferramentas e máquinas necessárias
|
Aplicativos e serviços online
| ||||
| ||||
|
Sobre este projeto
Resumo
A maioria dos tutoriais e projetos para controladores Midi são baseados apenas em uma explicação do trabalho do Arduino, mas não tanto em usá-lo no próprio DAW. Quero criar um tutorial com todas as coisas necessárias em um só lugar. Com este projeto, eu queria ajudar iniciantes a entender melhor o processo de criação e uso de um controlador, e espero que seja útil para alguém.
Há muito tempo eu queria fazer um controlador midi e finalmente consegui e agora vou compartilhar o projeto com vocês. Eu usei um Arduino Uno que não tem a capacidade de enviar mensagens MIDI via USB, então programas especiais tiveram que ser usados para isso (serão explicados mais tarde neste texto).
As seções a seguir descreverão o circuito elétrico, o código do Arduino, bem como como se conectar a um computador e DAW, neste caso o Ableton.
Circuito
É um circuito muito simples. Usei 9 botões, mas não na matriz, porque queria a capacidade de pressionar vários botões (é mais fácil e tenho pinos digitais não usados - eu uso 9, na matriz seria 6).
Botão 3 ==> D2 Botão 2 ==> D3 Botão 1 ==> D4 Botão 6 ==> D5 Botão 5 ==> D6 Botão 4 ==> D7Botão 9 ==> D8 Botão 8 ==> Botão D9 7 ==> D10
Mapeamentos MIDI
Eu defini 9 notas MIDI, de 36 a 45, e NOTE_ON e NOTE_OFF.
Este tutorial de MIDI o ajudará a entender como você pode usar a linguagem MIDI para controlar qualquer dispositivo que use o protocolo MIDI.
#define NOTE_ONE 36 # define NOTE_TWO 37 // Defina todas as notas aqui. # define NOTE_ON_CMD 0x90 # define NOTE_OFF_CMD 0x80 # define MAX_MIDI_VELOCITY 127
MIDI via USB
Como o Arduino Uno não pode enviar notas MIDI para o DAW sozinho, devemos usar dois programas adicionais - LoopMidi e Hairless MIDI <-> Serial Bridge.
Com o LoopMidi, criamos uma porta MIDI virtual que podemos usar no Hairless Midi para conectar com a porta do Arduino.
Explicação do código
Eu criei a classe Button e a utilizo assim:
int NUMBER_BUTTONS =9; Botão Botão1 (4, NOTE_ONE); Botão Botão2 (3, NOTE_TWO); Botão Botão3 (2, NOTE_THREE); Botão Botão4 (7, NOTE_FOUR); Botão Botão5 (6, NOTE_FIVE); Botão Botão6 (5, NOTE_SIX); Botão Botão7 (10, NOTE_SEVEN); Botão Botão8 (9, NOTE_EIGHT); Botão Botão9 (8, NOTE_NINE); Botão * Botões [] {&Botão1, &Botão2, &Botão3, &Botão4, &Botão5, &Botão6 , &Button7, &Button8, &Button9};
Para saber mais sobre a implementação do botão, consulte Buttons.cpp.
Como não usamos resistores, apenas conectamos o botão ao pino digital e ao aterramento, usamos INPUT_PULLUP em vez de INPUT.
//Buttons.cpppinMode(_pin, INPUT_PULLUP);
A única parte complicada disso é que você não está procurando por um
ALTO
sinal como você pode supor - seu botão emitirá LOW
(0)
quando é pressionado. // Botão é pressionado if (state ==0) {midiNoteOn (Buttons [i] -> Nota, 127); } // O botão não é pressionado se (estado ==1) {}
Isso também significa que o estado inicial do botão é 1, não 0.
//Buttons.cpp _state =1;
Cada mensagem NOTE ON requer sua mensagem NOTE OFF correspondente. Quando o botão é pressionado, envia mensagem NOTE_ON. Quando o botão é liberado, ele envia a mensagem NOTE_OFF, então, além do estado inicial, adicionei o último estado lembrado ao código.
//Buttons.cpp _lastState =1;
Só enviamos mensagens MIDI se o estado atual for diferente do estado anterior.
//Buttons.cppif(state!=_lastState) {// ....}
Use essas duas funções para enviar mensagens MIDI. Os parâmetros de funções são note e midiVelocity (Eu usei a velocidade máxima).
void midiNoteOn (nota de byte, byte midiVelocity) {Serial.write (NOTE_ON_CMD); Serial.write (nota); Serial.write (midiVelocity);} void midiNoteOff (nota de byte, byte midiVelocity) {Serial.write (NOTE_OFF_CMD); Serial.write (nota); Serial.write (midiVelocity);}
Eu coloquei a lógica do programa na função
updateButtons
função. void updateButtons () {for (int i =0; i getButtonState (); // Botão pressionado if (state ==0) {midiNoteOn (Buttons [i] -> Nota, 127); } // O botão não é pressionado if (state ==1) midiNoteOff (Buttons [i] -> Nota, 0); }}
A função é chamada dentro do método de loop.
void loop () {if (NUMBER_BUTTONS! =0) updateButtons ();}
Use seu controlador com DAW (Ableton Live)
Como um iniciante no uso de DAWs, eu não sabia como conectar nada ali. Quando conectei meu Korg Nanokey, o próprio Ableton o reconheceu e eu poderia usar o controlador imediatamente. Isso (é claro) não era o caso com o controlador Arduino, já que ele não é um dispositivo HID e o PC ainda o reconhece como um Arduino.
Vou mostrar aqui como conectar e usar seu controlador Arduino MIDI no Ableton Live 10.
- Conecte-se com o Ableton
Abra loopMIDI e criar uma nova porta MIDI virtual como nas próximas imagens.
Abra o midiserial sem pelos e atribuir porta serial, saída MIDI e entrada MIDI como nas próximas imagens. Para a porta serial, escolhemos a porta Arduino Uno e, para entrada e saída de MIDI, usamos a porta MIDI virtual que criamos na etapa anterior.
Defina a taxa de transmissão com a mesma taxa em seu esboço do Arduino. Vá para Arquivo> Preferências , e lá você deve definir a taxa de transmissão.
Se estiver tudo bem feito, você pode depurar a mensagem MIDI enviada pelo controlador. Pressione o botão no controlador e verifique se há mensagens MIDI recebidas no MIDI sem fio.
Não feche o MIDI sem pelos!
Abra o Ableton Live e vá para a aba Options, então Preferences. A guia Link MIDI deve ser semelhante a este exemplo.
Para verificar se tudo está bem conectado e se o Ableton está lendo mensagens MIDI, vamos dar uma olhada no canto superior direito do Ableton. A caixa superior deve piscar quando o botão no controlador é pressionado, conforme mostrado no próximo exemplo.
O controlador está pronto para uso!
- Use o controlador como rack de bateria ou Teclado
Selecione a trilha MIDI. No Monitor seção escolha Em , em vez de Auto , e em MIDI para escolha a saída do seu alto-falante. Você deve ouvir seu teclado agora. O mesmo deve ser feito para o rack da bateria.
Meu projeto concluído
Usei uma caixa de alto-falante velha para este projeto e um pouco de plástico que encontrei em casa. Cortei ambas as placas de plástico nas dimensões da caixa e fiz furos para os botões e um LED que adicionarei mais tarde.
Também tenho outro alto-falante antigo com o mesmo case que irei usar para outro controlador MIDI, desta vez com botões e joysticks.
Para fazer
- Pressione longamente o botão para mudar para o modo CC.
Código
- MidiDrumPad.ino
- Buttons.cpp
- Botões.h
MidiDrumPad.ino Arduino
#include "Buttons.h" // ------ Notas ------------- # define NOTE_ONE 36 # define NOTE_TWO 37 # define NOTE_THREE 38 # define NOTE_FOUR 39 # define NOTE_FIVE 40 # define NOTE_SIX 41 # define NOTE_SEVEN 42 # define NOTE_EIGHT 43 # define NOTE_NINE 44 # define NOTE_ON_CMD 0x90 # define NOTE_OFF_CMD 0x80 # define MAX_MIDI_VELOCITY 127 // ------------------ ------ int NUMBER_BUTTONS =9; Botão Botão1 (4, NOTE_ONE); Botão Botão2 (3, NOTE_TWO); Botão Botão3 (2, NOTE_THREE); Botão Botão4 (7, NOTE_FOUR); Botão Botão5 (6, NOTE_FIVE); Botão Botão6 (5, NOTE_SIX); Botão Botão7 (10, NOTE_SEVEN); Botão Botão8 (9, NOTE_EIGHT); Botão Botão9 (8, NOTE_NINE); Botão * Botões [] {&Botão1, &Botão2, &Botão3, &Botão4, &Botão5, &Botão6 , &Button7, &Button8, &Button9}; int red_light_pin =11; int green_light_pin =12; int blue_light_pin =13; void setup () {Serial.begin (9600);} void loop () {if (NUMBER_BUTTONS! =0) updateButtons ( );} void updateButtons () {for (int i =0; igetButtonState (); // Botão pressionado if (state ==0) {midiNoteOn (Buttons [i] -> Nota, 127); } // O botão não é pressionado if (state ==1) {midiNoteOff (Buttons [i] -> Nota, 0); }}} void RGB_color (int red_light_value, int green_light_value, int blue_light_value) {analogWrite (red_light_pin, red_light_value); analogWrite (green_light_pin, green_light_value); analogWrite (blue_light_pin, blue_light_value);} // Enviar nota MIDI ONvoid midiNoteOn (nota de byte, byte midiVelocity) {Serial.write (NOTE_ON_CMD); Serial.write (nota); Serial.write (midiVelocity);} // Enviar nota MIDI OFFvoid midiNoteOff (nota de byte, byte midiVelocity) {Serial.write (NOTE_OFF_CMD); Serial.write (nota); Serial.write (midiVelocity);}
Buttons.cpp Arduino
#include "Buttons.h" Button ::Button (int pin, nota curta) {_pin =pin; pinMode (_pin, INPUT_PULLUP); _estado =1; _lastState =1; Note =note;} int Button ::getButtonState () {int returnValue =-1; estado interno =digitalRead (_pin); if (state ==_lastState) retorna 5; if (state! =_lastState) {if (state ==0) {returnValue =0; } else {returnValue =1; }} _lastState =estado; return returnValue;}
Buttons.h Arduino
#ifndef Buttons_h # define Buttons_h # include// Botão (Número do Pin, Número da Nota) class Button {public:Button (int pin, short note); int getButtonState (); int Note; privado:int _pin; nota curta; int _state; int _lastState;}; # endif
Você pode baixar o código do meu Github
https://github.com/sadreactonly/MidiDrumpadEsquemas
Processo de manufatura
- Luzes de dimerização com PWM usando o botão de ação
- Jogo Arduino Gyroscope com MPU-6050
- Sensor DHT11 com LEDs e um alto-falante Piezo
- Homem de Ferro
- Sensor de obstáculo simples com Arduino
- Encontre-me
- Controle do umidificador Arduino
- Cubo de LED 4x4x4 com Arduino Uno e 1sheeld
- Joystick Arduino
- Pedômetro (Arduino 101)