GELÖST: Das gute alte "Delay" Problem...(Bin absoluter Anfänger)

Hallo, geehrte Schwarmintelligenz

Ich möchte, wenn ich einen Poti drehe, einen MIDI Befehl ausgeben und eine LED leuchten lassen.
Diese LED soll aber etwas länger leuchten, als die eigentliche Ausgabe des MIDI Send Befehls, da sie sonst nicht erkennbar fürs menschliche Auge leuchtet.
Ein "Delay" von 50 wäre perfekt, wenn..., ja wenn da nicht der MIDI Send Befehl in der Warteschleife wäre.

Da ich absoluter Anfänger bin, komme ich mit dem "Nachtwächter", wenn er denn hier überhaupt nötig sei, auch nicht wirklich voran, denn der eigentlich sehr einfache Sketch würde hier grosse Ausmasse annehmen.
Gibt es hier eine einfachere Lösung?

Ich habe hier eine vereinfachte Variante meines Sketches angefügt. Die MIDI Befehle laufen perfekt.
Ich benutze einen Teensy, daher passt der MIDI Send Befehl nicht mit einem Arduino überein, aber das spielt wohl für mein Problem keine Rolle.

Besten Dank im Voraus für eure Mühen, LG aus Kopenhagen

f_rs_Forum.ino (935 Bytes)

Setze Deinen Sketch am besten in Code Tags </> Symbol im Editor...

int cWert = 0;    //Damit die Werte nur dann gesendet werden, 
int cWertAlt = 0; //wenn das Poti benutzt wird

int potiWert = 0; //bestimmt den Poti
int ledPin = 13; // Ausgang der LED


void setup() {
  
  Serial.begin(31250);        //Die Bauderate der MIDI Sprache
  pinMode(ledPin, OUTPUT);    //Bestimmt den Zustand der LED Zuweisung am Proessor
}

void loop() {
  
potiWert = (analogRead(9));          //Die Adresse des Poti
 cWert = map(potiWert,0,1023,0,127); //Der Poti Wert wird auf MIDI Verständliche
                                     //Werte von 0 - 127 runtergerechnet
 if (cWert != cWertAlt) {            //Wenn der Poti gedreht wird...
  
   usbMIDI.sendControlChange(22,cWert,0);//Der MIDI Send Befehl

   digitalWrite(ledPin, HIGH);  //Eine LED leuchtet, wenn der Poti benutzt wird
   
   delay(50);                   //DIES HIER MUSS WEG,HÄLT ALLES AUF
 }
  else digitalWrite(ledPin, LOW);
cWertAlt = cWert;
}

Habe das mal für Dich gemacht

Hmmm, nun hast Du wieder gelöscht...?

Gruß SG

Ach, das war deiner?
Tschuldige, ich hatte das nicht gesehen...
Magst du das nochmal posten, habe das mittlerweile verstanden, aber als Anfänger darf ich jetzt erstmal nichts neu mit code posten...

Der Sketch compiliert nicht. usbMIDI ist nich deklariert. Da fehlt doch eine Lib im Sketch.

Edit: eventuell diese GitHub - arduino-libraries/MIDIUSB at 0a1ef7498dad7904d2a54530616f418dcba9197c

Der wird nicht unterm Arduino deklariert, da es für einen Teensy ist. Arduino kann "usbMIDI" nicht...
Ich hatte gehofft, dass das kein grosses Problem sein würde...

Aha kenne mich mit dem tennsy nicht aus. Wahr nur so ein Gedanke.

mfg
Thorsten

Natürlich trotzdem besten Dank...
Der Teensy funzt ja fast genauso wie der Arduino, nur dass er eine eigene MIDI Schnittstelle an Board hat, weswegen ich dann zum Teensy auch gewechselt bin...

Vielleicht kannst du aber trotzdem mein problem lösen?

LG

Hi

