Die Computatur

Es ist keine Tastatur, auch wenn man eine daran anschliessen kann und für die Verwendung die ich hier Beschreibe auch sollte.

Aber worum geht es jetzt eigentlich genau? Ich möchte hier den Arduino Leonardo vorstellen.
Er ist schon eine Weile keine Neuheit mehr (Release war 2011 oder 2012), kann aber etwas, was in meinen Augen gerade unter Administratoren, mehr Beachtung finden sollte.
Wie der Begriff „Arduino“ schon verrät, handelt es sich beim Leonardo um ein Circuit Board aus der Arduino Produktlinie.
Das Board ist für 20-22 € in gut sortierten Elektro-Bastelläden (z.B. EXP TECH) zu haben.
Arduino Boards kommen ohne Zubehör, bei einem Leonardo sollte man ein datenfähiges USB zu Micro USB Kabel vorrätig haben oder gleichzeitig besorgen.
Der Leonardo ist mit einer CPU (ATmega32u4) ausgestattet, die es ermöglicht das Board als USB Tastatur, USB Maus oder beides gleichzeitig zu verwenden.
Aber was soll das bringen?
Die meisten Leute denken, sobald man sagt oder schreibt… „Arduino Leonardo und Due können USB Tastatursignale imitieren“ … das so etwas die Tastatur ersetzen soll, aber es geht eher darum die Tastatur über ihre natürlich gesetzten Grenzen hinaus zu erweitern. So kann man bei so gut wie keiner Tastatur Phrasen oder Tastenkombination hinterlegen so das diese nach einem Stromverlust noch vorhanden wären. Ich kenne auch keine Tastatur, die über das Internet angesteuert werden könnte.
Der Leonardo ist ausserdem mit mehreren Digitalen und Analogen, Ein- und Ausgängen ausgestattet.
Arduinos lassen sich über ein spezielles Programm von OS X, Linux oder Windows aus mit selbst erstellten Prgrammen bespielen. Dieses „spezielle“ Programm ist Editor,Interpreter,Compiler,Flasher und serieller Terminal in ein Java Programm zusammengefasst.
Die verwendete Programmiersprache (ich weiss gerade nicht ob sie einen eigenen Namen hat) ähnelt Processing und arbeitet auch sehr gut damit zusammen. Arduino Programme, genannt „Sketche„, sind in der Regel als Loop aufgebaut. Die Funktion loop läuft, solange dem Board genügend Strom zur verfügung gestellt wird.
Ich verwende z.Z. einen Leonardo, um in der Arbeit ständig wiederkehrende teils lange Befehlszeilen, die sich wegen der Verteilung der System auf denen ich sie benötige nicht anders scripenten lassen, ein zu geben.
Eigentlich ist dieser Artikel hier zu ende…
Es folgt noch mein aktuelles Setup und ein paar Ideen die ich noch ausprobieren will:
Wie ich vorhin schon geschrieben habe, verwende ich mein Setup um wiederkehrende Befehle durch den Leonardo eingeben zu lassen. Damit das funktioniert sollte man ein paar Tasten mit dem Leonardo verbinden. Es gibt einige Anleitungen wie man Taster über einen Arduino ausliest. Ich hab’s mir ein wenig leichter gemacht und ein 16 Tasten Feld (Trellis von Adafruit) besorgt. Dieses Tastenfeld wird via I²C angesteuert und man kann insgesamt 8 Trellisboards über eine Verbindung adressieren. Es gibt auch noch andere interessante Tastenfelder auch von anderen Herstellern. Ich bin mit dem Trellis wie den meisten Sachen von Adafruit aber bisher recht zufrieden.
Mein Sketch ist recht einfach gestrickt:
Beleuchte die Tasten die ich Benutze, bis ich sie drücke und übergebe den hinterlegten Befehl an den angeschlossenen Rechner sobald ich die Taste wieder los lasse.

Mein altes WP-Theme hat u.a. den Sourcecode zerhackt…
Also muss ich das jetz anders machen:

