Raspberry Pi Pico: Fertiger Prototyp des Tastatur/Maus/GamePad-Emulators mit CircuitPython

Nachdem ich im ersten Artikel über den Raspberry Pi Pico die Hardware, die technischen Daten und das Pinout des Pico vorgestellt und mit der STM32 Bluepill, dem Arduino Nano und dem ESP8266 verglichen haben, blieb die Frage im Raum stehen, wie einfach sich der Pico programmieren lässt und ob er ein ernstzunehmender Konkurrent zu den etablierten Mikrocontrollern ist.

Im zweiten Artikel ging es dann um die Installation des UF2-Files für MicroPython und die erste Programmierung darin über Putty, was sich als wenig komfortabel herausgestellt hatte.

In dritten Artikel habe ich die Entwicklungsumgebung Thonny für MicroPython auf dem Raspberry Pi Pico vorgestellt und außerdem ein paar Python-Programme geschrieben: Um die interne LED zum Blinken zu bringen, den internen Temperatursensor auszulesen und die Temperatur auf einem OLED-Display anzuzeigen. Auch der Paketmanager und die Suche nach Libraries wurde kurz erklärt. Auch wenn schlussendlich alles lief, ging mir die instabile serielle Verbindung auf die Nerven.

Im vierten Artikel ging es um eine weitere Entwicklungsumgebung: CircuitPython. Das ist ein Ableger von MicroPython, der von Adafruit weiterentwickelt wurde und gegenüber Thonny so einige Vorteile hat. Das Hochladen ist zum Beispiel komfortabler, auf der anderen Seite fehlt ein Paket-Manager.

Im fünften Artikel habe ich dann einen Breadboard-Prototypen aufgebaut, mit Tastern, um ein Tastatur-Tastendruck, einen Maustastendruck, einen GamePad-Feuertastendruck und auch das Mausrad per Drehgeber zu emulieren und die entsprechende Aktion auf dem angeschlossenen Windows-PCs auszuführen. Die Debug-Ausgaben geschahen dabei über die serielle Schnittstelle und das angeschlossene OLED-Display:



Das fertige Gerät


Inzwischen ist das endgültige Gerät fertig, bzw. der Prototyp dazu. Zu kaufen wird es das nämlich nicht geben, sondern es gibt nur dieses eine Exemplar für den persönlichen Einsatz bei mir. Und das möchte ich euch zuerst einmal vorstellen, bevor ich dann dazu komme, wie genau ich das zusammengebaut habe. Vielleicht will es ja jemand für den privaten Gebrauch zuhause nachbauen.

Oben links hat der Tastatur/Maus/GamePad-HID-Emulator, oder "HID-Master", so will ich ihn mal kurz nennen, eine Tastatur mit 20 Tasten: 12 programmierbaren Funktionstasten, die die Tastenkombination Windows+Strg+Alt+Shift plus F1 bis F12 drücken, die auf Windows-Seite von AutoHotkey abgefangen werden und dann je nachdem, welche Anwendung gerade läuft, diese Anwendung steuern oder Textschnipsel darin einfügen.

Darunter folgen die Tasten für linke (L), rechte (R) und mittlere (M) Maustaste und die Kurztasten zum Kopieren (C), Einfügen (V) und Ausschneiden (X).

Die Tasten A für Autofire und F für Rapidfire haben eine besondere Funktion: Autofire drückt in schneller Wiederholung eine Taste ganz automatisch, bis die Funktion durch erneuten Druck wieder abgestellt wird; und Rapidfire "schießt" nur, solange die definierte Taste niedergedrückt gehalten wird. Beim ersten Druck auf A oder F wird nach der zu feuernden Taste gefragt, die man einfach danach drückt. Das können einer der drei Maustasten oder eine der beiden Joystick-Feuerknöpfe sein.

Rechts daneben gibt es ein kleines OLED-Display, dass die Taste, die gerade niedergedrückt ist, anzeigt; als auch die Richtung, in die ein gedrückten Digital-Joystick gedrückt wird. Außerdem dient sie zur Anzeige der Autofire und Rapidfire-Taste.

Links sieht man drei Kabel aus dem HID-Master herausgehen. Das Kabel in der Mitte ist das USB-Kabel zum Anschluss an den PC. Das obere endet in einer D-Sub-15-Buchse und ist ein PC-Gameport-Anschluss, um hier die alten Gameport-Joysticks anzuschließen, die es zu Zeiten von Soundkarten gab. Darin ist ein analoger Joystick und zwei Feuerknöpfe. Die Bewegungen des Gameport-Joysticks werden vom HID-Master ausgewertet und an den USB-Port weitergeleitet, so dass der Windows PC von einem ganz normalen USB-Joystick ausgeht. Wenn gewünscht, dann kann der HID-Master einen Feuerknopf auf Dauerfeuer stellen und zwar unabhängig davon, ob der Joystick das kann. Der HID-Master emuliert das entsprechende Signal einfach selbst.

