Arduino edrum Midi Modul --> Verzögerung, wenn Displayanzeige ein

Hi zusammen,

ich hab einen Code geschrieben, über den ich die Schläge auf meinem Edrum in Midi-Noten umwandle.
Das edrum besteht aus ca. 8 PADs in denen sich Piezos befinden.
Je nach Stärke des Schlags wird eine Midi-Note erzeugt und per Midi-Out an meinen Windows-PC gesendet.
Dort wird dann der Schlagzeugsound erzeugt.

Mein Problem:
Ich will verschiedene Parameter einstellbar machen und habe mir deshalb ein Display besorgt (ein TM1638).
Zum Einstellen verwende ich einen Drehregler (kwmobile Rotary Encoder KY-040).
Wenn ich nun aber den Displaycode in den Main-Loop einbaue (im Code-Beispiel sind die Passagen auskommentiert) habe ich sofort eine Verzögerung beim Schlagzeugspielen, d.h. ich hau aufs Pad und der Ton kommt leicht verzögert.
Klar: Das Display benötigt auch eine gewisse Zeit zum Aktualisieren.
Wenn ich den Display-Code rauslösch, funktioniert alles tadellos.

Daher meine Frage:
Gibt es irgendeine bessere Methode, das Display zu integrieren, ohne das ich eine Verzögerung hab?
z.B. dass sich das Display nicht bei jedem Loop refreshed, sondern nur wenn man was daran einstellt und ansonsten aus dem Loop irgendwie rausspringt?

Hier der aktuelle Code (im Beispiel nur mit 2 Piezos):

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MIDI
#include <HardwareSerial.h>
#include <ArduMIDI.h> //<-- Include ArduMIDI Library.
//Create new instance of ArduMIDI library:
ArduMIDI midi = ArduMIDI(Serial, CH1);

//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Einstellpoti
int pinCLK = 5; // Connected to CLK on KY-040
int pinDT = 3; // Connected to DT on KY-040
int encoderPosCount = 0; 
int pinCLKLast;
int aVal;
boolean bCW;


//++++++++++++++++++++++++++++++++++++++++++++++++++++++ Display
#include <TM1638.h>
const int strobe = 7;
const int clock = 9;
const int data = 8;
int dots = 0x0; // display all decimal points, value in hexadecimal
int leds = 0xFF; // mask to display LEDS
byte keys; // key value
double number; // number to display
// define a module
TM1638 module(data, clock, strobe);

// ++++++++++++++++++++++++++++++++++++ Variablen für Grundfunktion
#define NUM_PIEZOS 2
// Default-Thresholds pro Pad
unsigned short thresholdMap[NUM_PIEZOS];
// Default-Noten pro Pad
unsigned short noteMap[NUM_PIEZOS];
// Dynamik pro Pad
unsigned short sensMap[NUM_PIEZOS];
// Trigger-Sensibilität pro Pad (Einstellen, wenn Doppeltrigger)
unsigned short trigMap[NUM_PIEZOS];
// Array zur Aufzeichnung der zuletzt ausgelösten Midi-Noten pro Pad
unsigned long lastNoteTime[NUM_PIEZOS];
// Array zur Aufzeichnung der Peaks pro Pad
unsigned long peakList[NUM_PIEZOS];
//Default-Triggerpad (wird später durch Schlagen des Pads ausgewählt)
int ctrl_slot = 1;  
// Default Einstellmodus
int mode_int=1;
// Default Display Modus-Anzeige
String mode="";
String strOut="";
// Default-Einstellwert Einstellpoti
int cur_val=0;
// Default Programm (Drumset)
int prog_def=1;


