Screen als Serial-Terminal

Manche Dinge sind so einfach, dass man keine Ahnung hat, wie einfach sie sein können. Vorhin bin ich über eine tolle kleine Unix-Anwendung gestolpert, die einem die Nutzung von Arduino massiv vereinfachen kann: "screen"

Bisher habe ich jedes Mal, wenn ich mit meinem Arduino kommunizieren wollte, die Arduino-IDE geöffnet und dort den Serial-Terminal verwendet. Das ist zum einen umständlich und zum anderen werden Nutzer später wahrscheinlich nicht unbedingt die Arduino-IDE bei sich installiert haben.

Screen aufrufen

Screen aufrufen

Klar gibt es Tools, die man sich irgendwo herunterladen kann (unter Windows ist zum Beispiel PuTTY eine häufige Wahl), aber ich habe es gern, wenn ich auch Onboard-Lösungen kenne. Und "screen" auf unixoiden System ist genau das. Um zu wissen, mit welchen Geräten man sich überhaupt verbinden kann, sollte man sich erst angucken, welche TTY-Devices es gibt:

1
ls /dev/tty.*

Hier sticht der Arduino als einziges USB-Device deutlich hervor. Der Aufruf von "screen" ist dann ziemlich einfach. Man benötigt den Gerätenamen und dazu (bei mir war es optional) die Baudrate (die Zahl, die man z.B. bei "Serial.begin()" beim Arduino angibt).

1
screen /dev/tty.usbmodem1d11 9600

Anschließend wird einem die serielle Ausgabe als normale Konsolendarstellung bereitgestellt. Bei meinem derzeitigen Arduino-Projekt, das im Moment über einfache serielle Ein- und Ausgaben funktioniert, habe ich dadurch eine Art normale Terminalanwendung - nur, dass die Logik eben auf einer separaten Hardware läuft.

Screen Darstellung

Screen Darstellung

Das einzige, was ich bisher noch nicht herausgefunden habe, ist, wie ich die Verbindung trennen kann, sodass ich sie erneut öffnen kann, ohne vorher den Stecker des Arduinos herausziehen zu müssen. Bisher ist das Gerät da ein bisschen zickig. ^_^
Update:
Ich habe nun endlich des Rätsels Lösung gefunden! Mit der Tastenkombination "Ctrl+A D" kann man ja Screen von der geöffneten seriellen Schnittstelle trennen. So ist zumindest der Plan. Wie ich jedoch feststellen musste, hielt Screen die Verbindung weiterhin geöffnet. Getestet habe ich das mit:

1
lsof /dev/tty.*

Dabei herausgekommen ist folgendes:

1
2
3
WeizenBook:~ kenny$ lsof /dev/tty.*
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
screen  13242 kenny    5u   CHR  18,34     0t52 1285 /dev/tty.usbmodem1d11

Gelöst habe ich das dadurch, indem ich den entsprechenden Prozess einfach abgeschossen habe:

1
kill -9 13242

Und siehe da: Plötzlich klappt auch eine erneute Verbindung mit dem Arduino. Super. Aber doof. Extra händisch den Prozess killen zu müssen. Ob das wirklich so gewollt ist?

Update:
Wie man den hilfreichen Kommentaren von Oliver entnehmen kann, gibt es mehrere Möglichkeiten, die mit "Ctrl+A D" beendete (= "detachte") Session wieder zu bekommen. Die eine Möglichkeit ist, die letzte Session fortzusetzen (= "reattachen"):

1
screen -r

Die andere Möglichkeit ist, sich mit einem Befehl sämtliche verfügbaren Sessions anzeigen zu lassen. Die Sessionnamen sind in der Regel mit Punkten getrennte Bezeichner in der Form "[PID].TTY.[HOSTNAME]":

1
screen -ls

Mit folgendem Befehl kann man sich nun wieder zu dieser Session verbinden:

1
screen -x [SESSIONNAME]

Update:
Ich habe eine interessante Seite gefunden, auf der sämtliche Tastenkombinationen von Screen beschrieben sind. Darunter auch die Kombination "Ctrl+A K", um die Session zu töten (= "killen"). Die werde ich heute Abend mal ausprobieren. 🙂
Serielle Grüße, Kenny