if (cWert != cWertAlt) {            //Wenn der Poti gedreht wird...
   supersonderstatus=1;
   ledabmillis=millis();
   usbMIDI.sendControlChange(22,cWert,0);//Der MIDI Send Befehl
   digitalWrite(ledPin, HIGH);  //Eine LED leuchtet, wenn der Poti benutzt wird
}
if (supersonderstatus==1 and millis()-ledabmillis>=50){
   supersonderstatus=0;
   digitalWrite(ledPin, LOW);  //Eine LED geht auch wieder aus, wenn nicht mehr gedreht wird
}

Eigentlich GENAU der Nachtwächter :wink:
(sofern supersonderstatus und ledabmillis deklariert werden)

MfG

Das mit der LED würde mit ein paar veränderten Zeilen deines Codes etwa so funktionieren:

int cWert = 0;    //Damit die Werte nur dann gesendet werden,
int cWertAlt = 0; //wenn das Poti benutzt wird

int potiWert = 0; //bestimmt den Poti
int ledPin = 13; // Ausgang der LED

const unsigned long leuchtDauer = 50;
unsigned long startZeit;


void setup() {
  Serial.begin(31250);        //Die Bauderate der MIDI Sprache
  pinMode(ledPin, OUTPUT);    //Bestimmt den Zustand der LED Zuweisung am Proessor
}


void loop() {
  potiWert = (analogRead(9));          //Die Adresse des Poti
  cWert = map(potiWert, 0, 1023, 0, 127); //Der Poti Wert wird auf MIDI Verständliche
                                         //Werte von 0 - 127 runtergerechnet
  if (cWert != cWertAlt) {            //Wenn der Poti gedreht wird...
    usbMIDI.sendControlChange(22, cWert, 0); //Der MIDI Send Befehl
    digitalWrite(ledPin, HIGH);  //Eine LED leuchtet, wenn der Poti benutzt wird
    startZeit = millis();        // Einschaltzeitpunkt merken
  }

  if (millis() - startZeit >= leuchtDauer) {  // wenn die Leuchtdauer vorbei ist die LED ausschalten
    digitalWrite(ledPin, LOW);
  }

  cWertAlt = cWert;
}

Allerdings schwanken normalerweise die Werte von analogRead ein wenig, auch wenn das Poti nicht gedreht wird.
Und das wird wohl für "Dauerfeuer" auf der MIDI-Schnittstelle sorgen. Und auch die LED wird höchstwahrscheinlich dauernd leuchten oder zumindest nervös blinken - auch wenn das Poti nicht berührt wird.

Kannst dir ja mal die Werte von "potiWert" oder "cWert" auf der seriellen Schnittstelle ausgeben lassen, dann siehst du das.

@postmaster-ino

Boah, wie geil...

Haha..., Supersonderstatus, sehr schön geschrieben....

Also, das ist tatsächlich einfach, aber einem Dummen wie mir muss man es echt ins Hirn prügeln. Ja, es IST der Nachtwächter, ich habe ihn einfach so nicht sehen können...

Also, allerliebsten vielen Dank, das bringt mich so richtig weiter, auch für den Rest meines Programmes.

Falls du mal Urlaub in Kopenhagen machen solltest, melde dich, ich werde dir und deiner Familie für einen Tag den Reiseführer spielen....

Beste Grüsse,
Axel Munshine

@uxomm

Auch genial...

Jetzt habe ich ja richtig was auszuprobieren...

Magst dich auch gerne melden, wenn du einen Reiseführer brauchst.. :wink:

Besten Dank

LG
Axel Munshine

PS: Aber kommt nicht alle am selben Tag, würde schwierig werden... :wink:

@uxomm

Ja, du hast vollkommen recht, es würde zu "Dauerfeuer" führen, daher habe ich folgende Zeile eingebaut:

potiWert = (9.5 * potiWert + 0.5 * analogRead(9)) / 10;

Da kann ich mit den Werten ein bisschen rumspielen, kann 9.5 und 0,5 auch in 8 zu 2 umwandeln, jenachdem, wie gut die Qualität des Poti ist...

