Cómo Construí un Instrumento Musical Electrónico con ESP32 y MIDI BLE

A primera vista, este proyecto parece un simple pad de teclado. Sin embargo, detrás de ese pequeño dispositivo hay un sistema capaz de emular una gran variedad de instrumentos musicales gracias al protocolo MIDI y a la conectividad Bluetooth Low Energy (BLE).

En este tutorial te mostraré cómo diseñé y construí mi propio instrumento electrónico, capaz de conectarse de forma inalámbrica a un smartphone y funcionar en tiempo real sin los molestos cables que suelen causar errores en dispositivos portátiles.

Lo mejor de todo es que hoy en día cualquier persona puede acceder a componentes electrónicos avanzados a precios accesibles. Así que quiero compartir contigo un curso intensivo de 4 pasos, basado en los mismos métodos que utilicé durante mi carrera de ingeniería para desarrollar proyectos complejos en la universidad.

1. Diseño de dispositivo electrónico

El primer paso fue diseñar la interfaz física que convertiría nuestras acciones en notas musicales. Para esto utilicé EasyEDA, una plataforma gratuita, sencilla y con librerías suficientes para proyectos de distintos niveles.

✔ ¿Qué diseñé exactamente?

  • Un teclado de 9 pulsadores configurados en pull-up.
  • Cada pulsador representa una entrada digital estable y libre de ruido eléctrico.
  • La configuración pull-up garantiza que el pin esté en un estado lógico alto cuando no se presiona, evitando valores flotantes.

Elegí esta configuración porque prefiero trabajar con estados activos bajos, y porque facilita la lectura del microcontrolador.

Una vez definidos los pulsadores, convertí el diseño a PCB y preparé el archivo para su fabricación. Mientras ese proceso corría, definí la lógica musical del instrumento.

Definición de Secuencias: cómo convertir 9 teclas en 27 notas

La música occidental se basa en 12 notas principales (7 naturales + 5 alteradas). Estas notas pueden repetirse en diferentes octavas, y la mayoría de instrumentos manejan entre 2 y 3 octavas útiles, por ejemplo instrumentos como flauta traversa, suele utilizar principalmente dos octavas, es decir, 24 notas.

Mi objetivo fue crear un instrumento de 27 notas, pero sin construir un teclado gigante. La solución fue implementar combinaciones de teclas, inspiradas en la lógica de instrumentos como la flauta.