Und das untere linke Kabel führt zu einem D-Sub-9-Stecker, wie er in C64 und Amiga und vielen anderen Homecomputern eingebaut war. Er ist zum Anschluss von 9-poligen digitalen Joysticks wie dem legendären Competition Pro. Da digital, gibt es hier nur Voll-Ausschläge des emulierten Joystick. Das macht die Reaktionen schneller, lässt aber keine feinen Abstufungen bei der Steuerung der Spielfigur zu. Wer schon einmal eine Autorennsimulation auf dem Amiga und dem PC gespielt hat, weiß, was ich meine: Das Lenkrad lässt sich mit einem analogen Joystick sehr viel feiner einschlagen und das Auto lenken als mit einem digitalen. Natürlich kann auch hier Dauerfeuer angestellt werden.

Rechts unter dem OLED-Display und neben der Handballenauflage gibt es dann einen großen Drehknopf, einem Jog-Dial nachempfunden. Dies emuliert das Mausrad. Nach rechts gedreht scrollt es herunter, nach links gedreht nach oben. Gleichzeitig wird einer der 8 LEDs unter dem Jog-Dial in blau erleuchtet, die mit der Drehrichtung weiter wandern. Nicht unbedingt nötig, aber ein nett anzuschauendes Gimmick.

Die LEDs dienen auch dazu, die Richtung, in die ein Joystick gerade gedrückt wird, anzuzeigen. Das macht den HID-Master auch gleichzeitig zum Joystick-Test-Gerät, ohne einen Monitor anzuschließen. Beim analogen Joystick wird die Helligkeit der LEDs mit PWM geregelt, um anzuzeigen, wie weit der Ausschlag in eine Richtung ist.

Video des fertigen HID-Master

Aber was rede ich groß und erkläre viel mit Worten, wenn ein Demonstrations-Video das viel besser zeigen kann:



Aufbau des Gerätes in Modulen

Da der HID-Master mit seinen vielen Tasten doch eine ziemliche Lötarbeit verspricht, bin ich so vorgegangen, das Gerät in Modulen aufzubauen. Es gibt:

Das Tastatur Modul


Meine ersten Überlegungen betrafen die Tastatur: will ich wirklich die kleinen Mikro-Taster verwenden, wie bei meinem Multitimer-Projekt?

So richtig schön sind diese kleinen Tasten ja nicht. Okay, man kann sie größer aus dem 3D-Drucker lassen aber so ein richtig gutes Tippgefühl wird dabei nicht aufkommen. Und ich will die Tasten doch viel und gerne benutzen...

Also habe ich mal in meinem Alt-Hardware-Fundus gegraben und eine alte AT/XT-Tastatur gefunden, eine QTRONIX KT-30M von 1989, noch mit seriellen und DIN Anschlüssen:




Auch der Trackball war noch altertümlich mit aufliegender Trackballkugel und Lochrad-Abtastung, weder leichtgängig noch präzise.

Aber unter den vergilbten Tastenkappen verbargen sich blaue Tasten mit der Aufschrift Cherry. Die leicht klickenden blauen Cherry-Switches sind sehr gute Tasten, die so schnell nicht kaputt zu kriegen sind und ein gutes Tippgefühl haben.

Was lag also näher als die Tastatur auszuschlachten und die über 100 blaue Cherry-MX-Switches zu ernten?



Mal eben die benötigten 20 oder 24 Tasten auslöten, so einfach war es dann leider doch nicht. Die Cherry-Switches waren oben in eine Metallplatte eingeklippst und dann mit den Pins durch eine große Platine und dann auf der anderen Seite festgelötet.

Das hieß: erst einmal über 200 Lötpukte an den Unterseiten der Switches entlöten - was für eine Heidenarbeit. Zum Glück hatte ich mir letztens für kleines Geld (unter 10 Euro) eine beheizte Entlötpumpe gekauft. Natürlich Schrott im Vergleich gegenüber einer professionellen Entlötstation, aber trotzdem noch besser, als mit normaler Entlötpumpe und Lötkolben herumhantieren.

Dann doppelt checken, dass auch nichts mehr festhängt und gegebenenfalls noch weitere Lötreste entfernen und dann die Metallplatte mit den Switches vorsichtig von der Platine trennen.


Danach dann jede einzelne Tastenkappe abziehen, dafür hatte ich zum Glück noch ein kleines Tool, eine Art gebogene Metallklammer mit Widerhaken an der Unterseite (siehe oberes Foto auf der Tastatur) gefunden. Und dann jede einzelne Taste an den jeweils zwei Einklipps-Nippeln gleichzeitig zusammendrücken und mit etwas hin und her vorsichtig aus der Metallplatte ziehen.

Nachdem ich also mindestens 500 mal an den Tasten herumgefummelt hatte, hatte ich endlich meine Ausbeute: gut 100 Cherry-Switches und gut 100 Tastenkappen. Die wurden erst einmal in einer Reinigungsflüssigkeit für einen Tag eingelegt, damit die Tasten einweichen konnten.

Danach mit der elektrischen Billig-Zahnbürste aus China, die nicht mal zum Zähneputzen taugte, aber die Reinigung wohl ein klein wenig einfacher macht (kann auch sein, dass ich mir das nur einbilde, weil ich insgeheim nicht wollte, dass die 4 Euro oder so dafür aus dem Fenster geworfen waren), die Tastenkappen gesäubert. Den Gilb wurde ich so allerdings nicht los. Aber zumindest sind die Tasten jetzt keimfrei und sauber.


Dann stand ich vor der Entscheidung eine eigene Einfassung für die Tasten zu designen und mit meinem Anycubic i3 mega 3D zu drucken oder aber die Metallplatte wieder zu verwenden.

