KY040 Drehregler als Lautstärkeregler für den Raspberry Pi

Mit Drehreglern ist es möglich die Anzahl der bewegten „Schritte“ zu erkennen. Anders als übliche Potentiometer, welche in verschiedenen analogen Modulen wie z.B. Joysticks verbaut sind, wird beim KY040 eine Drehung in beide Richtung erkannt. Solche Drehregler sind üblicherweise in Radios und anderen drehbaren Einstellungsmöglichkeiten verbaut.

In diesem Tutorial bauen wir aus einem solchen KY040 einen Lautsärkeregler für unseren Raspberry Pi. So können wir bspw. auch einfach per Hardware die Lautstärke unseres Live-Radios oder unserer Jukebox regeln.

Natürlich kann das Tutorial (in abgewandter Form) auch für andere Projekte verwendet werden. Helligkeitsregelung, Zeiten einstellen, etc. sind Optionen die mir spontan einfallen, allerdings kann so ziemlich alles, was per Drehknopf eingestellt werden soll, damit umgesetzt werden.

 

Zubehör

Neben einem Raspberry Pi wird ein Drehregler mit 5 Pins benötigt. Zum Anschluss an den Pi werden außerdem Female-Female Jumper Kabel gebraucht.

Wer einen 3D Drucker besitzt, kann sich auch noch dazu einen aufsteckbaren Drehknopf drucken.

In dem Video habe ich zusätzlich die Daten auf einem 20×04 Zeichen Display anzeigen lassen (hier geht es zur Anleitung).

 

Raspberry Pi KY040 Verbindung

Der Drehregler hat insgesamt 5 Anschlüsse – davon zwei Spannungspole (VCC, GND) und einen zum Erfassen des Tastendrucks (SW). Mit Hilfe der restlichen zwei Pins (DT, CLK), kann die Richtung der Drehung festgestellt werden. Dabei wird beim Drehen eine Flanke erzeugt. Je nachdem, ob nach rechts oder links gedreht wird, ist die Spannung des anderen Pins digital 0 oder 1. Der SW Pin liefert hingegen solange eine Spannung, die der Knopf gedrückt wird.

Meine Pinbelegung sieht folgendermaßen aus:

Raspberry Pi KY040
GPIO 5 (Pin 29) CLK
GPIO 6 (Pin 31) DT
GPIO 13 (Pin 33) SW
3.3V (Pin 1) +
GND (Pin 6) GND

 

Raspberry Pi KY040 Steckplatine

 

Um den Drehregler verwenden zu können, laden wir der Einfachheit halber eine Bibliothek, welche auf Github verfügbar ist.

git clone https://github.com/conradstorz/KY040

Die enthaltene „KY040.py“ Datei können wir in anderen Skripten importieren.

 

Drehregler Anwendungsbeispiel: Lautstärke ändern

Im folgenden Video habe ich den Drehregler KY040 als Drehknopf für die Lautstärke am Raspberry Pi genommen. Das Drücken des Knopfes lässt den Sound stumm schalten (Mute).

Um auch einen solchen Lautstärkeregler nach zu bauen, habe ich ein Skript geschrieben, welches Systemaufrufe zum Ändern der Lautstärke aufruft. Die Basis bildet die eben geladene Klasse, welche im selben Verzeichnis wie das nachfolgende Skript vorhanden sein muss.

Dazu können wir z.B. einfach in den Ordner wechseln und eine neue Datei erstellen:

cd KY040
sudo nano volume_regulator.py

Folgender Inhalt wird eingefügt:

Gespeichert wird mit STRG+O und mit STRG+X wird der Nano-Editor geschlossen.

Das Skript leitet im Grunde genommen nur die jeweiligen Bewegungen weiter. Dazu lesen wir zuerst die aktuelle Lautstärke aus und erhöhen bzw. verringern diese um 5%. Den Wert kannst du natürlich nach Belieben anpassen. Wer mehr über den Alsa-Mixer erfahren möchte, kann einen Blick in die Dokumentation werfen. Hiermit können alle Sound-relevanten Daten (Lautstärke, Einstellungen, etc.) ausgelesen werden und auch in anderen Projekten verwendet werden (Car-PC als Beispiel).

 

