Midi NoteOn / Off per USB senden

Hallo zusammen,

ich versuche mit dem Teensy 3.2 Midi NoteOn/Off in abhängigkeit von der an A1 anliegenden Spannung
per USB zu senden.
Note On zB nur dann wenn die Spannung über 3V, NoteOff nur wenn die Spannung unter 1V liegt.

Grundsätzlich funktioniert das - aber:
NoteOn und Off Messages werden dabei als Dauersignal ausgegeben…

Das hört sich im angeschlossenen Midi Instrument an wie eine alte Wechselstrom Klingel…- und führt
wegen dem hohen Miditraffic zum “aufhängen” des Midi Instruments…

float voltage = 0;
float voltage_Old = 0;

int midiNeu = 0 ;
int midiOLD = 0 ;

void setup() {
  analogReadResolution (16); // 16 Bit = 65536 (3.31 / 65536);
  Serial.begin(115200);
}

void loop() {

  voltage = analogRead(A1) * (3.31 / 65536);


  if (voltage > 3.00 ) {
    usbMIDI.sendNoteOn(40, 127, 1);
    voltage_Old = voltage;
    //midiOLD = midiNeu ;
  }
  if (voltage < 1.00 ) {
    usbMIDI.sendNoteOff(40, 0, 1);
    voltage_Old = voltage;
    //midiOLD = midiNeu ;
  }

  //delay(250);
  { Serial.print("voltage = ");
    Serial.print(voltage);
    Serial.print("\t");

    Serial.print("voltage_Old = ");
    Serial.print(voltage_Old);
    Serial.print("\t");

    Serial.print("midiOLD = ");
    Serial.print(midiOLD);
    Serial.print("\t");

    Serial.print("midiNeu = ");
    Serial.println(midiNeu);


  }
  while (usbMIDI.read()) {  // Eingehende Nachrichten lesen und ignorieren !
  }
}

Wie kann ich erreichen das Note ON / Off nur jeweils 1 x bei den Schwellwerten ausgegeben wird?