Eigentlich hatte ich an 24 Tasten gedacht, weil das das Maximum für drei 74HC165er ist, aber die Metallplatte bot mir maximal 20 Tasten mit einer regelmäßigen Breite von 4 Tasten. Und zwar der Teil vom Ziffernblock. Danach zerstörte die doppelt große Enter-Taste das Muster (siehe Tastatur-Foto oben).

Also blieb es bei 20 Tasten: fünf Zeilen zu jeweils 4 Tasten. Wobei ich da mit dieser Tastatur einen Glücksgriff getan habe, denn normalerweise hat man bei einem NumPad nur zwei bis vier regelmäßige Zeilen. Und der Metallrahmen hatte schon die richtigen Abstände und Abmessungen und war eben aus Metall und das war ein Vorteil gegenüber PLA. Die Metallplatte ist steif und gibt den Tasten beim Wiedereinklippsen einen guten Halt.


Als nächstes habe ich mir Gedanken gemacht, welche 20 Tasten ich denn gerne hätte. Die entsprechenden Tastenkappen habe ich dann herausgesucht und die 4x5-Tastatur schon einmal dabei ausgestattet. Am wichtigsten waren mit möglichst viele frei belegbare F-Tasten, die außerdem einen schönen Block bilden. Für die unteren Tasten brauchte ich auf jeden Fall die drei Maustasten und eine Autofire und Rapidfire-Taste. Blieben noch drei für STRG+C, V und X.

Von der ursprünglichen Idee, hier auch nocheinmal die Cursor-Tasten zu haben und dann ggf. auf Joystick, WASD etc. für Spiele abzubilden, musste ich mich verabschieden. Aber es hält mich ja nichts davon ab, einen Competition Pro Joystick oder das Gravis Gamepad an den HID-Master anzuschließen und für alte DOS-Spiele dann statt der Joystick-Signale Tastendrücke weiterzuleiten. Doom mit dem Joystick spielt sich bestimmt auch nicht schlecht.

20 Tasten und damit 20 belegte GPIO-Pins sind natürlich ein bisschen viel für den Pico, wenn ich dann auch noch andere Sachen damit machen will. Also muss ich einen kleinen Trick anwenden und 74HC165 Schieberegister benutzen.

Wie man die Schieberegister benutzt, habe ich in meinen Artikeln Mit dem 74HC165-Schieberegister Eingabe-Pins und Leitungen einsparen und 74HC165-Schieberegister kaskadieren und mehr als 8 Taster verwalten genau erklärt, hier nur noch einmal in Kürze:

Ein 74HC165 ist ein IC, dass an 8 Pins digitale Zustände (hier: gedrückt bzw. nicht gedrückt) parallel einsammelt und dann bitweise, also seriell, weiterschickt. Außer zu einem Mikrocontroller kann der Chip auch an andere 74HC165 weiterschicken. Mit drei 74HC165 kann man also bis 24 Tasten abfragen und braucht dafür dann nur vier Steuerleitungen statt 24 Einzelleitungen.

Da wir hier mit 3.3 Volt arbeiten, sollte es die HC Variante sein, die ein High schon bei niedrigen Voltwerten erkennt und eher nicht die alte LS-Variante. Die HC-Variante ist aber sowieso erste Wahl, da günstiger, neuer, stromsparender und schneller. LS-Varianten braucht man wirklich nur noch für Uralt-Hardware wie im C64 aus 5V-Kompatibilitätsgründen.

Also werden die 20 Tasten nicht direkt an den Pico, sondern als eine 74HC165-Kaskade angeschlossen. Dafür brauchen wir eine kleine Zusatzplatine, auf der wir schon mal Versorgungsspannung, Masse und Signalleitungen verlöten können. Damit das Modul auch irgendwann mal wieder, zum Beispiel im Fehlerfall, herausgenommen werden kann, gibt es eine kleine Buchse, in die wir später die Kabel zum Pico stecken werden.



Die Platine bekommt ihren Platz dann (von der Unterseite her gesehen) rechts von der Tastatur, mit etwas Abstand zur Tastatur, damit ich noch die Anschlüsse der ICs verlöten kann. Hier muss ich ja noch 20 "Strippen ziehen".

Dazu drucke ich mir einen passenden Rahmen mit meinem Anycubic i3 mega 3D-Drucker aus. An der Stelle, wo die Platine kommt, hat es eine kleine Vertiefung in der ich die Platine mit doppelseitigem Klebeband festklebe.

Auch die Tasten habe ich festgeklebt, mit Epoxidharz und nur an der Unterseite. Die waren mir dann doch ein bisschen zu wackelig. Bei der QTRONIX-Tastatur waren die Tasten ja alle auf der Unterseite durch die Platine angelötet und felsenfest. Aber nur mit den beiden Klipps-Teilchen hielten sie mir nicht gut genug. Zur Not bekommt man eine kaputte Taste aber trotzdem wieder raus, wenn eventuell auch nicht zerstörungsfrei, aber hey, ich habe ja noch über 80 Ersatztasten.



Die Sockel auf der Vorderseite werde ich nach den weiteren Lötarbeiten mit 74HC165ern bestücken. Es ist ja nicht nötig, sie der Hitze, die beim Löten entsteht, auszusetzen.

