Midi Controller

Hallo zusammen,

ich bastele gerade an einem MidiController mit Teensy 3.2 zur Ausgabe von Midi NoteON / Off Befehlen.
Die Stromversorgung läuft über USB.

Mit einem Poti an A1 lässt sich ein Schwellwert einstellen. Definiert ist der als (VoltageA1>1) und entspricht dem Anschlag einer Saite.

Um das besser simulieren zu können hängt zwischen Poti Schleifer und A1 noch ein Taster (mit 10 K und 40nF gegen GND).

Zusätzlich wird mit einen Spannungsteiler an A0 der Widerstand gemessen und über switchcase in Midi Noten (= Bund Position der Greifhand) umgerechnet .

Grundsätzlich funktionieren damit zumindest mal die einzelnen Schaltpunkte .

Sketch:

/*
  Teensy 3.2 (72 MHz,USB Type Midi, Optimize = Faster), 
  IDE 1.8.12
  Stromversorgung per USB

  Spannungsteiler an A0 und GND fest angeschlossen !
  Poti an A1 für Schwellwert (mit Taster am Schleifer).

*/

const int channel = 1; // Midikanal
float Quellspannung = 3.28;// gemessene Spannung !

const int PinA0 = 0;    // Hier ist der Spannungsteiler angeschlossen
const int PinA1 = 1;    // Poti Anschluss für Schwellwert (wird später durch Pickup für H Saite ersetzt)


int WertA1;               // speichert die gemessene Spannung
float voltageA1;         // Schwellwert für Note On / Off


int Velocity_H;           //Midiwert für Lautstärke zZ per Poti an A1(später per Pickup)
int MidiOffsets[5] = {0, 5, 10, 15, 20};    // Zugriff auf 1. Wert mit MidiOffsets[0];


int R1 = 3270.0;         //Wert des bekannten Messwerts(3,3k; nachgemessen = 3270)
long MesswertA0;
long MesswertA1;

float SpannungR2;      //Spannung über dem zu messenden Widerstand
float Widerstand = 0;

int midineu = 0 ; 
int midiold = 0 ; 


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