Kann mich dunkel dran erinneren das da mal irgendwas mit midiAlt / midiNeu war - steh da aber gerade etwas auf`m Schlauch…

Grüsse

Hallo

indem Du dir merks das Du es schon mal gesendet hast. Dazu benötigst Du am besten eine bool Variable

bool status
.
.

Wenn volt >3 && not status
status =true
.
.

wenn volt <1 && not status
status =true

.
.

wenn volt > 1.2 && Volt <2.8 status=false

sowas in der Art

Heinz

Für das Thema Teensy 3.2 Ohmmeter mit Midi Ausgabe habe ich mal was geschrieben:

// Widerstände messen
//              _____
//            -|_R1__|- VCC
//AnalogPin  -' _____
//           '-|_R2__|- GND

// R2 = zu messender Messwert (Reihenschaltung von mehreren 3,3k Widerständen)

float Quellspannung = 3.30;
int AnalogPin = 0;
int R1 = 3280.0; //Wert des bekannten Messwerts(3,3k, nachgemessen = 3280)
long Messwert;
float SpannungR2; //Spannung über dem zu messenden Widerstand
float Widerstand = 0;
float WiderstandAlt = 0;
int MidiNote = 0;
int MidiNoteAlt = 0;

// usbMIDI.send_now() anstelle von usbMIDI.sendNoteOn verwenden ????
void setup()
{
  Serial.begin(115200);
  Serial.println("Widerstand ausmessen");
  Serial.println();
}

void loop()
{
  //5 Messungen machen und Mittelwert bilden
  Messwert = 0;
  for (int i = 0; i < 5; i++) {
    Messwert += analogRead(AnalogPin);
  }
  Messwert = trunc(Messwert / 5);

  //Spannung berechnen
  SpannungR2 = (Quellspannung / 1023.0) * Messwert;
  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();

  MidiNoteAlt = MidiNote;
  switch (int(Widerstand))
  {
    case 2970 ...  3630 : MidiNote = 60; break;
    case 5940 ...  7260 : MidiNote = 61; break;
    case 8910 ... 10890 : MidiNote = 62; break;
  }

  if (MidiNote != MidiNoteAlt)
  {
    usbMIDI.sendNoteOff(MidiNoteAlt, 0, 1);
    usbMIDI.sendNoteOn(MidiNote, 99, 1);
  }

  // MIDI Controllers should discard incoming MIDI messages.
  while (usbMIDI.read()) {
    // read & ignore incoming messages
  }
  delay(200); // Verzögerung zum Lesen der Anzeige, fliegt sonst raus!
}

Entscheident sind die Variablen MidiNoteAlt und MidiNote.

Bei Dir sollte das genauso funktionieren.

Hi Argmue,

danke für die Info - kann mich dran erinnerern...

Ich gebe hier allerdings Midinote 40 fest vor.
Hatte das auch bereits mit Midineu / Midialt probiert (deshalb auskommentiert). Funktioniert aber so leider nicht. Da scheint nochwas zu fehlen...

Mir ist noch nicht klar wie und wo die Midnote 40 dann an Midineu / Midialt übergeben wird... ?

stingray05:
Da scheint nochwas zu fehlen...

Möglicherweise hätte ich deutlich machen sollen, daß es um eine Kombination mit der Antwort von Heinz geht. Wenn sich die Note nicht ändert, was ändert sich dann? Du könntest es MidiStatus nennen.

agmue:
Wenn sich die Note nicht ändert, was ändert sich dann? Du könntest es MidiStatus nennen.

Hi Argmue,

Es ändert sich nur die Spannung an PIN A1.
Deshalb hatte ich das direkt mit “voltage > 3.00” bzw voltage < 1.00 versucht.

Ich hab mir zwar die Variablen midiNeu und MidiOLD angelegt, die werden aber mit usbMIDI.sendNoteOn(40, 127, 1); offenbar nicht mit Noten Werten gefüllt…

Mit bool krieg ich das so (noch)nicht hin.

Ziel ist es NoteOn für MidiNote 40 einmal beim überschreiten des oberen Schwellwertes , und einmal NoteOff beim unterschreiten des unteren Schwellwertes auszulösen.

Bisher wird, je nach anliegender Spannung, entweder NoteOn oder NoteOff dauerhaft gesendet…

Grüsse

Versuche mal dies als Anregung:

void setup() {
  analogReadResolution (16); // 16 Bit = 65536 (3.31 / 65536);
  Serial.begin(115200);
}

void loop() {
  static bool midistatus;
  uint16_t voltage = analogRead(A1) * (3.31 / 655.36);

  if (midistatus) {
    if (voltage < 100 ) {
      midistatus = false;
      usbMIDI.sendNoteOff(40, 0, 1);
      Serial.println("Note aus");
    }
  } else {
    if (voltage > 300 ) {
      midistatus = true;
      usbMIDI.sendNoteOn(40, 127, 1);
      Serial.println("Note ein");
    }
  }

  while (usbMIDI.read()) {  // Eingehende Nachrichten lesen und ignorieren !
  }
}

agmue:
Versuche mal dies als Anregung:

Hi agmue,

vielen Dank, das funktioniert !

Warum (3.31 / 655**.**36); statt 3.31/ 65536 ? Verliere ich dadurch nicht ADC Auflösung ?

Grüsse

stingray05:
Warum ...

Um Dich zum Nachdenken über die Verwendung von Datentypen anzuregen :slight_smile:

Der Teensy 3.2 hat anders als 3.5 und 3.6 keine Fließzahlenrecheneinheit, weshalb Fließzahlen aufwändig in Software berechnet werden müssen.

stingray05:
Verliere ich dadurch nicht ADC Auflösung ?

Wozu benötigst Du diese? Ist 197.9939575195 wirklich genau (WinTaschenrechner 197,9939577039275)? Ginge nicht auch

uint16_t voltage = analogRead(A1) / 198;

Da ich Deine Anwendung nicht kenne, kann ich nur Fragen stellen, um Dich zum Nachdenken anzuregen.

agmue:
Da ich Deine Anwendung nicht kenne, kann ich nur Fragen stellen, um Dich zum Nachdenken anzuregen.

Hi argmue, - frohes neues Jahr !

mich hatte nur die Schreibweise der 655.36 Auflösung gewundert- Die hatte ich als
655Komma36 interpretiert... Daher die Frage wegen der Auflösung...

Zur Anwendung muss ich etwas weiter ausholen:

Es geht darum mit einem E Bass (5 Saiten) Midi Noten, ohne den üblichen Umweg der Frequenzanalyse, zu
erzeugen.
Dazu hab ich das Projekt aufgeteilt.

  1. Ohmmeter Sketch mit Midiausgabe:
    Die Greifhand bestimmt durch direkten Kontakt zwischen Saite und Bundstäbchen die Midinoten Höhe
    (Saiten sind voneinander isoliert).
    Entweder per Spannungsteiler, oder jedes Bundstäbchen funktioniert zusammen mit der Saite als Schalter und
    hat einen eigenen PIN.

  2. Das eigentliche Auslösen der Midinoten erfolgt aber erst bei einem bestimmten Schwellwert der gemessenen
    Pickup Spannung durch das Anschlagen der Saite

Die Signalaufbereitung für den ADC sieht so aus (siehe Anhang):

  1. Vorverstärker
  2. Impedanzwandler (sitzt im Bild noch am Ausgang der Schaltung)
  3. Halbwellengleichrichter mit Limiter auf 3.3V

Die Schaltung funktioniert auch mit LM 324 / LM 358, TL 084 / LMC 6482 und anderen -
Bei meinen vorhandenen OpAmps war der TL 072 bisher die beste Lösung.
Im Orginal wurde für den Gleichrichter / Limiter ein LT6015, für den Roland GK3B Vorverstärker ein UPC4570G
verwendet.

Als Test Eingangssignal habe ich zunächst 3.3V DC direkt auf den A1 PIN gegeben.
Mit deinem Sketch funktioniert das auch mit dem angeschlossenen Midi Instrument.

Bei einem weiteren Test, diesmal mit vorgeschalteter Signalaufbereitung (Sinussignal mit 30 Hz / bis
max 800mV), kommt es ebenfalls nicht zur gefürchteten mehrfachen Midi Auslösung.
Lässt sich am Oszi und im Serial Plotter gut beobachten, zumindest dann wenn die Signalfrequenz
entsprechend runtergedreht wird (auf etwa 3 - 4 Hz) .

Ganz anders beim angeschlossenen Pickup.
Das Signal hat Impulscharakter, allerdings leider so das bei einem einzigen Saitenanschlag gleich mehrere sich weiter abschwächende Impulse entstehen, solange man die Saite nicht massiv abdämpft.
Hört sich dann wie die zititerte Wechselstromklingel an...
Es kommt dadurch zur beschriebenen mehrfacher Midi Auslösung die unbedingt vermieden werden sollen.
Auch ein ändern der Schwellwerte brachte keine brauchbaren Ergebnisse.

Die Frage ist wie sich das schwankende Eingangssignal vom Pickup, entweder Hardware- oder Softwareseitig
(oder beides) so verändern lässt das der ADC jeweils nur den ersten (größten) Impuls davon sieht - andrerseits
aber auch schnelle mehrfache Saiten Anschläge zuverlässig erkannt werden... ?

Grüsse

stingray05:
Hi argmue, - frohes neues Jahr !

Ich wünsche Dir ein kreatives Jahr 2021!

stingray05:
Die Frage ist wie sich das schwankende Eingangssignal vom Pickup, entweder Hardware- oder Softwareseitig
(oder beides) so verändern lässt das der ADC jeweils nur den ersten (größten) Impuls davon sieht - andrerseits aber auch schnelle mehrfache Saiten Anschläge zuverlässig erkannt werden… ?

Liest sich wie die Quadratur des Kreises ;D

Wie sieht das Signal an Meßpunkt 3 oder A1 mit dem Oszi aufgezeichnet aus?

agmue:
Liest sich wie die Quadratur des Kreises ;D

Wie sieht das Signal an Meßpunkt 3 oder A1 mit dem Oszi aufgezeichnet aus?

Also die Quadratur des Kreises issses nicht (sonst hätt ich mich schon um nen Patent bemüht :slight_smile: . Das Konzept gibts schon lange, seit den 60er Jahren.
Die Idee dabei war ein Griffbrett mit der Funktion einer Keyboard Tastatur auszustatten...
Damit hat jedes Saiteninstrument dann den vollen Zugang zum Midi "Universum"...

Es gibt aber nur so gerade eben eine Handvoll Hersteller die sowas überhaupt noch anbieten - und dann auch nur für 4 Saitige Bässe (zu Preisen jenseits von 3000€).

Die billigere Variante mit Midinotenbestimmung durch Frequenzmessung (wie zB bei Roland) oder komplett per Software, hat bis heute den entscheidenden Nachteil das es zu immer größeren Verzögerung kommt je tiefer die gespielten Töne werden.
Bei Gitarren zB kaum ein Problem da die eine Oktave höher spielen...

Screenshot vom Signal schick ich gleich noch.

Grüsse

Hi argmue,

hier die Screenshots vom Signalverlauf am ADC Eingang:

stingray05:
hier die Screenshots vom Signalverlauf am ADC Eingang:

Das sieht gut aus, aber was unterscheidet die farbigen Kurven (Messpunkt 3 und ADC?) und die Bilder (andere Saite oder andere Zeitbasis?)?

Oh sorry, hatte ich ganz vergessen...

Blau = Messpunkt 2, also das schon Vorverstärkte Signal vom Tonabnehmer
Lila = Messpunkt 3 - das was der ADC bekommt (Gleichgerichtet mit Begrenzung)

Die angeschlagene Saite ist immer die gleiche - wenn auch nicht immer mit dem gleichen Anschlag...
Ich habe nur mit der Zeitbasis versucht den Signalverlauf besser in ein Bild quetschen zu können.

Am besten wär eigentlich ein Video das den Signalverlauf zeigt - die Arbeit würd ich mir glatt machen...
Wie, wo und bis zu welcher Größe könnte hier eins hochgeladen werden, falls das möglich ist ?

Grüsse

Nur zur Sicherheit nachgefragt: Zeigt ADC_04.jpg einen oder mehrere Anschläge?

Was das Oszi sieht, ist die eine Sache, was der Teensy sieht, eine andere, denn der ADC braucht ja Zeit für die Wandlung. Das könntest Du über den DAC in einer weiteren Linie darstellen.

stingray05:
Also die Quadratur des Kreises issses nicht ...

... dennoch benötigst Du ein (mathematisches) Konzept, wie Du an die Information kommen möchtest. Hast Du schon eine Idee?

agmue:
Nur zur Sicherheit nachgefragt: Zeigt ADC_04.jpg einen oder mehrere Anschläge?

... dennoch benötigst Du ein (mathematisches) Konzept, wie Du an die Information kommen möchtest. Hast Du schon eine Idee?

Hi argmue,

das ist tatsächlich immer jeweils nur ein Anschlag auf allen Screenshots gewesen !
Ein paar Ideen hab ich schon, allerdings kein (mathematisches) Konzept sondern eher das Ergebnis von Trial&Error:
Nach vielem probieren war mir endlich aufgefallen das ich keinen Kondensator zwischen A1 und GND verbaut hatte...

Hab dann mal mit verschiedenen Werten getestet. Die müssten so ganz grob irgendwo zwischen 660nF und 880nF liegen.

Den richtigen Wert zu finden ist allerdings ziemlich knifflig. Ist der zu groß leidet die Empfindlichkeit der Anschlagserkennung ganz erheblich, ist der zu klein gibts mehrfache Midiauslösungen (bei 880nF zB nicht mehr).

Sieht also so aus als wenn ich meine Schaltung um Sample&Hold bzw Peak&Hold erweitern müsste.

Zusätzlich zum passenden Kondensator Wert muss der dann auch automatisch entladen werden...

Hast Du ne Idee wie dafür die passende (Transistor ? ) Schaltung aussehen müsste ?
Oder könnte ich vielleicht mit digitalWrite GND auf den Kondensator legen, um den zu entladen ?

Grüsse

stingray05:
das ist tatsächlich immer jeweils nur ein Anschlag auf allen Screenshots gewesen !

Dann kann man zwei wichtige Dinge nicht sehen:

  • Das Ausschwingverhalten eines Anschlags.
  • Wie nah zwei zu unterscheidende Anschläge beeinanderliegen können.

stingray05:
Ist der zu groß leidet die Empfindlichkeit der Anschlagserkennung ganz erheblich, ist der zu klein gibts mehrfache Midiauslösungen ...

Das meinte ich mit der Quadratur des Kreises.

stingray05:
Hast Du ne Idee wie dafür die passende (Transistor ? ) Schaltung aussehen müsste ?

Vor langer Zeit waren mal Lichtorgeln in Discos angesagt, die Hoch-, Band- und Tiefpassfilter verwendet haben. Meine Kumpels und ich haben anstelle der üblichen recht primitiven Schaltungen Operationsverstärker verwendet. An die Musik von Kate Bush kann ich mich noch gut erinnern, an die Schaltungen eher nicht. Das weltweite Netz wird Dich aber mit Schaltungen zuschütten.

Filter und dergleichen kann man natürlich auch in Software gießen, das wird aber komplizierter werden als ein einfacher Spanngsvergleich.

Wie Du das angehst, hängt von Deinen Kenntnissen ab, die ich nicht kenne, weshalb ich da keine Empfehlung abgeben möchte.