✔ ¿Cómo funciona mi sistema?

  • 7 teclas principales → Do, Re, Mi, Fa, Sol, La, Si
  • 1 modificador de octava → cambia entre notas graves y agudas
  • 1 modificador de sostenido → activa notas alteradas (Do#, Re#, Fa#, Sol#, La#)

Esto permite:

  • Tocar dos octavas completas
  • Acceder a notas alteradas
  • Mantener un diseño compacto y fácil de usar

A diferencia de instrumentos como la flauta o el saxofón, aquí no existe un “activador” como el aire o el rasgueo. Por eso cada nota debe depender de una sola tecla principal, y los modificadores solo ajustan su comportamiento.

2. Construcción del Hardware: del diseño a la realidad

Con el diseño listo, pasé a la construcción física del instrumento.

✔ Proceso de fabricación

  • Corte CNC del PCB
  • Preparación de pistas
  • Montaje de pulsadores
  • Soldadura de conexiones
  • Integración con un ESP32-S3

Durante el proceso cometí un error común: configuré la CNC para cortar sobre el vector, en lugar de por dentro o por fuera. Esto redujo el ancho de las pistas, dejándolas más delgadas de lo ideal.

Afortunadamente, como trabajamos con señales de baja potencia, el circuito funcionó sin problemas, aunque no es lo más recomendable.

Tras verificar cada pin y conexión, el hardware quedó listo para la programación.

Conexiones:

ESP32S3Pines dispositivo MIDI
GNDGND
3.3VVcc
35Pin 1
36Pin 2
37Pin 3
38Pin 4
39Pin 5
40Pin 6
41Pin 7
42Pin 8
2Pin 9

3. Programación del Sistema: lógica musical y MIDI BLE

Para este proyecto utilicé un ESP32-S3, aunque cualquier ESP32 funciona igual porque todas las versiones incluyen funciones BLE similares.

✔ ¿Qué hace el programa?

  • Lee las 7 teclas principales
  • Aplica modificadores de octava y sostenido
  • Genera la nota correspondiente
  • Envía la señal vía MIDI BLE
  • Permite tocar notas por debajo del Do grave para mayor flexibilidad musical

La programación se basa en condiciones simples que combinan:

  • Nota base
  • Modificador de octava
  • Modificador de sostenido
  • Casos especiales para notas graves adicionales

Para diseñar el programa, utilicé la librería BLEMIDI para la capa de transporte, utilicé los archivos de forma local, por lo que la carpeta del proyecto terminará viéndose así:

Código main completo:

#include "BLEMIDI_Transport.h"
#include "hardware/BLEMIDI_ESP32.h"

BLEMIDI_CREATE_INSTANCE("MIDI_ESP32S3_DHCAST", MIDI);

const int pin_C = 2;
const int pin_D = 40;
const int pin_E = 39;
const int pin_F = 36;
const int pin_G = 41;
const int pin_A = 37;
const int pin_B = 35;
const int pin_M1 = 42;
const int pin_M2 = 38;

int key_value_C = 0;
int key_value_D = 2;
int key_value_E = 4;
int key_value_F = 5;
int key_value_G = 7;
int key_value_A = 9;
int key_value_B = 11;
int key_value_M1 = 12;
int key_value_M2 = 1;

int baseNote = 48; // 60 Do central

int lastPressedNote = 0;
int getPressedButtons();

void setup() {
  pinMode(pin_C , INPUT);
  pinMode(pin_D , INPUT);
  pinMode(pin_E , INPUT);
  pinMode(pin_F , INPUT);
  pinMode(pin_G , INPUT);
  pinMode(pin_A , INPUT);
  pinMode(pin_B , INPUT);
  pinMode(pin_M1 , INPUT);
  pinMode(pin_M2 , INPUT);
  BLEMIDI.begin();
  Serial.begin(115200);
  // put your setup code here, to run once:
}

void loop() {
  int iRet = getPressedButtons();
  Serial.printf( "\nKey Pressed Now %d",iRet);
  if(iRet != lastPressedNote and iRet != 0 and (lastPressedNote != (baseNote -1)) and (lastPressedNote != (baseNote -2)) and (lastPressedNote != (baseNote -3))  ){
    MIDI.sendNoteOff(lastPressedNote,127,1);
    MIDI.sendNoteOn(iRet,127,1);
    lastPressedNote = iRet; 
    Serial.printf( "\nMidi Sent %d",iRet);
  }else if(iRet == 0){
     MIDI.sendNoteOff(lastPressedNote,127,1);
    lastPressedNote = 0; 
   
    // MIDI.sendControlChange(124 , 0, 1);
    // MIDI.sendControlChange(125 , 0, 1);

    // MIDI.sendControlChange(120, 0, 1);
    // MIDI.sendControlChange(121, 0, 1);
    // MIDI.sendControlChange(64, 0, 1);
  }
  // MIDI.read();
  // put your main code here, to run repeatedly:
}

int getPressedButtons(){
  int key_C = 0, key_D = 0, key_E = 0, key_F = 0, key_G = 0, key_A = 0, key_B = 0;
  int notePressed = baseNote;
  if(digitalRead(pin_C)){
    key_C = 1;
  }
  if(digitalRead(pin_D)){
    key_D = 1;
  }
  if(digitalRead(pin_E)){
    key_E = 1;
  }
  if(digitalRead(pin_F)){
    key_F = 1;
  }
  if(digitalRead(pin_G)){
    key_G = 1;
  }
  if(digitalRead(pin_A)){
    key_A = 1;
  }
  if(digitalRead(pin_B)){
    key_B = 1;
  }
  // Serial.printf( "\nActual Keys Key C = %d, Key D = %d, Key E = %d, Key F = %d, Key G = %d, Key A = %d, Key B = %d, Key M1 = %d, Key M2 = %d ", key_C, key_D, key_E, key_F, key_G, key_A, key_B, digitalRead(pin_M1), digitalRead(pin_M2) );

  if(key_C == 1 or key_D == 1 or key_E == 1 or key_F == 1 or key_G == 1 or key_A == 1 or key_B == 1 ){
    if(digitalRead(pin_M1) and key_C == 1 and key_B == 1){
      notePressed -= 1;
      return notePressed;
    }
    if(digitalRead(pin_M1) and key_C == 1 and key_A == 1 and digitalRead(pin_M2)){
      notePressed -= 2;
      return notePressed;
    }
    if(digitalRead(pin_M1) and key_C == 1 and key_A == 1){
      notePressed -= 3;
      return notePressed;
    }

    int keyHaveMod = 0;
    if(key_C == 1){
      notePressed += key_value_C;
      keyHaveMod = 1;
    }else if(key_D == 1){
      notePressed += key_value_D;
      keyHaveMod = 1;
    }else if(key_E == 1){
      notePressed += key_value_E;
    }else if(key_F == 1){
      notePressed += key_value_F;
      keyHaveMod = 1;
    }else if(key_G == 1){
      notePressed += key_value_G;
      keyHaveMod = 1;
    }else if(key_A == 1){
      notePressed += key_value_A;
      keyHaveMod = 1;
    }else if(key_B == 1){
      notePressed += key_value_B;
    }

    if(digitalRead(pin_M1)){
      notePressed+=12;
    }
    if(digitalRead(pin_M2) and keyHaveMod == 1){
      notePressed++;
    }
    return notePressed;
  }else{
    return 0;
  }
}

Además, el uso de MIDI BLE ofrece una velocidad muy superior al antiguo protocolo MIDI 1.0, que funcionaba a solo 31.250 baudios. Con BLE podemos alcanzar velocidades de hasta 2 Mbps, dependiendo de la versión de Bluetooth.

4. Pruebas y Funcionamiento

Para probar el instrumento:

  1. Emparejé el ESP32 con mi smartphone usando la app MIDI + BLE.
  2. Abrí una aplicación compatible como BandLab y se selecciona un instrumento, si MIDI + BLE se emparejó correctamente, automáticamente debería poder escuchar los sonidos tocados en BandLab.
  3. Probé cada nota y verifiqué la respuesta en tiempo real.

El resultado fue sorprendentemente fluido y rápido, ideal para tocar melodías simples o experimentar con diferentes instrumentos virtuales.

Conclusión

Este proyecto demuestra lo accesible que es hoy en día construir un instrumento musical electrónico desde cero. Con un microcontrolador, algunos pulsadores y un poco de creatividad, puedes crear dispositivos únicos que se integran con tu smartphone y con cualquier software MIDI moderno.

Y si te interesa ver el instrumento en acción, te invito a visitar mi canal y escuchar la pieza completa que grabé con este dispositivo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll to Top