Entradas analogicas dejan de funcionar

Hola a todos! bueno les comento, hice una bateria electonica casera, estoy usan un Arduino Mega 2560 con pisoelectricos como sensores, todo funciona bien hasta que luego de tocar por 1 o 2 minutos, dejan de funcionar algunas entradas analogicas y debo resetearlo.

(Aclaracìón: Dejan de funcionar por un tiempo y luego vuelven a funcionar)
Me podran ayudar, me volvi loco buscando soluciones
Gracias

Codigo:

unsigned char PadNote[11] = {10,35,44,55,50,45,57,43,51,127,126};         // MIDI notes from 0 to 127 (Mid C = 60)

int PadCutOff[11] =          {600,1,600,1000,600,600,1000,600,600,600,600};           // Minimum Analog value to cause a drum hit

int MaxPlayTime[11] =        {30,1,10,20,30,10,30,10,30,30,30};               // Cycles before a 2nd hit is allowed

#define  midichannel	0;                              // MIDI channel from 0 to 15 (+1 in "real world")

boolean VelocityFlag  = true;                           // Velocity ON (true) or OFF (false)





//*******************************************************************************************************************
// Internal Use Variables			
//*******************************************************************************************************************

boolean activePad[11] = {
  0,0,0,0,0,0,0,0,0,0,0};                   // Array of flags of pad currently playing
int PinPlayTime[11] = {
  0,0,0,0,0,0,0,0,0,0,0};                     // Counter since pad started to play

unsigned char status;

int pin = 0;     
int hitavg = 0;

//*******************************************************************************************************************
// Setup			
//*******************************************************************************************************************

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

//*******************************************************************************************************************
// Main Program			
//*******************************************************************************************************************

void loop() 
{
  for(int pin=0; pin < 11; pin++)
  {
    hitavg = analogRead(pin);                              // read the input pin

      if((hitavg > PadCutOff[pin]))
    {
      if((activePad[pin] == false))
      {
        if(VelocityFlag == true)
        {
          //          hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin]));    // With full range (Too sensitive ?)
          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); 
      }
    }
  } 
}


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

Moderador:
Por favor, lee las Normas del foro y edita tu código/error usando etiquetas de código.
Ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en </>


Primero corrige la presentación del código como te pidió @Surbyte. Por favor usa la opción Auformato del menú Herramientas de la IDE antes de volver a copiar y pegar el código así nos facilitas su lectura.

Después prueba quitando el else de la sentencia

else if((activePad[pin] == true))

O sea, que quede así

if((activePad[pin] == true))

Perdon, ya esta!

Listo! Ya puse bien el codigo.
Con respecto a la solucion de eliminar "else" lo que hace es dejar encendido el Serial RX

aaa

Bueno, no era por ahí... :man_facepalming:t2:

Al margen, revisa

hitavg = (hitavg / 8) -1 ;

porque cuando hitavg sea 0 la pondrías en -1 (que a nivel de byte sería 255) y no es un valor de velocity válido para MIDI (el rango es 0 - 127)
Además el máximo valor que puede leerse del ADC es 1023, que dividido 8 arroja como resultado 127 porque es una división entera y sin redondeo por lo que el decremento no es necesario.

Te conviene cambiar

status = MESSAGE + midichannel;

por

status = MESSAGE | midichannel; // OR 

Tienes declarada una variable global pin que no es necesaria y presta a confusión, te aconsejo que la elimines.

No encuentro otro problema por ahora.

Saludos

Agrego:
Tienes un error

#define midichannel 0;

No lleva punto y coma final.

Tienes un condicional basado el VelocityFlag cuyo valor nunca cambia. Yo lo quitaría.

Si quieres, prueba esto (es lo mismo pero más "ordenado")

struct pad_t {
  byte padNote;
  int padCutOff;
  byte maxPlayTime;
  byte pinPlayTime;
  bool activePad;
};

pad_t pinData[11] = {
    {10, 600, 30, 0, false},
    {35, 1, 1, 0, false},
    {44, 600, 10, 0, false},
    {55, 1000, 20, 0, false},
    {50, 600, 30, 0, false},
    {45, 600, 10, 0, false},
    {57, 1000, 30, 0, false},
    {43, 600, 10, 0, false},
    {51, 600, 30, 0, false},
    {127, 600, 30, 0, false},
    {126, 600, 30, 0, false}
  };

const byte MIDI_CHANNEL	= 0; // MIDI channel from 0 to 15 (+1 in "real world")
const byte NOTE_ON = 0x90;  // 144 decimal
const byte NOTE_OFF = 0x80;  // 128 decimal

byte status;

int hitavg = 0;

void MIDI_TX(byte message, byte pitch, byte velocity);

void setup() {
  Serial.begin(57600);
}

void loop() {
  for (int pin=0; pin < 11; pin++) {
    hitavg = analogRead(pin);
    if (hitavg > pinData[pin].padCutOff) {
      if (!pinData[pin].activePad) {
        hitavg = (hitavg / 8); // Upper range
        MIDI_TX(NOTE_ON, pinData[pin].padNote, hitavg); 
        pinData[pin].pinPlayTime = 0;
        pinData[pin].activePad = true;
      }
      else {
        pinData[pin].pinPlayTime++;
      }
    }
    else if(pinData[pin].activePad) {
      pinData[pin].pinPlayTime++;
      if(pinData[pin].pinPlayTime > pinData[pin].maxPlayTime) {
        pinData[pin].activePad = false;
        MIDI_TX(NOTE_OFF, pinData[pin].padNote, 127); 
      }
    }
  } 
}

