AIO Fork Marco KY-040 Encoder

@marco-117 Du hast recht.
Man bekommt dann kein Signal bzw. ich bekam meist nur einmal was.
Könntest du mir erklären wie ich es sonst wieder auf die alte Lib umstellen kann?

Ich bin ehr Anfänger aber bastel halt gerne und versuche was zu verstehen.

21.04.21 22:18
Habe noch etwas gelesen.
Leider konnte ich nicht in der Encoder Lib ein entprellen finden. Hatte irgendwo mal was beim Pi gehabt wo man was einstellen konnte.
Ich habe noch was gefunden aber geht ehr um Taster. Vielleicht trotzdem interessant, wenn man das mit einbindet. Ich kann es leider nicht. Sorry.
Bounce Lib

Ich versuch das mal zu beschreiben.

In meinem Fork ist die Erkennung der Eingaben komplett umgeschrieben um Fälle wie deinen schnell implementieren zu können.
Im Fall Rotary Encoder dreht sich alles um diese Funktion:

#if defined ROTARY_ENCODER
int8_t currentPosition  = 0;

void RotEncSetVolume () {
  int8_t newPosition = myEnc.read() / ROTARY_ENCODER_STEPS; //lesen der erkannten Impulse

  if (newPosition != currentPosition) {
    if (newPosition > currentPosition) {
#if defined ROTARY_ENCODER
      Serial.println(F("encoder direction clockwise"));
#endif
      myTrigger.volumeUp |= true;
    } else if (newPosition < currentPosition) {
#if defined ROTARY_ENCODER
      Serial.println(F("encoder direction conterclockwise"));
#endif
      myTrigger.volumeDown |= true;
    }
    currentPosition = 0;
    myEnc.write(currentPosition);
  }
}
#endif

Das ist quasi 1:1 aus dem Beispiel der Bibliothek übernommen. Wichtig ist hier nur, dass man die Drehrichtung erkennt.

if (newPosition != currentPosition) -> rechts herum
else if (newPosition < currentPosition) -> links herum

und dann das setzt, was es bewirken soll. In meinem Fall die Lautstärke erhöhen oder verringern.

myTrigger.volumeUp |= true;
myTrigger.volumeDown |= true;

Ich arbeite hier mit globalen Variablen. Für jeden Befehl gibt es eine. Hier die Übersicht aller Befehle:

struct inputTrigger {
  bool noTrigger;
  bool pauseTrack;
  bool next;
  bool nextPlusTen;
  bool previous;
  bool previousPlusTen;
  bool volumeUp;
  bool volumeDown;
  bool cancel;
  bool adminMenu;
  bool resetTrack;
  bool shortCutNo [availableShortCuts]; //muss an letzter Stelle stehen bleiben!
};

Es gibt eine Struktur die zwei Mal instanziert wird

static inputTrigger myTrigger;
static inputTrigger myTriggerEnable;

Die erste Varaibale myTrigger ist für das Triggern des Befehls. Die zweite myTriggerEnable für die Flankenerkennung, damit beim Dauerdrücken nicht ständig der Befehl getriggert wird. Wenn man das will, muss die Abfrage des Triggers an entsprechender Stelle entfernt werden. Im Fall des Rotary Encoder aber irrelevant. Ich will nur das Prinzip etwas erläutern. Man muss hier nur wissen, welche Befehle es gibt und dass man Sie mit |= true triggert.

Was musst du jetzt machen um die Libary zu ändern?

  1. eine Libary aussuchen, es gibt ein paar. -> z.B. https://github.com/mprograms/SimpleRotary
  2. Dir auf Github die Beispiele anschauen, wie der Encoder ausgelesen wird ->https://github.com/mprograms/SimpleRotary/blob/master/examples/rotate/rotate.ino
  3. Alles nötige in den Code einfügen.

Die obige Methode ist nur das reine Lesen und Auswerten des Encoders. Es müssen aber oft, Libaryspezifisch, die Encoder initalisiert werden. Man muss ein Objekt aufrufen oder eine Methode, um z.B. die Pins zu übergeben oder es muss noch eine Interrupt Rutine mit rein.