So sieht das Tastatur-Modul übrigens von der Seite aus:




Danach ziehe ich zuerst die 3.3V-Schiene ein. Denn an jeweils den einen Pin der Taster muss 3.3V anliegen.

Wenn diese Taste dann später gedrückt wird, werden diese 3.3V an den 74HC165 weitergegeben, der dann an seinem Pin ein High erkennt und dann das entsprechende Einser-Bit weitergibt.


Der andere Pin der Taster wird mit einem 10 KΩ-Widerstand auf Low gezogen. Wenn die Taste also nicht gedrückt ist, liegen 0V am 74HC165-Pin an und der gibt ein Nuller-Bit weiter.

Dafür brauchen wir eine Ground-Schiene, die von der anderen Richtung mit blankem Draht eingezogen wird. Damit hier nicht umherbiegt, nehme ich dickes Kupferkabel, das ich normalerweise für 230V/16A-Hausleitungen benutze. Das gibt Festigkeit. Es soll doch bloss keinen Kurzschluss zwischen der blanken Ground und der blanken Versorgungsspannungsleitung geben.


Schließlich muss noch jeder zweite Tastaturpin an die jeweiligen Eingangs-Pins der drei 74HC165er gelötet werden. Spätestens hier zahlt es sich aus, ein rechteckiges Raster beim Löten eingehalten zu haben und nicht überall wilde Kabel kreuz und quer gezogen zu haben.

Und so will ich es bei der Verkabelung der 20 Signalleitungen in orange auch halten. Zur Stabilisierung versenke ich sie jeweils ein bisschen in den "Gräben" zwischen den Tasten.

Das die Kabel jeweils die richtige Länge haben dient auch der Stabilität. Die kleine Platine wird jetzt praktisch von den angelöteten Drähten gehalten. Die Klebung der Platine wäre gar nicht mehr nötig, war aber natürlich doch sehr hilfreich beim Einlöten.

Damit ist das Tastaturmodul fertig. Erst einmal weg vom Lötarbeitsplatz und rüber an den Computer: Programmieren der 74HC165-Auswertung in CircuitPython und Testen der Schaltung, ob alles so funktioniert, wie es soll und die einzelnen Tasten schalten und voneinander unterschieden werden können.

Dabei muss insbesondere das 74HC165 Protokoll laut Datenblatt eingehalten werden, das regelt wie die Steuerleitungen im einzelnen gesetzt und die Bits abgerufen werden müssen:



Im Anfangszustand ist CLK INH auf High und Ser auf Low. SH/LD wird einmal auf Low, High gesetzt. Clock wird in regelmäßigen Abständen abwechselnd auf High und Low geschaltet. Danach werden dann die einzelnen Bits ausgelesen.

Es gibt zwar auch für CircuitPython 74HC165 Libraries, aber die sind totaler Overkill, wenn man weiß, wie es geht. Die folgenden Zeilen CircuitPython-Code reichen nämlich völlig aus, die 20 (oder auch 24) Tastendrücken "einzusammeln":

#### für Schieberegister Tastatur def keybRead(): # Anfangs-Status lt. Datenblatt keybClock.value = False keybShift.value = True keybClockInh.value = True for i in range (0,24): keybClock.value = False keybShift.value = False sleep(HC165_pulseLength) keybClock.value = True keybShift.value = True sleep(HC165_pulseLength) keybClockInh.value = False state=0 for i in range (0,24): keybClock.value = False sleep(HC165_pulseLength) keybClock.value = True sleep(HC165_pulseLength) val = keybData.value if val: state = state + pow(2,i) return (state) Die ersten bzw. letzten 4 Bits sind permanent Low, also Null, weil ich diese ja nicht gebrauche. Deswegen habe ich sie auch in der Schaltung direkt mit GND verbunden, damit sie einen definierten Zustand haben.

Je nach gedrückter Taste kommt ein anderer State-Code heraus. Die erste Taste liefert eine 1, die zweite eine 2, die dritte eine 3, die zwanzigste eine 1'048'576 und so weiter. Und werden erste und zweite Taste gleichzeitig gedrückt, dann addieren sich die Zustände zu 1 + 2 = 3.

Wir wollen aber nur immer eine Taste gleichzeitig benutzen. Das "mehrere gleichzeitig" wird erst später bei den Joysticks wichtig, weil wird wollen ja auch schräg lenken können.

Video des Tastatur Moduls

Über das Tastatur-Modul habe ich ein kleines Video gemacht, in dem ich auch ein klein wenig auf die Kaskadierung der 74HC165 eingehe:



Das OLED-Modul

Nachdem ich rechts von der Tastatur sowieso noch einmal extra Platz für den Stecker für das Tastaturmodul lassen muss, habe ich mir die Sache so angeschaut und mir ist aufgefallen, dass jetzt genügend Platz rechts neben der Tastatur für das OLED wäre.

Da der HID-Master links neben meiner Haupt-Tastatur steht und mit der linken Hand bedient wird, ist der Platz rechts von der Tastatur und oberhalb des Jog-Dials eigentlich ideal, weil er niemals durch die von links tippende Hand, noch durch die von unten kommenden, scrollenden Hand verdeckt wird und deshalb immer gut ablesbar wäre.