Wie im Video zu sehen ist, ist die Erkennung leider nicht immer absolut genau. Hier kann die bouncetime geändert werden, um eine Variabilität zu gewährleisten. Ist der Wert allerdings zu groß, kann es sein, dass manche Drehungen gar nicht erkannt werden.

26 Kommentare

  1. Was wäre denn der Code für Up/Down/Enter?
    Ich überlege, so einen Regler als Steuerung für einen Squeezebox-Client zu verwenden.

    Antworten
  2. 1.2.2017
    An interesting tutorial. This has given me an idea.
    Volume control using the potentiometer as volume limit, but including
    with a digital potentiometer such as http://cdn-reichelt.de/documents/datenblatt/A200/DATASHEET_AD_8400.pdf (the data sheet is in English).
    The idea being that when the device is switched on the volume to be increased
    until equal to the analogue poti. This is to avoid the problen caused by cranking
    the volume poti up to max ,switching off, then later switching on to get a large
    scale dose of tinnitus.
    When I get enough time free I’ll try that out and let you know, I have a bit of a problem with my right arm, it is difficult to build alone – I need help.
    Perhaps someone has all ready done it,

    Antworten
    • My first thought was using a potentiometer as you said. But the problem ist, if you are near to the maximum (e.g. 9k from 10k) and you rotate again to the right: Then you will reach e.g. 1k and the volume is changing from 90% to 10%. This is why I decided to use use a rotary switch instead of a potentiometer. But if you have a better solution, I would be happy if you would share it with us.

      Antworten
  3. Für die Genauigkeit einfach 2 Kondensatoren ( steht auch im Datasheet drin ) benutzen.
    Eine gute Erklärung siehe hier:

    Antworten
  4. Könntest du bitte konkret aufzeigen wie du das Display zum Lautstärke anzeigen programmiert hast? Bin daran fast am verzweifeln. Vielen lieben Dank!

    Antworten
  5. Vielen Dank für das Toutorial
    Sieht so aus, als dass auch ich als Newbie damit mein Ziel erreichen könnte. Ich habe dazu noch ein – zwei Fragen und bin sehr dankbar, wenn mir jeman weiterhelfen kann.
    1. Muss ich die Bibliothek KY040 irgendwie einbinden, damit sie beim Start des Raspy gelesen wird?
    2. Ich betreibe mein PI mit einer externen Soundkarte, fundktioniert das oben beschreibene Vorgehen trotzdem?
    3. Ich habe Kodi 17 in einem Raspbian Jessie installiert, denkt Ihr, dass ich den Sound so trotzdem regeln kann?

    Vielen Dank für eure Hilfe

    Simon

    Antworten
      • Vielen Dank Felix für deine rasche Antwort! Das stimmt mich sehr optimistisch auszuprobieren!
        Weisst du wie ich die Quelle meiner Soundkarte auslesen- und welchen Pfad ich danach im Skript eingeben oder ersetzen muss?

      • Am besten du ließt dich ein bisschen in den amixer ein. Das Python Skript ruft ja lediglich den Shell Befehl dessen auf.

      • Soundkarte funktioniert leider nicht und ich habe nicht herausgefunden, wo ich die zu regelnde Quelle angeben kann.
        Aber ich glaube dem Rätsel ein Schritt näher gekommen zu sein und zwar habe ich in der alsa.conf die Werte:
        defaults.ctl.card
        defaults.pcm.card
        defaults.pcm.device

        alle auf 1 (USB AUDIO Codec) gestellt. Beim Reboot wird nun die USB Soundkarte als default erkannt. Wenn ich jetzt aber das Skript „volume_regulator.py“ starte kommt beim Bedienen des Drehreglers folgende Fehlermeldung:

        Traceback (most recent call last):
        File „/home/pi/KY040/KY040.py“, line 43, in _clockCallback
        self.rotaryCallback(GPIO.input(self.dataPin))
        File „volume_regulator.py“, line 11, in rotaryChange
        volume = readVolume()
        File „volume_regulator.py“, line 8, in readVolume
        return int(value)
        ValueError: invalid literal for int() with base 10: ’84n84n‘

        Weiss jemand von euch wie ich diesen Fehler beheben, bzw ich den USB AUDIO Codec in KY040.py integrieren kann? Oder gibt es einen anderen Weg die zu regelnde Quelle anzugeben?

  6. Analog geht, aber die USB Soundkarte kann man damit nicht steuern.
    Ich weiß nicht wie, wurde hier ja schon beschrieben.
    Meine USB Soundkarte funktioniert einwandfrei.

    Analog mit der int. Soundkarte macht keinen Sinn. Da kann man sich das Geld für den Drehschalter sparen. Oder hat noch jemand eine Lösung, falls nicht spart euch das Geld.

    Antworten
  7. Hi,
    ich habe alles so gemacht, wie es in dem Tutorial steht, allerdings habe ich damit leider keinen Erfolg.
    Vllt kann mir ja jemand weiter helfen. Vielen Dank!

    Grüße
    P.S.: Ich weiss jetzt nicht welche Angaben noch notwendig sind, von dem her bitte fragen….

    Antworten
      • So sieht die Ausgabe aus:

        pi@CarPi:/var/mail/KY040 $ sudo ./volume_regulator.py

        ./volume_regulator.py: 1: ./volume_regulator.py: import: not found
        ./volume_regulator.py: 3: ./volume_regulator.py: import: not found
        ./volume_regulator.py: 6: ./volume_regulator.py: Syntax error: „(“ unexpected

      • Hat sich erledigt. War einfach nur mein blöder Fehler, das Script nicht mir python zu starten….

        Grüße

        P.S.: Vielen Dank für das Tutorial! Sehr leicht verständlich!

  8. Hallo Felix,

    vielen Dank für dieses TuT 🙂 Das hat mich erst auf die Idee gebracht, den KY040 zu verwenden!

    Ein Problem habe ich noch, an dem ich seit gestern bastel.
    In der Variable wird ja die aktuelle Lautstärke gespeichert, was bei dem analogen Ausgang des Rai kein Problem ist. Ich nutze jedoch eine USB Soundkarte und dort muss ich in der Variable (oder in zwei?) die Lautstärke je Kanal speichern. dies bekomme ich nicht eingebaut.

    Auslesen und Ausgeben geht ja mit: amixer sget Speaker | grep ‚Right:‘ | awk -F'[][]‘ ‚{ print $2 }‘

    Vielleicht kann mir jemand erklären, wie ich dies je als Variable speichere um es in Deinem Code zu verwenden.???

    Vielen Dank und Grüße
    Sören

    Antworten
  9. Hallo!

    Danke für das TuT. Hab es auch mit einer USB Soundkarte zum laufen gebracht. Das Problem hierbei war, dass beim Lautstärke auslesen der linken und rechte Kanal ausgegeben wurde. Hab ich recht einfach gelöst indem ich in Zeile 8 einfach [:-4] in den int Befehl eigegeben habe

    return int(value[:-4])

    Damit kommt jetzt bei der Ausgabe z.B. nur 67
    Vorher war es

    67
    67

    und Pyhton hat damit nichts anfangen können.

    Ein Problem habe ich aber noch. Ich würde gerne, wie im Video zu sehen, mit einem Druck auf den Taster die Lautstärke stumm schalten. Bin noch absoluter Python Anfänger und habe es selbst leider nicht zum laufen gebracht. Wäre nett wenn mir wer helfen könnte.

    Antworten
    • Die Lösung ist mit
      return int(value[:-4])
      nicht wirklich optimal.
      Sobald die Lautstärke einzeilig wird gibt Pyhton nur noch Fehler aus.
      Habe aber jetzt eine Lösung gefunden. Beim Auslesen der Lautstärke einfach ein „uniq“ dranhängen. Damit werden Dupletten gelöscht und man hat nur noch z.B. 45 als Ausgabe.
      value = os.popen(„amixer get PCM|grep -o [0-9]*%|sed ’s/%//’|uniq“).read()

      Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

Blog abonnieren

Abonniere Raspberry Pi Tutorials, um kein Tutorial mehr zu verpassen!