Danke für deinen Hinweis...

Ja, du solltest eine "Toleranz-Schwelle" einbauen.

Und dass die Werte schwanken hat meist weniger mit der Qualität des Poti zu tun, als mit dem ADC (analog to digital converter) des Mikrocontrollers. Das ist kein "Präzisions-Instrument", die Versorgungsspannung ist oft nicht ganz sauber, es gibt Einstreuungen und so weiter.

Absolut.
Ohne Toleranzschwelle geht es nicht.
Wie würdest du sie einbauen?

Mich hat das lange genervt, dieses "Zittern".

Letztlich werde ich am Ende die digitalen Eingänge benutzen, aber wir sind hier ja am Theorisieren, am beschreiben, wie es gehen müsste...

Ich würde das etwa so machen:

const int ledPin = 13;
int cWert;
int potiWert;
int potiWertAlt;
int toleranz = 1;    // kleine Werte sollten reichen

const unsigned long leuchtDauer = 50;
unsigned long startZeit;

void setup() {
  Serial.begin(31250);        //Die Bauderate der MIDI Sprache
  pinMode(ledPin, OUTPUT);    //Bestimmt den Zustand der LED Zuweisung am Proessor
}

void loop() {
  potiWert = (analogRead(9));          //Die Adresse des Poti

  if ( (potiWert > (potiWertAlt + toleranz))  ||  (potiWert < (potiWertAlt - toleranz)) ) {
    cWert = potiWert/8;     // ergibt Werte von 0 bis 127 
    usbMIDI.sendControlChange(22, cWert, 0); //Der MIDI Send Befehl
    digitalWrite(ledPin, HIGH);  //Eine LED leuchtet, wenn der Poti benutzt wird
    startZeit = millis();        // Einschaltzeitpunkt merken
    potiWertAlt = potiWert;
  }

  if (millis() - startZeit >= leuchtDauer) {  // wenn die Leuchtdauer vorbei ist die LED ausschalten
    digitalWrite(ledPin, LOW);
  }

}

Also nur dann einen MIDI-Befehl senden, wenn sich der "potiWert" um mehr als den Toleranzwert ändert. Es reichen aber durchaus kleine "Toleranzwerte". Weil die Werte des ADC meist nicht um mehr als +/- 1 oder 2 schwanken.
Allerdings kann es sein, dass man sich Störungen einfängt. Und dann sind die Schwankungen größer. Das kann sich so äußern: Du berührst das Poti und plötzlich gibt es Schwankungen von 10 oder mehr.
Da kann ein Keramik-Kondensator, 100nF helfen. Zwischen GND und dem Analog-Eingang, an dem das Poti hängt.
Also zumindest bei mir ergibt so ein Aufbau sehr "smoothe" Poti-Werte. :slight_smile:

Das Poti sollte übrigens nicht allzu hochohmig sein. 10 Kiloohm sind OK.

Beim Code oben werden beim Drehen des Potis mehrmals hintereinander MIDI-Befehle mit demselben Wert versendet. Das kann ein Problem sein oder auch nicht, das hängt davon ab, wofür du es verwendest.
Wenn du "toleranz" auf 7 stellst wird dieses Verhalten verhindert und es werden nur MIDI-Befehle mit unterschiedlichen Werten gesendet.

Besten Dank...

Das mit der Toleranz werde ich gleich mal ausprobieren, klingt einfacher als meine Rechnung.

Das mit dem Potiwert geteilt durch 8 ist auch super, aber ich muss beim "map" bleiben, da ich auch einen Joystick einplane, und da muss ich den Mittelwert berechnen und einmal auch sogar eine Hälfte des ganzen Wertes negativieren. Klingt jetzt seltsam, ergibt aber Sinn.. :wink:

Egal, du hast mir absolut super weiter geholfen, eben auch so, dass ich es verstehe...

Schönen Abend...
Axel Munshine