Die Ablesbarkeit könnte man durch eine leichte Neigung noch verbessern. Das Behältnis für das OLED müsste man dann ein bisschen höher machen, aber auch das stört nicht bei der Bedienung der Tasten, denn es gibt ja ein wenig Abstand rechts der Tasten.

Befestigt soll das OLED-Behältnis werden, indem es in eine Auflageplatte für unter die Tastatur übergeht. Der linke Teil wird dann von oben auf die Metallplatte zwischen die Tasten geklebt, darf aber nicht zu hoch sein, damit man die Tasten noch ganz niederdrücken kann. Gleichzeitig darf er aber auch nicht zu dünn werden, damit er noch stabil genug bleibt.

Auf der rechten Seite ist dann das unten hohle OLED-Behältnis, das noch oben nur einen Ausschnitt hat, durch den man das OLED ablesen kann. Das muss ganz genau ausgemessen werden, damit die Ausschnitt auch stimmt und nichts verdeckt. Für die Befestigung des OLEDs unterhalb kommt eine Presspassung zum Einsatz, in die der Rahmen des OLED gedrückt wird. Das OLED selbst ist sehr dünn und empfindlich und deshalb packe ich es nach Erhalt immer sofort in einen 3D-gedruckten Plastikrahmen, der es rundum schützt. Die Aussparung ist genau passend für diesen Rahmen.

Außerdem werden die zwei Kabel für Spannungsversorgung und die zwei Kabel für die I2C-Steuerung angelötet und nach außen geführt. Diese enden wieder in einer Buchse, die ich auf die Unterseite des Tastatur-Moduls klebe.



Dann wird das OLED-Modul auf das Tastatur-Modul geklebt. Dummerweise stellt sich dabei heraus, dass das OLED-Behältnis doch nicht hoch genug ist und der OLED-Rahmen auf ein 74HC165-IC drückt. Aber mit ein bisschen feilen kann der nötige Millimeter Platz doch noch geschaffen werden... Bevor ich nochmal alles neu drucken muss...

Tastatur- und OLED-Modul verheiratet sieht dann so aus:



... und bildet später den oberen Teil des HID-Masters. Darunter wird dann der Pico und das Jog-Dial-Mausrad seinen Platz finden.

Video des OLED Moduls

Auch über das OLED-Modul gibt es ein kurzes Video:



Das Jog-Dial-Modul

Als nächstes kommt das Jog-Dial-Modul dran, das für unsere Mausrad-Emulation zuständig ist. Herzstück davon ist der Drehgeber, auf den das Jogdial gesteckt wird.

Der Drehknopf sollte nach meinem Gefühl etwa fünf Zentimeter Durchmesser haben, weil das einfach der natürliche Abstand zwischen meinem Daumen und meinem Zeigefinger bzw. Mittelfinger ist, wenn ich meine Hand ganz normal halte. So wird es am bequemsten sein, daran herumzudrehen. Die Höhe ergibt sich einfach aus der Höhe des Drehgebers. Und war mir mir drei Zentimeter eigentlich zu hoch.

Aber da es nicht anders ging, schluckte ich die Kröte. Später stellte sich dann heraus, dass das eine doch sehr angenehme Höhe ist und etwas mehr als meine Daumenbreite.

Der Drehgeber braucht natürlich eine feste Basis, auf dem er sich möglichst exakt horirontal drehen kann. Er soll nicht eiern und möglichst nich aufsetzen. Oder aber er soll immer ein wenig aufsetzen, um ein Eiern auszuschließen; aber dann schleift er. Aber um das Problem kümmere ich mich später.

Zuerst kommt erst einmal der Drehgeber möglichst senkrecht in die Mitte einer mindestens 5 x 5 Platine. Da hatte ich eine passende im Fundus.

Beim Abzählen der Pins des Picos ist mir dann aufgefallen, wenn ich auf den Drehgeber-Taster verzichte, ich noch genau 8 GPIO-Pins frei habe. Das wäre doch ideal für acht LEDs unter dem hohlen Drehknopf. Den würde ich dann mit transparenten Filament 3D-drucken und könnte die Oberseite von unten bescheinen. Zum Beispiel, um die Drehrichtung anzuzeigen oder auch die Richtung, in die ein Joystick gedrückt wird.

Also möglichst im Kreis um die Mittelachse des Drehgebers die LEDs angeordnet. Nur welche sollte ich nehmen? Erst schwebten mir rote vor, doch die waren mir dann nicht hell genug. Schön hell waren meine blauen LEDs und das ist ja auch einen coole Farbe.

Zu hell wollte ich es dann auch nicht habe und wählte 100 Ω-Widerstände, damit die LEDs nicht ganz so arg hell waren. Außerdem trägt das zur Haltbarkeit bei, wenn man die nicht auf Anschlag fährt.

Auf der Rückseite der Platine dann also die Vorwiderstände (hier gibt es übrigens einen Widerstandsrechner) eingelötet und die anderen Enden an der Seite der Platine herausgeführt, um sie später mit dem Pico zu verbinden:





Dann ging es um den 3D-Druck des passenden Rings, ersteinmal einen nicht so hohen Teil, um zu testen, ob das mit der Mitte hinhaut und ob genug Platz ist. Ich habe mich dabei um eine Riffelung der Außenhaut entschieden, um das Jog-Dial griffiger zu machen.

