GeekzeugHardwareSoftware

Projekt Tutobar: Arduino- und Autohotkey-Skripte 2/3 (Software)

Mit gerade mal einem Dutzend verschiedener Code-Zeilen erwacht die Tutobar zum Leben

Der Zusammenbau der Hardware war ein einziger Trial-and-Error-Prozess – Teile flogen gegen Wände, Dinge mussten nachbestellt werden, Details haben sich on-the-fly verändert. Bei der Software sah der Prozess im Grunde genauso aus, allerdings deutlich entspannter. Das Ergebnis: Halbwegs sauberer Code, ziemlich redundant, aber daher verständlich und einfach. Dank eines API-für-Arme-Ansatzes.

Zu Teil 1

Im ersten Teil des Artikels wird die Hardware zusammengebaut – wenn Euch aber nur der Software-Part interessiert, hier die Ausgangssituation: 15 Schalter sind mit dem Arduino Leonardo verbunden, 10 Kippschalter und 5 Druckknöpfe – jeweils irgendwo an Minus und einem GPIO-Pin angeschlossen. Und so sieht es aus:

tutobar arduino-projekt
Vom Schalter zum Steckbrett zum Arduino – mehr ist es nicht.

Für Arduino-Einsteiger nochmal der Hinweis auf unseren Einführungsartikel, wo Ihr auch seht, wie man mit so einem Ding überhaupt interagiert. Eine Einführung in Autohotkey haben wir hier.

Konzept

Nochmal kurz zur Erinnerung das bereits erwähnte Konzept aus drei Schritten:

  1. Arduino-Sketch: Schalter senden Tastenkürzel an den PC.
  2. Autohotkey-Skript: Interpretiert die Tastenkürzel und triggert Funktionen pro Schalter.
  3. Tutobar-Config: Enthält die finalen Funktionen – für Nachbauer die einzig relevante Datei!

Natürlich ginge das auch mit eleganterem Code oder Tausend anderen Herangehensweisen. Das Schöne an dieser Fast-API: Arduino- und Autohotkey-Skripte müssen nie wieder verändert werden. Jeder Schalter sendet eindeutige Signale und Autohotkey macht daraus eindeutige Hotkeys – jegliche Nutzerkonfiguration findet in der simplen Config-Datei statt, die natürlich wiederum Autohotkey-Code beinhaltet.

Man könnte die Tutobar auch einfach Hardware-Autohotkey-Frontend nennen.

tutobar arduino-projekt
Im Grunde ist es nur ein Autohotkey-Eingabegerät.

Den kompletten hier beschriebenen Code könnt Ihr als ZIP-Datei herunterladen und natürlich nutzen, verändern, weitergeben.

Arduino-Sketch

Das Arduino-Skript ist simpel: Die beiden RBD-Bibliotheken sorgen für eine einfache Ansprache von Druckknöpfen, die Switch-Bibliothek erledigt dasselbe für die Switches und die Keyboard-Bibliothek ermöglicht das Senden von Zeichen. Bibliotheken erreicht Ihr in der IDE über Sketch/Bibliothek einbinden/Bibliotheken verwalten – und zwar viele!

// Bibliotheken laden
#include <avdweb_Switch.h>
#include <RBD_Timer.h>
#include <RBD_Button.h>
#include <Keyboard.h>

Im Deklarationsteil werden nun Pushbuttons und Switches definiert – nach dem üblichen Muster TYP NAME GPIO-PIN. Zusätzlich werden noch die Modifier-Tasten definiert, sprich ALT, UMSCHALT und STEUERUNG:

// Pushbuttons definieren - button1 auf Analog-IO A2
RBD::Button button1(A2);
RBD::Button button2(2);
[...]

// Switches definieren
Switch switch3 = Switch(3); // GPIO 3
Switch switch4 = Switch(4);
[...]

// Modifier definieren
char ctrlKey = KEY_LEFT_CTRL;
char altKey = KEY_LEFT_ALT;
char shiftKey = KEY_LEFT_SHIFT;

Im Setup-Teil passieren zwei Dinge: Die Ausgabe über die Keyboard-Bibliothek wird gestartet und einige Analog-GPIOs werden mit dem internen Pullup-Widerstand verbunden. Der Grund ist simpel: Es gibt nur 12 digitale GPIOs auf dem Arduino Leonardo. Alle dort über Bibliotheken verknüpften Schalter haben standardmäßig ebenfalls den aufgeschalteten Pullup-Widerstand. Um die analogen GPIOs genauso nutzen zu können, muss der Widerstand hier eben noch gesetzt werden.

// Setup
void setup() {

Keyboard.begin();
// Die analogen Anschlüsse werden mit
// dem internen Pullup-Widerstand verbunden.
pinMode(A0, INPUT_PULLUP);
pinMode(A1, INPUT_PULLUP);
pinMode(A2, INPUT_PULLUP);
}

Im Haupt-, also dem loop-Teil werden nun die Aktionen für die Pushbuttons und Switches festgelegt.