#include <Wire.h>
#include "Adafruit_Trellis.h"

Adafruit_Trellis matrix0 = Adafruit_Trellis();

Adafruit_TrellisSet trellis =  Adafruit_TrellisSet(&matrix0);

#define numKeys 16

#define INTPIN A2

void setup() {
  Keyboard.begin();
  pinMode(INTPIN, INPUT);
  digitalWrite(INTPIN, HIGH);
  
  trellis.begin(0x70);
  // light up all the LEDs in order
  for (uint8_t i=0; i<numKeys; i++) {
    trellis.setLED(i);
    trellis.writeDisplay();    
    delay(50);
  }
  // then turn them off
  for (uint8_t i=0; i<numKeys; i++) {
    trellis.clrLED(i);
    trellis.writeDisplay();    
    delay(50);
  }
  trellis.setLED(0);
  trellis.setLED(1);
  trellis.setLED(2);
  trellis.setLED(3);
  trellis.setLED(8);
  trellis.setLED(9);
  trellis.setLED(11);
  trellis.writeDisplay();
}

void loop() {
  delay(30);
  
  if (trellis.readSwitches()) {
    if (trellis.isKeyPressed(0)) {
      Keyboard.println("telnet 10.11.12.13 9997");
    }
    if (trellis.isKeyPressed(1)) {
      Keyboard.press(0x80);
      Keyboard.press(0x5D);
      delay(250);
      Keyboard.releaseAll();
      Keyboard.write(0xB0);
      delay(50);
      Keyboard.println("q");
      Keyboard.write(0xB0);
    }
    if (trellis.isKeyPressed(2)) {
      Keyboard.press(0x80);
      Keyboard.press(0x63);
      delay(50);
      Keyboard.releaseAll();
    }
    if (trellis.isKeyPressed(3)) {
      Keyboard.println("pwd");
      Keyboard.println("ls -la");
    }
    if (trellis.isKeyPressed(8)) {
      Keyboard.write(0x83);
      Keyboard.println("mstsc");
    }
    if (trellis.isKeyPressed(9)) {
      Keyboard.print("UserName");
      Keyboard.write(0x09);
      Keyboard.println("Pa55w0rd");
    }
    if (trellis.isKeyPressed(11)) {
      Keyboard.press(0x80);
      Keyboard.press(0x64);
      delay(50);
      Keyboard.releaseAll();
    }
  }
}

Dieser Code ist jetzt erstmal so wie ich ihn gerade in der Arbeit brauche. Und dient dazu, auf Rechnern, auf denen ich mich via ssh oder remotedesktop verbunden habe, die Datenverbindung zu einem Splunk Server und die Verzeichnisstruktur zu prüfen.
Taste 0 (erste Reihe, Links aussen) startet den Telnet Befehl.
Taste 1 „drückt“ ctrl+] für 250ms und schickt noch ein return und ein „q“ hinterher um eine aufgebaute Telnet verbindung zu beenden
Taste 2 sendet einen abbruch mit ctrl+c
Taste 3 sendet ein „pwd“ um zu erkennen, ob der Benutzer mit dem richtigen Home-Pfad angelegt wurde und ein „ls -la“ um überprüfen zu können, ob die richtigen Verzeichnissrechte gesetzt sind.
Taste 8 öffnet mir an einem Windowsrechner das Programm „Remotedesktopverbindung“
Taste 9 gibt Benutzername und Passwort für mich ein.
Taste 11 sendet ein ctrl+d um die Verbindung zu beenden zum Remoterechner zu beenden

Und so sieht es dann bei mir in „Natura“ aus
IMG_0889

Das die Tastatur erst beim release ausführen soll hab ich so programmiert, weil man dafür dann keine Routine braucht, die dafür sorgt, das es nur einmal ausgeführt wird. Macht man es anders rum und schreibt keine Routine, wird die der Befehl alle 30ms ausgeführt, solange man die Taste gedrückt hält. Administratoren sind faul 😉