void MIDI_TX(byte message, byte pitch, byte velocity) {
  status = message | MIDI_CHANNEL;
  Serial.write(status);
  Serial.write(pitch);
  Serial.write(velocity);
}

Agrego:
Simulé el código en Wokwi y corre correctamente aunque la nota 35 se dispara y no corta nunca, el problema es que tiene el umbral de disparo fijado en 1 (o sea que está con demasiada sensibilidad) al igual que la duración (excesivamente corta). Otras 2 con problemas son la 55 y 57 que creo que tienen el umbral demasiado alto y nunca se disparan.

Saludos

Funciona perfecto!!! No se como agradecertelo!
Tuve que modificar exactamente eso que me dijiste al final y nada mas, que alegria!
Gracias!

1 Like

Hola! perdon estoy lidiando hace unos dias con un problema, al tocar una nota talvez suena otra y varia sgun la intensidad del golpe tambien, que podra ser? ya revise cables y conexiones, mismo desconecto la nota que suena de mas y la sigue haciendo sonar.

Es raro...
Probá agregando

Serial.flush();

al final de MIDI_TX().
Ojo, es prueba, no se si va a mejorar o empeorar.

¿Qué código estás usando?
El #1 corregido o el #8?

El corregido! ahora pruebo

No cambio nada, cuando me lo pasaste funcionaba perfecto, yo creo que el problema es de conexiones, pero la verdad no encuentro nada

Corregiste esto

hitavg = (hitavg / 8) -1 ;

No?
Va sin "-1"

Lo raro es que cambie la nota, postea el código que tenés cargado y lo revisamos

Sisi, lo cambié.
Específicamente lo que pasa es en la nota 9 al pegarle fuerte suena la nota 10
Adjunto el código:

struct pad_t {
  byte padNote;
  int padCutOff;
  byte maxPlayTime;
  byte pinPlayTime;
  bool activePad;
};

pad_t pinData[11] = {
    {10, 600, 30, 0, false},
    {35, 600, 30, 0, false},
    {44, 600, 30, 0, false},
    {55, 600, 30, 0, false},
    {50, 600, 30, 0, false},
    {45, 600, 30, 0, false},
    {57, 600, 30, 0, false},
    {43, 600, 30, 0, false},
    {15, 600, 30, 0, false},
    {65, 600, 30, 0, false},
    {126, 600, 30, 0, false}
    
    
  };

const byte MIDI_CHANNEL  = 0; // MIDI channel from 0 to 15 (+1 in "real world")
const byte NOTE_ON = 0x90;  // 144 decimal
const byte NOTE_OFF = 0x80;  // 128 decimal

byte status;

int hitavg = 0;

void MIDI_TX(byte message, byte pitch, byte velocity);

void setup() {
  Serial.begin(57600);
}

void loop() {
  for (int pin=0; pin < 11; pin++) {
    hitavg = analogRead(pin);
    if (hitavg > pinData[pin].padCutOff) {
      if (!pinData[pin].activePad) {
        hitavg = (hitavg / 8); // Upper range
        MIDI_TX(NOTE_ON, pinData[pin].padNote, hitavg); 
        pinData[pin].pinPlayTime = 0;
        pinData[pin].activePad = true;
      }
      else {
        pinData[pin].pinPlayTime++;
      }
    }
    else if(pinData[pin].activePad) {
      pinData[pin].pinPlayTime++;
      if(pinData[pin].pinPlayTime > pinData[pin].maxPlayTime) {
        pinData[pin].activePad = false;
        MIDI_TX(NOTE_OFF, pinData[pin].padNote, 127); 
      }
    }
  } 
}

void MIDI_TX(byte message, byte pitch, byte velocity) {
  status = message | MIDI_CHANNEL;
  Serial.write(status);
  Serial.write(pitch);
  Serial.write(velocity);
  Serial.flush();
}

:interrobang:

No tiene sentido. La verdad no se me ocurre la causa, salvo que se esté "metiendo" ruido, algo al respecto de eso explican en la hoja de datos del micro (al menos en la del 328).

Olvidate! me ayudaste un millon, esto es tema de conexiones para mi, Gracias!

Hola a todos! Les cuento, hice una bateria electrica con sensores "Pisoelectricos" y hay 3 notas que activan otras segun la intensidad del golpe, quisiera saber como podria solucionarlo, muchas gracias!

:warning:
Código corregido

Tu publicación fue ** MOVIDA ** a su ubicación actual ya que es más adecuada.

¿Podría también tomarse unos minutos para Aprenda a usar el foro .

Moderador:
Por favor, lee las Normas del foro.
Si posteas en el foro en inglés usa idioma inglés para expresarte.
Si escribes en español debes usar el foro Arduino en español.
Ya tienes otro hilo, cómo es posible que vuelvas a equivocarte y lo postees en el foro en inglés?

Tu crees que con las 3 líneas que has escrito incluido el Gracias, uno puedo saber como responderte?
Por favor, lee las normas, agrega código, enlaces, y toda la información que ayuda a entender lo que estas haciendo.

Este tema debería ser continuación de este otro