Nachdem der tiefe, schwarze Ring ganz gut passte, noch ein paar Versuche für den Aufsatz auf die Drehgeberachse gedruckt. Zuerst auch in schwarz, was gut passte und sich auch leicht wieder abziehen ließ. Die Festigkeit könnte ich dann ja später durch Klebeknete herstellen; lieber zu locker als zu fest.

Als alles soweit perfekt passte Achsenaufsatz und Drehknopf vereint und in transparentem PLA ausgedruckt. Jetzt kam der spannende Augenblick: War alles mittig? Eiert das Ding etwa? Ist es zu hoch? Nicht hoch genug? Reicht der Platz?

Das transparente PLA hatte im Gegensatz zum schwarzen PLA dann seltsamerweise kein Spiel mehr und als der Drehknopf dann einmal auf der Achse war, war er nicht wieder abzubekommen. Das zum Thema "etwas Spiel lassen". Zum Glück passte aber alles und es schleifte fast nichts, nur manchmal, aber das lag am Drehgeber, der eben doch ein bisschen Spiel in der vertikalen Achse hat, was sich bei einem so großen Drehknopf dann natürlich ausweitet.

Allerdings den obersten Widerstand musste ich nach unten versetzen, weil doch die Gefahr bestand, dass das Jog-Dial-Äußere daran schleift oder hängenbleibt. Ein wenig Glück gehört wohl dazu.



Das Jog-Dial/Pico-Modul

Links von dem JogDial soll der Pico Platz finden. Bevor es jetzt erneut ans Verlöten geht, lasse ich wieder einen Rahmen aus meinem 3D-Drucker: Rechts mit einem Ausschnitt, in den ich die Jog-Dial-Platine drücken kann und links mit einem Rahmen mit Mittelsteg, auf den ich meinen Pico kleben kann.

So habe ich Platz, Kabel auf der Unterseite des Pico anzulöten. Die Oberseite ist ja sowieso weiterhin zugänglich. Darauf, wie ursprünglich angedacht, den Pico zu sockeln habe ich verzichtet, weil ich den unteren Teil möglichst flach haben will. Wenn der nämlich zu hoch wird, dann komme ich an die Tasten nicht gescheit heran. Ich könnte zwar den ganzen hinteren Teil noch ein bisschen erhöhen, aber das würde das komplette Gerät höher machen. Und eigentlich möchte ich das möglichst flach.

Dann bemerke ich, dass der Platz für den USB-Stecker nicht ganz ausreichend ist. Statt den Rahmen noch einmal neu zu drucken, erhitze ich einfach einen großen Flach-Schraubendreher über einem Teelicht und drücke damit das PLA platt. Das drückt das Infill zusammen und den Oberseite des Druckes auf die Unterseite des Druckes. So kann man nachträglich noch ein wenig korrigieren. Sieht zwar nicht schön aus, aber an dieser Stelle wird es später sowieso keiner mehr sehen. Hauptsache, der USB-Stecker passt jetzt.



Die 8 Leitungen für die LEDs löte ich gleich an an GP0 bis GP5 und GP14 und GP15. Außerdem die Leitungen für den Drehgeber an GP19 und GP20 und für das OLED an GP16 und GP17. Bleiben noch einige frei. Die brauche ich später für die Joysticks.

Der Jog-Dial/Pico-Modul-Rahmen ist natürlich genauso breit wie das obere Tastatur-Modul. Später kommt beides auf eine große Grundplatte mit erhöhtem Rahmen und wird dann untereinander Platz finden.

Alle Module nebeneinander

Das sieht dann so aus:



In den unteren Außenrahmen werden oberes und unteres Modul nebeneinander gestellt und verschmelzen so zu einer Einheit. Im Rahmen gibt es links zwei Löcher für die Joystick-Kabel, die von innen mit Heißkleber fixiert werden, damit man von außen nicht aus Versehen die Kabel vom Pico reißt, an dem die Joystick-Leitungen angelötet werden.


Die Joystick-Signalleitungen werden auch noch an den Pico gelötet. Dafür taugt jetzt die Oberseite des Pico sehr gut.

Erfreulich, dass man den Pico so schön von beiden Seiten belöten kann. Auf der Oberseite muss man allerdings noch ein bisschen vorsichtiger sein, dass man nicht an die Komponenten des Picos dort kommt, denn dies ist die Bestückungsseite.

Oben links habe ich dem Pico einen Reset-Taster gegönnt, den ich allerdings selten benutzt habe. Und wenn die Entwicklung erst abgeschlossen und der Deckel drauf ist, dann wird er nicht mehr benutzt werden.

Rechts daneben finden sich an A0 und A1, also den analogen Eingängen noch zwei 100 kΩ-Widerstände, die auf Ground gehen.


Diese müssen sein, um eine Spannungsteilungsschaltung zu realisieren, denn nach ein wenig durchmessen habe ich herausgefunden, dass die Masse zwar in den Gameport-Anschluss geführt wird, aber nicht bei den dort verbauten Potis ankommt.

Die Potis hängen nur an Versorgungsspannung und Mittelpin der Potis, liefern damit also keine Spannung, sondern nur einen variablen Widerstand. Um aus dem Widerstand eine Spannung zu machen, die an A0 / A1 gemessen werden kann, brauchen wir eben diese beiden Spannungsteilungs Widerstände.