Zwei Ideen die ich noch ausprobieren will:
1. Nicht einzelne Tasten zu belegen, sondern das ganze über eine Binär Codierung zu machen die durch die letzte Taste auf dem Tastenfeld dann aktiviert wird. Kleiner Nachteil beim Leonardo: er hat bloss 32kb von denen bereits 4 für den bootloader „verbraucht“ sind und auch noch einig für die Routinen verwendet werden. Das schränkt die Möglichkeiten ggf ein wenig ein.
Done

/****************************************************************
  Written by Dirk Mader aka SierraX
  
  Designed specifically to work with the Adafruit Trellis 
  ----> https://www.adafruit.com/products/1616
  ----> https://www.adafruit.com/products/1611
  and Arduino Leonardo
  ----> http://arduino.cc/en/Main/ArduinoBoardLeonardo
  
  to create a Keyboard output based on a bitcode.
  The first 2 lines are 1 Byte beginning from the lower right
  The last key [15] on trellis is a kind of "Enter"
 ****************************************************************/

//Driver for Trellis
#include <Wire.h>
#include "Adafruit_Trellis.h"

//initial Trellis configuration
Adafruit_Trellis matrix0 = Adafruit_Trellis();
Adafruit_TrellisSet trellis =  Adafruit_TrellisSet(&matrix0);
#define numKeys 16
#define INTPIN A2

void setup() {
  //Setup USB Keyboard function
  Keyboard.begin();
  // INT pin requires a pullup
  pinMode(INTPIN, INPUT);
  digitalWrite(INTPIN, HIGH);
  //begin() for on Trellis
  trellis.begin(0x70);
  // the last setup Part is not necessary. But showes the LEDs of Trellis are working
  // light up all the LEDs in order
  for (uint8_t i=0; i<numKeys; i++) {
    trellis.setLED(i);
    trellis.writeDisplay();    
    delay(50);
  }
  // then turn them off
  for (uint8_t i=0; i<numKeys; i++) {
    trellis.clrLED(i);
    trellis.writeDisplay();    
    delay(50);
  }
}

void loop() {
  delay(30); // Adafruit write "is required". To "reinit" the i2c port expander I think
  int flag=0; // a flag to jump out of the following while loop
  int bits[] = {128,64,32,16,8,4,2,1}; // bit values in byte you know
  int bitcode=0; // lowest result
  // Clear Display for next round
  for (uint8_t i=0;i<8;i++) {
    trellis.clrLED(i);
  }
  trellis.writeDisplay();
  // to type the bitcode in
  while (flag < 1) {
    delay(30); // maybe not necessary, but does not hurt.
    // read the Keys of the first two lines and toggle light
    if (trellis.readSwitches()) {
      for (uint8_t i=0; i<8; i++) {
        if (trellis.justPressed(i)) {
          if (trellis.isLED(i)) {
            trellis.clrLED(i);
          }
          else {
            trellis.setLED(i);
          }
          trellis.writeDisplay();
        }
        // exit this loop
        if (trellis.isKeyPressed(15)) {
          flag++;
        }
      }
    }
  }
  // read LED status and calculate the bitcode
  for (uint8_t i=0;i<8;i++) {
    if (trellis.isLED(i)) {
      bitcode=bitcode+bits[i];
    }
  }
  /* print the bitcode followd by new line.
  but you can do as many if statements as you want (or 255) */
  Keyboard.println(bitcode); 
}

2. Das serielle Verbinden des Leonardo mit einem Raspberry Pi über GPIO und ihn somit Netzwerkfähig bzw. flexibler zu gestalten.
Herausforderungen hierbei: Die unterschiedlichen Betriebsspannungen der Schnittstellen und das schreiben eines Parsers, da das Programm auf dem Board ja zu Maschinensprache kompiliert wird.

Der Fantasie sind hier wenig Grenzen gesetzt.
Weitere Anregungen gerne in die Kommentare.

Dieser Beitrag wurde unter Allgemein veröffentlicht. Setze ein Lesezeichen auf den Permalink.