13 Kommentare » Schreibe einen Kommentar

  1. Hallo zusammen,

    weiß jmd wie ich die seriellen daten direkt speichern kann und weshalb ich nicht alle seriellen daten auf dem Bildschirm sehen kann?

    • Screen ist eher für Bildschirmausgaben gedacht. Wenn es darum geht, Binärdaten zu sehen und zu speichern, ist es wahrscheinlich sinnvoller, sie direkt aus dem Device auszulesen und in eine Datei zu speichern - zum Beispiel mit Hilfe eines kleinen Scripts.

  2. Mit Strg+d beendest Du ein Screensitzung. Ich habe das auch auf meinen Linuxservern in der bashrc:

    if [ "$PS1" != "" -a "${STARTED_SCREEN:-x}" = x -a "${SSH_TTY:-x}" != x ]
    then
    STARTED_SCREEN=1 ; export STARTED_SCREEN
    [ -d $HOME/lib/screen-logs ] || mkdir -p $HOME/lib/screen-logs

    sleep 1
    screen -U -RR && exit 0

    echo "Screen failed! continuing with normal bash startup"
    fi

    Sollte aus irgendeinem Grund die Screen-Session unterbrochen werden, z. B. durch einen Reconnect, werde ich beim nächsten Login direkt wieder in die Screensession geworfen und wenn ich mich auslogge, ist die Screensession auch beendet.

    • Mein Problem ist ja nicht, dass ich GAR NICHT aus Screen rauskomme. Ctrl+A D ist bekannt. Mein Problem ist, dass ich danach keinen erneuten Connect zum Arduino Uno hinkriege. Ich kriege dann eine Fehlermeldung, dass die Resource beschäftigt ist und keine Lese-/Schreibanfragen akzeptiert.

      • Vermutlich, weil die Session nicht beendet wird. Mit Strg + a wechselst Du zwischen den Sessions, so es mehrere gibt. Wird denn Screen auf Deinem Rechner beendet?

        • Genau den Gedanken hatte ich auch gerade. Ich hatte geguckt, ob es vielleicht am Arduino Uno lag und habe deshalb jetzt ein Arduino Leonardo ausprobiert. Doch auch dort trat das Fehlerbild auf. Und in der Tat hatte "lsof /dev/tty.*" gezeigt, dass Screen die Datei nicht ordentlich freigegeben hatte und immernoch im Hintergrund lief.

          • Ja, ist doch super! 🙂

            $ screen -ls

            There is a screen on:
            22337.pts-3.oliver-ThinkPad-X201s (25.04.2013 22:39:43) (Attached)
            1 Socket in /var/run/screen/S-oliver.

            $ screen -x 22613.pts-3.oliver-ThinkPad-X201s

            Und Du bist wieder drin. 😉

            • Habe das jetzt mal probiert. Sowohl "screen -r" als auch "screen -x [SCREENNAME]" funktionieren. Man erhält dadurch den Screen wieder. Das Problem ist, dass sich Ctrl+D nichts tut. Das scheint unter Mac OS kein funktionierender Befehl zu sein.

              • Ctrl + d wird wohl für was anderes benutzt. Du kannst exit als Befehl eingeben, dann sollte die Session auch beendet werden.

                • Das wird wohl auf keinen Fall funktionieren. Dazu müsste ich ja auf das Exit im Arduino explizit reagieren und von dort aus die serielle Verbindung kappen. Aber genau das will ich ja nicht. Denn dann kriege ich sie nicht mehr gestartet.

                  • Naja, dann steig mit Ctrl + a d aus und wähl Dich wieder ein, wenn Du es brauchst. Wenn die Verbindung abbricht müsste screen auch beendet werden. 🙂

          • Ach warte, jetzt weiß ich, was Du gemacht hast. Du hast die Session nicht mit Strg + d beendet, sondern Du hast Strg + a gedrückt und dann d. Damit wird die Session nicht beendet, sondern nur in den Hintergrund geschoben - Du musst Strg + d drücken, damit Du screen den Exitbefehl schickst oder alternativ, wenn Du mit Strg + a, d aus der Session gehst, kannst Du mit screen -r zurück. 🙂

Schreibe einen Kommentar

Um Ihnen beim weiteren Kommentieren auf dieser Webseite die erneute Eingabe Ihrer Daten zu ersparen, wird beim Absenden Ihres Kommentars ein Cookie an Ihren Browser gesendet und von diesem gespeichert. Mit dem Absenden eines Kommentars auf dieser Webseite stimmen Sie der Speicherung und Übertragung dieses Cookies explizit zu.

Pflichtfelder sind mit * markiert.