Cómo descifrar este código?

Buenas gente.
Estaba probando piezoeléctricos con Arduino Nano, y vi un código por la web de un proyecto de batería electrónica con varios programas. El problema que tengo es que al golpear el piezoeléctrico, suenan varios tambores y platillos a la vez en el programa. Así que decidí borrar algunas cosas de la siguiente línea de código (más abajo está el código original):
unsigned char PadNote[15] = {38};
Borré los otros números porque estaban destinado a los otros tambores/platillos, así que dejé solo uno (el 38) que corresponde al redoblante, y funciona bien porque sólo suena dicho tambor.
Pero la idea es conectarle más piezoeléctricos y que suene cada tambor de manera individual y, además, suene más/menos fuerte dependiendo de la intensidad del golpe al piezoeléctrico (obvio que el piezo está protegido para no golpearlo directamente).

A continuación, detallo todo lo que tengo para dicho proyecto:

  • FL Studio 20 (Sotware de edición de sonido)
  • EZDrummer 2 (batería virtual)
  • LoopBe1 (Cable virtual MIDI)
  • Hairless MIDI Serial (Software comunicación Serial entre Arduino y el software de edición de sonido).
  • Arduino Nano
  • Un piezoeléctrico conectado al pin análogo A0.

Y el siguiente código para Arduino que no lo entiendo:

unsigned char PadNote[15] = { 38,35,44,55,50,45,47,0,0,0,0,0,0,0,0 }; // 38 granadero 35 bombo 44 hi hat 55 platillo 45 platillo 57 tonton MIDI
int PadCutOff[15] = { 400,400,400,400,400,400,400,1000,600,600,600,600,600,600,600 }; // Sensibilidad con respecto a los tonos
int MaxPlayTime[15] = { 30,40,10,20,10,10,10,90,90,90,90,90,90,90,90 }; // Cantidad de golpes por milisegundos
#define midichannel 0; // canal MIDI 
boolean VelocityFlag = true; // velocidad del golpe


boolean activePad[15] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
int PinPlayTime[15] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

unsigned char status;

int pin = 0;
int hitavg = 0;

unsigned char PadNote[15] = { 38,35,44,55,50,45,47,0,0,0,0,0,0,0,0 }; // 38 granadero 35 bombo 44 hi hat 55 platillo 45 platillo 57 tonton MIDI
int PadCutOff[15] = { 400,400,400,400,400,400,400,1000,600,600,600,600,600,600,600 }; // Sensibilidad con respecto a los tonos
int MaxPlayTime[15] = { 30,40,10,20,10,10,10,90,90,90,90,90,90,90,90 }; // Cantidad de golpes por milisegundos
#define midichannel 0; // canal MIDI 
boolean VelocityFlag = true; // velocidad del golpe


boolean activePad[15] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
int PinPlayTime[15] = {
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

unsigned char status;

int pin = 0;
int hitavg = 0;

void setup() {
  Serial.begin(57600); // connect to the serial port 115200
}


void loop() {
  for (int pin = 0; pin < 7; pin++) {
    hitavg = analogRead(pin);

    if ((hitavg > PadCutOff[pin])) {
      if ((activePad[pin] == false)) {
        if (VelocityFlag == true) {

          hitavg = (hitavg / 8) - 1; // Upper range
        }
        else {
          hitavg = 127;
        }

        MIDI_TX(144, PadNote[pin], hitavg);
        PinPlayTime[pin] = 0;
        activePad[pin] = true;
      }
      else {
        PinPlayTime[pin] = PinPlayTime[pin] + 1;
      }
    }
    else if ((activePad[pin] == true)) {
      PinPlayTime[pin] = PinPlayTime[pin] + 1;

      if (PinPlayTime[pin] > MaxPlayTime[pin]) {
        activePad[pin] = false;
        MIDI_TX(128, PadNote[pin], 127);
      }
    }
  }
}

void setup() {
  Serial.begin(57600); // connect to the serial port 115200
}


void loop() {
  for (int pin = 0; pin < 7; pin++) {
    hitavg = analogRead(pin);

    if ((hitavg > PadCutOff[pin])) {
      if ((activePad[pin] == false)) {
        if (VelocityFlag == true) {

          hitavg = (hitavg / 8) - 1; // Upper range
        }
        else {
          hitavg = 127;
        }

        MIDI_TX(144, PadNote[pin], hitavg);
        PinPlayTime[pin] = 0;
        activePad[pin] = true;
      }
      else {
        PinPlayTime[pin] = PinPlayTime[pin] + 1;
      }
    }
    else if ((activePad[pin] == true)) {
      PinPlayTime[pin] = PinPlayTime[pin] + 1;

      if (PinPlayTime[pin] > MaxPlayTime[pin]) {
        activePad[pin] = false;
        MIDI_TX(128, PadNote[pin], 127);
      }
    }
  }
}

void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY) {
  status = MESSAGE + midichannel;
  Serial.write(status);
  Serial.write(PITCH);
  Serial.write(VELOCITY);
}