Bei Pushbuttons läuft alles über die Methode button1.onPressed, die die RBD-Bibliotheken spendieren – um sonstige Interna muss man sich nicht kümmern. Dazu zählt zum Beispiel das Debouncing: Das Drücken eines Pushbuttons würde ohne diese Softwarekorrektur nicht eine, sondern mehrere „Gedrückt-Aktionen“ melden – die Crux mit Hardware, Physik und Elektronik ;) die delay-Anweisung dient nur dazu, versehentliche menschliche Doppelklicks zu vermeiden.

Superwichtig: Über Keyboard.releaseAll() werden die gedrückten Tasten wieder losgelassen – ohne diese Anweisung würde der Arduino in diesem ersten Beispielfall kontinuierlich STRG+ALT+SHIFT+a senden und das Autohotkey-Skript würde entsprechend laufend die hinterlegte Aktion ausführen. Hier führte ein Fehler in der Zeile beispielsweise dazu, das binnen Sekunden Hunderte Instanzen vom Windows-Taschenrechner (calc.exe) geöffnet wurden. Ein echter Spaß :(

Hier der Code für den ersten Pushbutton, der mit dem analogen GPIO-PIN A0 verbunden ist:

void loop() {

// Alle Pushbuttons mit Kürzeln der Art
// STRG+ALT+UMSCHALT+buchstabe belegen
// Pushbutton 1
if(button1.onPressed()) {
Keyboard.press(ctrlKey);
Keyboard.press(altKey);
Keyboard.press(shiftKey);
Keyboard.press('a');
delay(100);
// Tasten wieder loslassen - sonst spamt
// der Arduino den PC komplett voll ;)
Keyboard.releaseAll();
}
[...]

Übrigens: Natürlich gibt es für Pushbuttons auch ein button1.onReleased(), um eine Aktion beim Loslassen zu triggern – macht hier aber wenig Sinn.

Die Wahl der Tastenkürzel war übrigens rein praktischer Natur: Mit STRG+ALT+UMSCHALT hatte ich hier bislang keine Kürzel und da die 5 Pushbuttons je ein Kürzel und die 10 Switches je zwei Kürzel brauchen – sprich insgesamt 25 -, bot sich das Alphabet an. Eine Nummerierung wie 1, 2, 3a, 3b, 4a, 4b wäre vielleicht hübscher gewesen, aber Autohotkey verträgt zwar mehrere Modifier-Tasten, aber nicht in Kombination mit mehreren Auslösern also etwa „3a“ (gut, „3a“ als Hotkey ginge, dann aber wieder nicht in Kombination mit Modifier-Tasten … mehr dazu im Lessons-Learned-Abgesang).

Bei den Switches läuft es weitgehend genauso, nur dass hier die Switch-Bibliothek die Methoden switch3.pushed() und switch3.released() beisteuert, schließlich sollen hier beide Aktionen/Schalterpositionen etwas auslösen. Die Bibliothek verlangt zudem, dass die Zustände der Switches kontinuierlich abgefragt (ge-poll-t) werden, daher das switch3.poll() vor der if-Abfrage.

Hier der code für den ersten Switch, der mit dem digitalen GPIO-PIN 3 verbunden ist:

// Alle Switches mit Kürzeln der Art
// STRG+ALT+UMSCHALT+buchstabe belegen
// Switch 3
switch3.poll();
if(switch3.pushed()) {
Keyboard.press(ctrlKey);
Keyboard.press(altKey);
Keyboard.press(shiftKey);
Keyboard.press('c');
delay(100);
Keyboard.releaseAll();
}
if(switch3.released()) {
Keyboard.press(ctrlKey);
Keyboard.press(altKey);
Keyboard.press(shiftKey);
Keyboard.press('d');
delay(100);
Keyboard.releaseAll();
}
[...]

Autohotkey-Skript

Auch bei Autohotkey ist das Resultat ziemlich simpel geraten – nach einigen Irrwegen … Das #include settings.conf liest schlicht die Konfigurationsdatei ein, die gleich folgen wird.

Danach folgt das übliche Autohotkey-Prozedere: Definition des Tastenkürzels, hier STRG+ALT+UMSCHALT, Aufruf einer Funktion, zum Beispiel namens schalter_1_on(), Abschluss mit return. An dieser Stelle wichtig: In Autohotkey steht ! für die Alt-Taste – das würde aber (aus komplizierten Autohotkey-internen Gründen) dazu führen, dass weitere virtuelle Tastenanschläge registriert würden. Daher definiert <! nicht bloß eine Alt-Taste, sondern die linke Alt-Taste. ^ steht für STRG und + für UMSCHALT. Pushbuttons bekommen nur die eine Funktion für das Drücken, Switches bekommen zwei Funktionen für Ein- und Ausschalten.

Hier mal die ersten drei Schalter meiner Tutobar im Skript tutobar_api.ahk, also die Pushbuttons an den Stellen 1 und 2 sowie der Kippschalter an Stelle 3:

#include settings.conf

; Definition der Schalter
^<!+a::
schalter_1_on()
return

^<!+b::
schalter_2_on()
return

^<!+c::
schalter_3_on()
return
^<!+d::
schalter_3_off()
return

Status bis jetzt: Schalter 1 wird umgelegt, Arduino-Sketch sendet STRG+ALT+UMSCHALT+a an den PC, Autohotkey erkennt das Kürzel und startet die Funktion schalter_1_on().

Autohotkey-Konfiguration

Also folgt nun die Definition dieser Funktion in der Datei settings.conf: Ein popeliges run, calc.exe startet den Taschenrechner. Etwas aufwändiger ist es bei den Switches, da diese das Programm auch wieder ausschalten sollen. Dafür gibt es viele Möglichkeiten, die wohl einfachste: if WinExist(„Rechner“) prüft, ob ein Fenster mit dem Titel „Rechner“ geöffnet ist – falls ja, wird es von WinClose geschlossen.

schalter_1_on()
{
run, calc.exe
return
}

schalter_2_on()
{
run, calc.exe
return
}

schalter_3_on()
{
run, calc.exe
return
}
schalter_3_off()
{
if WinExist("Rechner")
WinClose ;
return
}
[...]

Der Code wird jetzt einfach für alle 25 Schaltmöglichkeiten wiederholt.

Mehr Funktionen und Gimmicks

Bislang machen alle meine Schalter dasselbe: Auf ON starten sie calc.exe und auf OFF schließen die Switches das Programm auch wieder. Aber hier lässt sich natürlich alles Mögliche hinterlegen.

Wirklich interessant wird es, wenn die Schalttafel abhängig vom im Vordergrund laufenden Programm unterschiedliche Funktionen bereit hält. Ein Artikel dazu folgt irgendwann wenn ich mit der Konfiguration mal glücklich und zufrieden bin. Grundsätzlich wird es aber auf eine case-Abfrage hinauslaufen, nach dem Motto: WENN Gimp im Vordergrund läuft, inkludiere gimp_funktionen, WENN torchlight im Vordergrund läuft inkludiere torchlight_funktionen und so weiter. Gerade für Spiele könnte das interessant sein – wie wäre es mit in der Armlehne vom Bürostuhl eingebauten ASDF-Tasten? Der Bequemlichkeit halber …

Die Tutobar in Aktion.

Natürlich wäre es hübsch, auch noch eine Beschriftung zu haben, eine Anzeige, welche Funktionsliste aktuell aktiv ist, weitere Regler, um zum Beispiel Lampen dimmen oder die Lautstärke regulieren zu können und so weiter. Aber dann wäre es irgendwann keine Tutobar mehr, sondern eher ein (rieeeeeesiges) Tuto-Cockpit. Bei mir wird es einfach eine wiederbeschreibbare Metallleiste werden, die ich mit Magneten bündig zur Aluschiene anpappen werde.

Direkt nachbauen wird die Tutobar vermutlich niemand, aber wenn Ihr eine Schalttafel in ähnlicher Manier bauen wollt, könnt Ihr zumindest große Teile des Codes weiterverwenden – sofern Ihr mit Autohotkey arbeiten mögt sogar alles bis auf die Einträge in der Config-Datei.

Ich für meinen Teil hatte durchaus Spaß beim Basteln – aber nicht nur, wie Ihr im letzten Teil sehen werdet.

Mirco Lang

Freier Journalist, Exil-Sauerländer, (ziemlich alter) Skateboarder, Dipl.-Inf.-Wirt, Einzelhandelskaufmann, Open-Source-Nerd, Checkmk-Handbuchschreiber. Ex-Saturn'ler, Ex-Data-Becker'ler, Ex-BSI'ler. Computer-Erstkontakt: ca. 1982 - der C64 des großen Bruders eines Freunds. Wenn Ihr hier mehr über Open Source, Linux und Bastelkram lesen und Tutonaut unterstützen möchtet: Über Kaffeesponsoring via Paypal.freue ich mich immer. Schon mal im Voraus: Danke! Nicht verpassen: cli.help und VoltAmpereWatt.de. Neu: Mastodon

Ein Kommentar

  1. Hallo Mirco,
    nun könnte man doch für Vi Einsteiger als Hilfe, eine Vi-Editor Custom Tastatur/Keypad basteln,
    die Ihre Tasten völlig anders (frei) zueinander platziert hat,
    die in Bereiche der Vi Commandos unterteilt ist… Bildschirm, Zeile, Suche, etc…
    dann ihre Eingaben zuerst an Arduino schickt..
    und vom Arduino werden diese Eingaben für den Ziel PC in die richtigen Vi-Eingaben umgewandelt und gesendet.
    Leonardo kann ja als nativ Keyboard am PC agieren..
    aber
    wenn man ein 2. Keyboard nutzen( mit farblichen Tasten etc) will
    wie bekommen wir die vielen Keyboard Eingaben an Arduino gesendet,
    anstelle einer Benutzung einer wilden unendlichen Menge von Buttons..(adressierung wäre dann wichtig)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

Schaltfläche "Zurück zum Anfang"
Schließen

Ooopsi!

Bitte deaktiviere Deinen Adblocker.