Die aktuelle Lib braucht folgende initalisierungen (im übrigen sind die alle mit #if defined ROTARY_ENCODER eingeklammert und lassen sich danit auch gut suchen und finden)

#if defined ROTARY_ENCODER
// erstellen des Objekts myEnc, übergabe der verendeten Pins 
Encoder myEnc(ROTARY_ENCODER_PIN_A, ROTARY_ENCODER_PIN_B);
#endif

Das steht fast ganz oben im Code.

Ich hoffe damit kommst du weiter.

1 „Gefällt mir“

Ich denke nicht das hier ein prellen das Problem ist.

Es wird entweder an deinem Encoder leigen, aber der hat ja schon funktioniert.

oder

Es liegt an der Umsetzung.
Mein aktueller Code arbeitet mit polling. Das ist super abhängig davon, das der Code in der loop durchläuft und myEnc.read() so schnell und häufig wie möglich aufgerufen wird.
Der Code ist aber eignetlich eher schlecht dafür geignet. Auf meinem Klassik TonUINO läuft es aber sauber genug für die Lautstärke. Der Große Vorteil, ich kann die Analogen Inputs nutzen

Die perfomantere Lösung wäre über ein Interrupt. Dann bekommt man immer mit wenn der Encoder was macht. Das geht aber nicht mit jedem Input und idR nur mit den Digitalen.

1 „Gefällt mir“

Ich hab das jetzt mit einem Abenteuerlichen Aufbaue an der AiO getestet.

und es läuft einwandfrei.

Mir ist aber eine Sache aufgefallen. Mit was versorgst du den Encoder? 5V oder 3.3V?
Ich habe 3.3V genommen und mit meinem Encoder keine Probleme.
Mit 5V bekomme ich nicht jeden Step mit und bei schnelleren Bewegungen hängt es auch.

Dankeschön für die Arbeit abermals.

Ich habe meinen an 5V. Ich werde es nachher ausprobieren.

22.04.21 20 Uhr
Ich habe es jetzt bei mir ausprobiert aber wirklich besser ist es nicht.
Dann muss ich nochmal schauen ob ich einen anderen KY bekomme. Habe jetzt zwei ausprobiert, die habe ich aber von der gleichen Bestellung.

Wenn das mit der alten Lib problemlos lief, ist das ja quatsch da nochmal Geld aus zu geben.
Die Software ist ja kostenlos.
Das würde ich an deine Stelle zuerst probieren.
Wenn du mit dem Code nicht weiter kommst, kannst du mir deinen Versuch mal schicken und ich helf dir bei der Fehlersuche.

Hallo Marco,

ich habe mir tatsächlich verschiedenes durchgelesen aber ich raff es nicht wirklich, wo ich was austauschen muss. Zum einen denke ich, dass ich irgendwie deine allgemeinen Bezeichnungen übernehmen muss ins neue, zum anderen muss ich ja irgendwie danach sagen was passieren soll. Ich stehe einfach auf dem Schlauch.

Ich habe diesen Encoder, zumindest steht es auf dem Ding drauf und am Pi bei der Phoniebox lief es auch mit einem anderen aus der Bestellung ganz gut.
Link Joy-it KY-040

Dort ist auch eine Code für Arduino und Raspberry.
Nach weiterem googeln bin ich die Tage auch hier fündig geworden.

Hier hat jemand auch was mit dem debouncing gemacht im Code und er schreibt sogar vom gleichen Hersteller.

Link Joy-IT KY-040 mit Debouncing

Das wäre die Pinbelegung bzw. müsste ich es nun auf die A1, A2, ggf. den Button auch A0 und die Debouncing Zeit einstellen.

// Contructor provides defaults for pins and debounce time - I am using a MEGA2560
KY040b(int clkpin=32, int dtpin=34, int buttonpin=36, int deb=25 )

Weiter Oben wird eine Lib erwähnt. Diese müsste ich dann einfügen.
Wird für das debouncing verwendet.

#include <ezButton.h>

Weiter Unten steht noch
Serial.begin (9600);
Hier denke ich muss auch eine Anpssung stattfinden, damit ich es im Montitor verfolgen kann.

Kannst du mir hierbei vielleicht helfen? Bzw. würdest du dir die Zeit nehmen?

Damit wir vom gleichen sprechen, wäre es am besten wenn du mir deinen kompletten Code mal schickst.

Du kannst ihn auch hier posten, das musst du wahrscheinlich über zwei Beiträge machen und mit </> Formatieren

Wäre sehr dankbar wenn jemand einen fertigen Sketch mit dem Drehencoder einstellen würde.
Der Sketch der auf Github verlinkt ist, ist schon 3 Jahre alt und funktioniert bei mir nicht.

Hast du dir den Affenboxfork mal angesehen? Der wird ja aktuell gehalten.

Ich habe mich vor einer Woche dran gemacht das ganze mit einem Drehencoder Ky-040 mit der AiO zu realisieren. Laut leiser funktioniert Mein Problem ist gerade noch, dass die Upload LED dauerhaft flackert das kann meines Erachtens nicht gesund sein…

Soo, nach langer Zeit und der Email, dass es bei mir hier eine „Antwort“ gibt bin ich auch wieder am schauen, dass ich es ans Laufen bekomme.

Mit dem aktuellen Master Fork bekomme ich meine AIO nicht ans laufen. Hier startet er mit Melodie und direkt danach kommt die Ausschaltmelodie.

Ich habe mein altes Fork nochmal genommen und mit den gleichen Einstellungen von früher wieder hochgeladen.

Fehler war jetzt erstmal das gleiche, dass die Lautstärke ehr nicht hoch/runter geht.
Jetzt habe ich ein wenig gespielt. Wenn ich den Schalter (Play/Pause) gleichzeitig gedrück halte, funktioniert es einwandfrei. Danach habe ich den Schalter mal abgeklemmt. Auch dann funktioniert lauter leiser einwandfrei. Dies ist bei beiden KY, welche ich habe der Fall.

Hat Jemand eine Idee woran es liegen kann?

Ich werden sonst einen extra Schalter für Play/Pause machen.
Aber vielleciht hat jemand eine Idee.

Schönen Abend

Hallo Andres,

ich verweise dich mal auf den Thread zu meiem Fork, da das Thema gerade aktuell ist und du nicht der einzige bist, der den Drehencoder verwenden will.
Hier eine kleine Anleitung zu dem Encoder:

Ich habe aber gerade noch einen blöden Bug gefunden. Ich veröffentliche gleich ein neues Release und Poste es in dem Affenbpx Thread

1 „Gefällt mir“

Super Marco!!!
Funktioniert komplett!!!

Dankeschön, dass du noch so spät Support gibst.

1 „Gefällt mir“

Hallo,
wie ist es denn mit der neuen AiO+ Platine,
wird da der KY-040 auch an A1 A2 angeschlossen
oder funktioniert das auch an der „Rotary-Buchse“ (In der Beschreibung steht noch: in Planung) ?

In Planung heisst in dem Fall einfach, daß es „offiziell“ weder ein Kabel noch Software dafür gibt. Du kannst dir aber ohne weiteres ein Kabel basteln was an diese Buchse passt. Welche Pins es sind steht ja in der Doku.