void setup() {
  // Display zurücksetzen
  module.clearDisplay();
  // Midi starten
  midi.begin();
  // Einstellpoti initialisieren
  pinMode (pinCLK,INPUT);
  pinMode (pinDT,INPUT);
  pinCLKLast = digitalRead(pinCLK);     
  // Default-Werte setzen
  // 1. Threshold
  for(short i=0; i<NUM_PIEZOS; ++i) {
    thresholdMap[i]=40; 
    sensMap[i] = 40; 
    lastNoteTime[i] = 0;  
    trigMap[i]=5;                                                                 
  }
  // 2. Noten
  noteMap[0]=36;
  noteMap[1]=38;
}

 
void loop () {
  // Tasten auslesen
  /*
  switch(keys){
    case 0:
      break;
    case 1:
      mode="prog";
      mode_int=1;
      break;
    case 2:
      mode="note";
      mode_int=2;
      break;
    case 4:
      mode="thre";
      mode_int=3;
      break;
    case 8:
      mode="sens";
      mode_int=4;
      break;
    case 16:
      mode="trig";
      mode_int=5;
      break;
    case 32:
      mode="load";
      mode_int=6;
      break;
    case 64:
      mode="save";
      mode_int=7;
      break;
    case 128:
      //OK
      break;    
  }
  //gedrückte Taste auslesen
  getKeyPressed();
  */
  unsigned long currentTime = millis();
  // Einstellpoti auslesen
  aVal = digitalRead(pinCLK);
  if (aVal != pinCLKLast) {
    if (digitalRead(pinDT) != aVal) { // Means pin A Changed first - We're Rotating Clockwise
      ctrl(1, mode_int);
    } else {// Otherwise B changed first and we're moving CCW
      ctrl(0, mode_int);
    }
  } 
  pinCLKLast = aVal;
  
  for(short i=0; i<NUM_PIEZOS; ++i) {
    // Piezowerte des gerade betrachteten Pads aufnehmen
    int piezoWert=analogRead(i);

    if (piezoWert > 120) {
      ctrl_slot=i;
    }
    // Display-Anzeige aktualisieren
    // Aktuellen Wert der Arrays für das zuletzt geschlagene Pad auslesen
    switch(mode_int){
      case 1:
        //cur_val=tmp_val;
        break;
      case 2:
        cur_val=noteMap[ctrl_slot];
        break;
      case 3:
        cur_val=thresholdMap[ctrl_slot];
        break;
      case 4:
        cur_val=sensMap[ctrl_slot];
        break;
      case 5:
        cur_val=trigMap[ctrl_slot];
        break;
    }
      
    // Wert lesbar für Display machen
    if (cur_val<10) {
      strOut=mode+" 00"+cur_val;
    } else if (cur_val <100) {
      strOut=mode+" 0"+cur_val;
    } else {
      strOut=mode+" "+cur_val;
    }
    // Ausgabe am Display:
    //module.setDisplayToString(strOut);
    
    unsigned long currentTime = millis();
    if (piezoWert > thresholdMap[i]) {
        recordNewPeak(i, piezoWert);
    } 
  }
}


void recordNewPeak(short slot, short newPeak) {
    if (newPeak > peakList[slot]) {
      peakList[slot]=newPeak;
    } else {
      fireNote(slot);
      peakList[slot]=thresholdMap[slot];                                                                                                               
      ;
    }
}

void fireNote(short slot) {
  //Höchsten aufgezeichneten Wert abrufen
  //Aber nur Note senden, wenn der Mindestabstand zwischen zwei Noten für den Slot eingehalten wurde
  unsigned long currentTime = millis();
  if (currentTime - lastNoteTime[slot] > trigMap[slot]) {
    short velo=map(peakList[slot], 0, 1023, sensMap[slot], 127);
    midi.noteOn(CH1, noteMap[slot], velo);
    midi.noteOff(CH1, noteMap[slot]);
    unsigned long currentTime = millis();
    lastNoteTime[slot]=currentTime;
  }
}

void getKeyPressed(){
  keys = module.getButtons();
  //Serial.println(keys);
  // light the LED
  module.setLEDs(keys & leds);
}