Damit geht es doch ganz schön eng im Gehäuse zu. Die Drähte übersichtlich und strukturiert angeordnet zu haben zahlt sich hier aus.

Deckel drauf und fertig

Fehlt nur noch ein Deckel für den unteren Teil. Aus dem soll dann nur das Jog-Dial herausschauen. Die Platine verschwindet unter dem Deckel.

Den Deckel mache ich wieder so flach wie nötig, aber so stark wie nötig. Schließlich soll hier meine Hand ruhen, wenn ich oben auf die PF-Tasten drücke. 2 Millimeter Stärke und viele Stützen sorgen für Stabilität.



Da bei mir das USB-Kabel gleich in die Kurve nach oben zum PC geht, habe ich es innen mit Heißkleber festgeklebt. Als Vorsorge. Nicht, dass mir dann irgendwann der USB-Port vom Pico abreißt, wenn sich das USB-Kabel in seiner Buchse immer ein bisschen hin und her bewegt.

Der untere Deckel ist nur mit Klebeknete befestigt. Im Reparaturfall kann ich dann den Deckel immer noch lösen und komme so an alles dran. Und den Reparaturfall hatte ich dann auch gleich. Bei meinem Vorstellungsvideo (ganz am Anfang dieser Seite) wollte die V-Taste ja nicht so richtig. Das lag daran, dass der eine Pin an der 3.3V-Schiene nicht so richtig angelötet war. Aber das Auseinandernehmen, Durchmessen mit dem Multimeter und Nachlöten ging eigentlich ganz gut. Dank der modularen Bauweise.

Video des Pico/Jog-Dial Moduls

Auch über das Pico/Jog-Dial Modul gibt es ein Video. Darin gehe ich auch nochmal auf die Eigenheiten der Gameport-Joysticks ein:



Fazit

Da habe ich mir ein echtes Multifunktionsgerät zusammen gebastelt. Und jeden einzelnen Pin des Pico ausgenutzt. Und davon hat der Pico reichlich. Und es lässt sich hervorragend etwas direkt an den Pico herumlöten. Außerdem ist er schön flach und hat eine hohe Qualität bei einem akzeptablen Preis.

Auch das mit dem PWM auf jedem GPIO-Pin gefällt mir am Pico, wie sowieso die Flexibilität an den GPIO-Ports und dass ich die für I2C, SPI oder UART benutzten kann, ganz wie es mir gerade in den Kram passt.

Natürlich hat der Pico kein WLAN wie der ESP8266 oder ESP32. Und keine Echtzeituhr wie die STM32-Bluepill. Aber da bin ich ja schon im ersten Artikel drauf eingegangen.

Der HID-Master ist größer geworden, als ich das ursprünglich im Kopf hatte. Logo muss der genau so groß rauskommen, aber so richtig klar wurde mir das dann doch erst, als ich ihn neben meine Haupt-Tastatur stellte: Er ist fast genau so hoch und etwa ein Drittel so breit. Dann noch den alten Trackball für die linke Hand daneben wird schon ein bisschen knapp auf dem Tisch.

In den Drehknopf für das Mausrad habe ich mich schon gewöhnt. Und die PF-Tasten werde ich sicherlich auch zu schätzen wissen, muss mich daran aber erst noch ein bisschen gewöhnen. Mal schauen, was am Ende als wie nützlich herausstellt.

Nachtrag 2022-02-03

Nachdem ich den HID-Master ein wenig gebraucht habe, habe ich bermerkt, dass ich den Trackball, der links daneben steht, so gut wie gar nicht mehr benutze. Wohl, weil ich meinen Arm dafür unnatürlich weit nach links ausstrecken muss. So fehlte mir irgendwie ein Mausersatz, den ich mit der linken hand bedienen kann.


Dann erinnerte ich mich an mein altes Touchpad, dass ich mal aus einer Indukey-Industrie-Tastatur "geernet" hatte. Den Tastatur-Teil brauchte ich damals für meinen C64DTV als C64-Tastatur. Das war einfach machbar, weil es zwei PS/2-Kabel gab: einen für die Tastatur und einen für die Maus. Ich musste die Tastatur nur an der richtigen Stelle durchsägen, damit ich kompakt den Tastaturteil übrig behielt.

Die rechte Seite des Touchpads und Tastaturgehäuses habe ich dann auch abgesägt und rechts an die Tastatur wieder dran geklebt. Sieht jetzt so aus, als ob es schon immer so gehört hätte.

Das Touchpad-Modul (sogar ein gutes von Synaptics) war auch PS/2 und ekelhafterweise in Plastik eingegossen. Ich konnte es jetzt aber befreien und an die PS/2-Clock und PS/2-Data-Signalleitungen, sowie an GND und VCC die entsprechenden Kabel für ein PS/2 Kabel anlöten. Die Maustasten-Platine kam raus, so dass nur noch das nackte Modul übrig blieb. Die Maustasten hatte ich ja schon als komfortable Tastatur-Tasten direkt über dem Platz, in den das Touchpad im HID-Master kommen sollte. Mit einem Cutter-Messer habe ich die Plasdtikfolie auf dem Touchpad auf dessen Minimalmaße zurechtgestutzt.