void loop() {

  WertA1 = analogRead(A1);
  voltageA1 = WertA1 * (Quellspannung / 1024);
  //for (int i = 0; i < 5; i++) {
  //  MesswertA1 += analogRead(PinA1);
  //}
  // MesswertA1 = trunc(MesswertA1 / 5);

  Serial.print("  Spannung an A1 beträgt  ");
  Serial.println(voltageA1);// voltageA1

  //int Velocity_H = map(voltageA1, 0, 1023, 0, 127);
  //Velocity_H = map(WertA1, 0, 1023, 0, 127);
  //Serial.print("  Midiwert ist  ");                                     
  //Serial.println(Velocity_H);                                            


  //5 Messungen am Spannungsteiler machen und Mittelwert bilden
  MesswertA0 = 0;
  //for (int i = 0; i < 5; i++) {
  MesswertA0 += analogRead(PinA0);
  // }
  //MesswertA0 = trunc(MesswertA0 / 5);


  //Spannung berechnen
  SpannungR2 = (Quellspannung / 1024) * MesswertA0;
  //Serial.print("Spannung ueber R2 betraegt ");                      
  //Serial.print(SpannungR2, 2);                                           
  //Serial.println(" Volt!");                                                    


  //Berechnung: (R2 = R1 * (U2/U1))
  Widerstand = R1 * (SpannungR2 / (Quellspannung - SpannungR2));
  Serial.print("Der Widerstand hat ");                                      
  Serial.print(Widerstand, 2);                                                
  Serial.println(" Ohm.");                                                      
  Serial.println();                                                                

  delay(250);                    // Verzögerung zum Lesen der Anzeige, fliegt sonst raus!


  //Umrechnung Widerstand => MidiNote
  switch (int(Widerstand))
  {
    case  2844 ...  3857 : midineu = 24; break; // 3,3 (theoretischer Mittelwert)
    case  6186 ...  7186 : midineu = 25; break; // 6,6 
    case  9495 ... 10578 : midineu = 26; break; // 9,9 
    case 12847 ... 13765 : midineu = 27; break; //13,2 
    case 16000 ... 17000 : midineu = 28; break; //16,5 
    case 19300 ... 20500 : midineu = 29; break; //19,8 
    case 22876 ... 23876 : midineu = 30; break; //23,1 
    case 25943 ... 27208 : midineu = 31; break; //26,4 
    case 29148 ... 30474 : midineu = 32; break; //29,7 
    case 31827 ... 33727 : midineu = 33; break; //33,0 
    case 35734 ... 37204 : midineu = 34; break; //36,3 
    case 39280 ... 40839 : midineu = 35; break; //39,6 
    case 42229 ... 43868 : midineu = 36; break; //42,9 
    case 45612 ... 47350 : midineu = 37; break; //46,2 
    case 49533 ... 50533 : midineu = 38; break; //49,5 
    case 52198 ... 54147 : midineu = 39; break; //52,8 
    case 56197 ... 57197 : midineu = 40; break; //56,1 
    case 58418 ... 60592 : midineu = 41; break; //59,4 
    case 60810 ... 63077 : midineu = 42; break; //62,7 
    case 64765 ... 66000 : midineu = 43; break; //66,0 
    case 66300 ... 68500 : midineu = 44; break; //69,3 
    case 70858 ... 73554 : midineu = 45; break; //72,6 
    case 74329 ... 75329 : midineu = 46; break; //75,9 
    case 78139 ... 81187 : midineu = 47; break; //79,2 

    case 82000 ... 93000 : midineu = 23; break; //89,2 (25. Widerstand = 10K "leere" H Saite)
    
    default: midineu = 0; break;
  }

  if (voltageA1 < 1 ) {
    usbMIDI.sendNoteOff(midiold, 0, 1);
    //midineu = 0;
    //midiold = 0;
    midiold = midineu;

  }
  if (voltageA1 > 1) {
   
    usbMIDI.sendNoteOn(midineu, 127, 1);     // midineu = Midi Note, 127 = Lautstärke, 1 = Kanalnr
    midiold = midineu;
  } 
}

Im Moment wird Note Off leider als "Dauerfeuer" gesendet wenn A1>1 ist (wenn A1< 1 kommt absichtlich nix).
Wenn über den Spannngsteiler eine neue Midinote errechnet wird kommt Note On auch als Dauerfeuer solange der entsprechende Widerstand ausgewählt ist.

Note On / Off sollten jeweils nur 1 x gesendet werden (wie bei einem Keyboard) solange sich A0 oder A1 nicht ändern.

Wie lässt sich das umsetzen ?

Würde mich über Eure Tipps freuen !

Grüsse

Merke Dir, dass Du gesendet hast und setze den Merker wieder zurück, wenn sich eine Veränderung zum Neusenden ergibt.

Gruß Tommy

Tommy56:
Merke Dir, dass Du gesendet hast und setze den Merker wieder zurück, wenn sich eine Veränderung zum Neusenden ergibt.

Gruß Tommy

Hi Tommy,

genau das habe ich bereits mit speichern in der Variablen midineu, und mit Backup midiold = midineu; (nach jedem senden der Note On / Off Befehle) versucht...

Auch das ändern der Variable in static int, oder die Verwendung anderer int / static int Startwerte bzw das tauschen dieser (zB midineu 23, midiold 0 / oder midineu 0, midiold 123) brachte bisher nicht das gewünschte Ergebnis.

Midi NoteOn 123 ist hierbei der Befehl für all Notes Off (eher eine Notlösung falls sich der Synth mal aufhängt.....).
Besser ist es nach jedem NoteON auch ein NoteOff zu schicken...

Grüsse