void ctrl(short dir, short mode_int) {
  // Plus
  switch (mode_int) {
    case 1:
      //ProgramChange
      if (dir>0) {
        if (prog_def < 21) {
          prog_def=prog_def+1;
        }
      } else {
        if (prog_def > 0) {
          prog_def=prog_def-1;
        }
      }
      cur_val=prog_def;
      midi.programChange(CH1, prog_def);
    break;
    case 2:
      if (dir>0) {
        //Note-Up
        noteMap[ctrl_slot]=noteMap[ctrl_slot]+1;
      } else {
        if (noteMap[ctrl_slot]>0) {
          noteMap[ctrl_slot]=noteMap[ctrl_slot]-1;
        }
      }
      cur_val=noteMap[ctrl_slot];
      break;
    case 3:
      if (dir>0) {
        //Threshold-Up
        thresholdMap[ctrl_slot]=thresholdMap[ctrl_slot]+1;
      } else {
        //Threshold-Down
        if (thresholdMap[ctrl_slot]>0) {
          thresholdMap[ctrl_slot]=thresholdMap[ctrl_slot]-1;
        }
      }
      cur_val=thresholdMap[ctrl_slot];
      break;
    case 4:
      if (dir>0) {
        //Sensibility-Up (=Dynamik Down)
        if (sensMap[ctrl_slot]<110) {
          sensMap[ctrl_slot]=sensMap[ctrl_slot]+1;
        }
      } else {
        //Sensibility-Down (=Dynamik Up)
        if (sensMap[ctrl_slot]>0) {
          sensMap[ctrl_slot]=sensMap[ctrl_slot]-1;
        }
      }
      cur_val=sensMap[ctrl_slot];
      break;
    case 5:
      if (dir>0) {
        //Trigger-Sens Up
        if (trigMap[ctrl_slot]<81) {
          trigMap[ctrl_slot]=trigMap[ctrl_slot]+1;
        }
      } else {
        //Trigger-Sens Down
        if (trigMap[ctrl_slot]>0) {
          trigMap[ctrl_slot]=trigMap[ctrl_slot]-1;
        }
      }
      cur_val=trigMap
      [ctrl_slot];
      break;
  }
}

Bin für jeden Tipp dankbar!

Grüßle
Daniel

Du willst in Deinem Sketch zwischen Einstellmodus und Drummodus unterscheiden.

Da musst Du Dir eine ANzeige machen, in welchem Modus Du bist. Steuern kannst Du das z.B. über den Taster des Drehgebers oder über einen Extra taster (ist evtl. einfacher) der zwischen beiden Modi umschaltet.
Im Einstellungsmodus kannst Du Deine Parameter mit dem Display ändern und dann stellt der nächste Druck in den Drummodus und da ist das Display uninteressant, nur Deine Drums.

Gruß Tommy

Du machst die Displayausgabe anscheinend viel zu oft... in jedem loop()-Durchgang, und dann noch in einer for-Schleife

Bastel Dir eine Ausgabe-Methode zusammen, wo die Ausgabe z.B. nur aller 200ms erfolgt :wink:

Ganz einfach so:

if (wert!=alterWert)
{
schreibeNeuenWertaufsDisplay();
alterWert=wert;
}

Das Ganze kombiniert man mit bissel geschicktem Timing, dann reicht die Zeit sogar für ein Grafikdisplay.
Grade bei Midi kommts drauf an, ein gutes Timing zu erreichen, daher tut man nur dann "andere" Dinge, wenn die auch wirklich nötig sind, und passt den richtigen Zeitpunkt dafür ab.
Darum bauen übrigens viele Hersteller noch immer diese grottigen Displays (wie hier, LED-Matrixen oder einfache LCD mit vorgefertigten Anzeigen) in Midi-Eingabegeräte. Die Dinger lassen sich einfach sehr schnell "beschreiben".