Heraus kam ein relativ flaches Touchpad-Modul mit angelötetem PS/2-Kabel, das gerade so bzw. optimal in die Fläche neben dem JogDial passen würde.

Nachdem ich meine OpenSCAD-Designs angepasst hatte und den Platz für das Touchpad vorgesehen hatte wurde die Touchpad-Unterseite erstmal mit Klebeband isoliert, denn es würde auf dem Pico aufliegen. Voller Spannung wartete ich auf den 3D-Druck, um zu schauen, ob alles passen würde. Und es passte auf Anhieb. Zwischen Pico und Touchpad-Modul war sogar noch ein Millimeter Platz, der durch Schaumstoff aufgefüllt wurde.



Passt genau. Und das Touchpad sieht danach aus, als ob es genau für diesen Zweck gemacht wäre und von Anfang an in die Design-Überlegungen mit enibezogen worden wäre. Wurde es aber nicht. Da habe ich mit den Maßen Glück gehabt. So kommt das Uralt-Touchpad zu neuen Ehren und wird doch wieder täglich benutzt.

Jetzt überlege ich noch, ob ich die Tastatur-Zeile "LRMA" mit der Zeile "CVXF" austausche, damit ich die Maustasten besser blind erreichen kann. Das wäre schnell getan: Nur die Tastenkappen austauschen und ein paar KeyCode-Zahlen in der Software ändern. Aber da muss ich erst einmal schauen, ob mich das wirklich stört, die Mausreihen in der "zweiten Reihe" zu haben. Meistens werde ich eh das Touchpad selbst für einen Klick benutzen.

Nachdem ich mich zuerst unnötigerweise nach einem Touchpad auf amazon und AliExpress umgeschaut hatte, obwohl ich ja etwas passendes schon daheim hatte, schaute ich jetzt nach einem PS/2-USB Adapter, nachdem meine PS/2 -> seriell D-Sub 9 -> USB - Adapter-Kaskade nicht funktionierte. Wieder unnötigerweise. Denn mein schon etwas betagter PC hat doch wirklich noch PS/2-Eingänge für Maus und Tastatur.

Also das Touchpad-PS/2-Kabel direkt in den PC gesteckt und: funktioniert. Wunderbar. Jetzt lässt der HID-Master wirklich keinen Wunsch mehr offen.

Nachtrag 2023-12-21

Der HID-Master ist bei mir täglich im Einsatz und ich habe zwei nervige Dinge dabei festgestellt:

1. Nach dem Schlafen-Legen des PCs (Ruhezustand, Suspend Modes Suspend to Disk, aber auch Suspend to RAM) und dem Wiederaufwecken von Windows funktionieren manchmal die Tasten nicht mehr. Da hilft nur, auf den Eintrag "HID-Tastatur" im Geräte-Manager rechts zu klicken und "deinstallieren" zu wählen. Nach einem Klick auf "nach neuer Hardware suchen" wird die HID-Tastatur kurzerhand von Windows neu installiert und es funktioniert alles wieder reibungslos.
Vielleicht liegt das auch an der Vielzahl von USB-Geräten an meinem PC und das mehrere Tastaturen am PC hängen. Die "HID-konforme Mouse", der "HID-konforme Gamecontroller" und das "HID-konforme Benutzersteuergerät" machen allerdings nie Probleme. Und es hängen ja auch mehrere Mäuse am PC. Seltsame Erscheinung, für die ich noch keine permanente Lösung gefunden habe.

2. Der HID-Master macht hin und wieder mal einen Ghost-Reset. Das heißt, er resettet einfach, ohne dass ich auf Reset-Knopf gedrückt hätte, was in diesem Fall der Klick des Drehgebers ist, also das herunterdrücken des Jog-Dials. Komischerweise tritt der Ghost-Reset eigentlich nur dann auf, wenn ich aufstehe und den Schreibtisch verlasse. Wenn ich still dasitze, passiert nichts. Das ist schon ziemlich seltsam.
Die naheliegenste Ursache dafür ist für mich ein "floating Pin", also ein Pin, dessen Zustand nicht sicher High oder Low ist. Und das natürlich bei dem Reset-Taster. Wird der gedrückt, wird während des Drückens der RUN-Pin vom Raspberry Pi Pico auf Low gezogen, was den Pico neu startet. Eigentlich sollte der RUN-Pin, so das Datenblatt, über einen 50 KΩ-Pullup-Widerstand auf High gezogen sein. Aber das reicht vielleicht nicht aus, oder wer weiß, der Widerstand fehlt bei mir. Auf jeden Fall habe ich nun noch einen Widerstand mit 10 KΩ parallel gelötet, also zwischen RUN und +3.3V. Damit sollte der gesamte Pullup-Widerstand jetzt bei 8.33 KΩ liegen, wenn der interne 50 KΩ vorhanden ist, ansonsten halt bei 10 KΩ. Das sollte sicherer sein gegen Floating-Effekte und in jedem Fall ist jetzt ein Pullup-Resistor vorhanden.
Bleibt zu beobachten, ob das hilft und die Geister-Resets ausbleiben. Vielleicht liegt es ja auch woanders dran. Die Zeit wird zeigen, ob die sporadisch auftretenden Ghost-Resets nun gänzlich ausbleiben.