Dejo una imagen del Hairless MIDI para que vean los valores que arroja cada vez que es golpeado el piezoeléctrico:
Hairless MIDI Sólo redoblante

Muchas gracias por su tiempo y por su ayuda.

Moderador:
Editado el código con sangría adecuada para mejor lectura
Editado el título de acuerdo a punto 5 de las normas.

Sin entender lo que estás haciendo, yo creo que el problema es el siguie:
Tienes un bucle for que mirará la intensidad del golpeteo
Preguntas si es mayor a "padcutoff" pero como lo preguntas varias veces (por el bucle "for") pues te sonarán diferentes velocidades y notas.
Otra cosa es que bajo el bucle "for" quizá deberías esperar al reposo de la puerta analógica, es decir un

while (analogRead(pin)>200) ; 

Para que no te repita notas.
Pero ya te digo que es desde el desconocimiento de lo que intentas hacer

2 Likes

Hola @DanX3 gracias por tu respuesta.

Algo que noté cuando golpeo despacio el piezoeléctrico es que el tambor suena varias veces como si lo hubiese golpeado 4 o 5 veces seguidas y rápidas. Eso también se puede observar en el "Hairless MIDI", el cual los circulitos grises se encienden de color verde reiteradas veces (como parpadeando, a pesar de que doy un sólo golpe suave. Dichos circulitos se encienden cuando detectan que golpeo el piezoeléctrico). Cuando golpeo más fuerte el piezoeléctrico, esto no ocurre.

Seguramente eso debe ser por lo que mencionas en tu respuesta, que quizá deberías esperar al reposo de la puerta analógica para que no repita notas, verdad? (Corregirme si me equivoco).

Muchas gracias.

Edita en tu posteo la imagen que ha fallado por alguna razón.

No veo en el código la línea que mencionas. El código está tal cual como lo encontré en un foro.

te esta sugiriendo que hagas eso.

Si, y le respondí a @DanX3 . Ahora en éstos días lo pruebo, ya que por temas laborales no tuve tiempo de realizar dicha prueba. Ahora, no entiendo qué es lo que querés que edite de nuevo?

Lo que me refiero es que el bucle se ejecuta muy rapido y entonces da tiempo a mandar varios mensajes MIDI en cada golpeteo.
Para ello, cuando haces:

 MIDI_TX(144, PadNote[pin], hitavg);

Le incluyas abajao la linea que pegué para esperar a que la puerta analógica no tenga lectura del gopeteo quedando así:

 MIDI_TX(144, PadNote[pin], hitavg);
 while (analogRead(pin)>200) ; 

Así te aseguras que no hay multiples mensajes MIDI enviándose en cada golpe.
Esa linea "while" esperará a que la lectura analógica baje de 200 para continuar. mira en reposo cuando lee realmente porque igual en reposos es más de 200.
Recuerda que es desde mi desconocimiento y sin probarlo pero por intuición creo que el problema viene de ahí.
Saludos.

Hola @DanX3, muchas gracias por tu respuesta. El mensaje de "no entiendo qué es lo que querés que edite de nuevo?" era para @Surbyte que me pedía que edite el posteo porque había fallado una imagen y no sabía cuál era la que fallaba.
Con respecto a tu respuesta, es verdad que me toma varias notas (como te había comentado anteriormente), ya que cuando doy 1 (un) golpe al piezo, suena varias veces y debe ser por eso que mencionas. Voy a probar escribir el "while" tal cual como me lo pusiste en tu respuesta y después te comento cómo me fue.

Hola @Danx3. Probé lo de poner la línea de código "while (analogRead(pin)>200);" pero el resultado fue negativo, ya que al dar un golpe, a los pocos milisegundos daba otro. Y si quería dar golpes rápidos, no los detectaba. Probé con poner un valor inferior a 200 pero seguía con el mismo problema.

el problemas tiene que ver con la parte de cómo esta construido los sensores y no de programación, suele darse el problema por las vibraciones que se producen al golpear, es necesario que el sensor o piezo esté bien sujeto de modo que quede como un sandwich y el sensor en medio.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.