Hallo und willkommen!

WeizenSpr.eu Schön, dass es dich auf diese Seite verschlagen hat. Der Blog hier auf WeizenSpr.eu ist meine eigene kleine Welt. Hier schreibe ich über dies und das - von Alltagssituationen bis hin zu Projekten, die mich momentan beschäftigen.

Ich wünsche dir viel Spaß beim Lesen der einzelnen Artikel. Vielleicht findest du ja ein paar Informationen, die du bisher noch nicht gekannt hast.

07. Mai 2013 ~ 0 Kommentare | ÄHNLICHE ARTIKEL

Arduino und x86: Crosskompilation trotz PROGMEM

Bei meinem derzeitigen Projekt lege ich viel Wert darauf, dass die eigentliche Codebasis nicht nur auf dem Arduino, sondern auch auf normalen PCs mit x86- und x64-Architektur läuft. Bisher war das relativ einfach, da ich - soweit möglich - Plattformspezifika vermeide. Dieses Mal war das jedoch nicht möglich: eine Zwischenschicht musste her.

Was genau ist PROGMEM?

Ein großes Problem der Arduino-Plattform ist ihr begrenzter Hauptspeicher (2kb). Dinge wie längere statische Strings, werden normalerweise als Array definiert. Diese werden beim Starten des Programms in den Hauptspeicher geladen und verbrauchen dort Platz. Um diese unnötige Platzverschwendung zu umgehen, gibt es bei AVR-Plattformen PROGMEM. Statische Variablen, die damit markiert werden, werden nicht in den Haupt-, sondern in den Programmspeicher gepackt und von dort aus gelesen. Der Programmspeicher bietet immerhin satte 32kb Platz. Über spezielle Funktionen kann die Variable dann wieder ausgegeben werden.

Und wo ist jetzt das Problem?

Wie schon angesprochen, möchte ich meinen Code sowohl auf dem Arduino als auch auf dem PC verwenden. Dieser unterstützt PROGMEM jedoch nicht. Wenn wir mal Base64 als Beispiel nehmen: Dort benötigen wir ein Array mit den 64 Zeichen, die für die Codierung verwendet werden. Das sind satte 64 Bytes, die uns vom Hauptspeicher beim Arduino verloren gehen. Auf dem PC macht das natürlich nicht sonderlich viel aus.

Und wie sieht die Lösung aus?

Um die PROGMEM-Funktionalität nutzen zu können, benötigt man sowohl die PROGMEM-Direktive als auch die speziellen Funktionen zum Auslesen des Speichers. Diese stehen auf dem PC natürlich nicht zur Verfügung. Aus diesem Grund habe ich mir einen kleinen Wrapper geschrieben.
Dieser definiert pm_*(x,y) Funktionen, die anstatt der normalen Pgmspace-Funktionen verwendet werden sollen. Zudem werden die für PROGMEM verwendeten Datentypen definiert. Wenn man nun folgenden Code in eine Headerdatei packt, diese neue Headerdatei anstelle von "<avr/pgmspace.h>" inkludiert und die pm_*(x,y) Funktionen nutzt, dann funktioniert der Code plattformübergreifend.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef __PROGMEMUINO_H__
#define __PROGMEMUINO_H__

#ifdef  __cplusplus
extern "C" {
#endif

#include <stdint.h>

#ifdef ARDUINO

#include <avr/pgmspace.h>

#define pm_byte(x,y)  ((uint8_t)pgm_read_byte_near(x+y))
#define pm_word(x,y)  ((uint16_t)pgm_read_word_near(x+y))
#define pm_dword(x,y) ((uint32_t)pgm_read_dword_near(x+y))
#define pm_float(x,y) ((float)pgm_read_float_near(x+y))

#else

#define PROGMEM /**/

#define prog_char     int8_t
#define prog_uchar    uint8_t
#define prog_int16_t  int16_t
#define prog_uint16_t uint16_t
#define prog_int32_t  int32_t
#define prog_uint32_t uint32_t

#define pm_byte(x,y)  ((uint8_t)x[y])
#define pm_word(x,y)  ((uint16_t)x[y])
#define pm_dword(x,y) ((uint32_t)x[y])
#define pm_float(x,y) ((float)x[y])

#endif

#ifdef  __cplusplus
}
#endif

#endif  /* __PROGMEMUINO_H__ */

Wie sieht das in der Praxis aus?

Ich nehme hier mal ein relativ einfaches Beispiel zur Hand. Hier wird ein String per PROGMEM definiert, anschließend zeichenweise ausgelesen und ausgegeben. Ein einfacheres Beispiel ist mir nicht eingefallen. :D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// contains the PROGMEM wrapper
#include "progmemuino.h"

// needed for "while (true)" loop
#include <stdbool.h>

#ifndef ARDUINO
// needed for printf()
#include <stdio.h>
// needed for sleep()
#include <unistd.h>
#endif

const uint8_t myLength = 17;
PROGMEM prog_uchar myString[] = "Das ist ein Test.";

void setup() {
#ifdef ARDUINO
    Serial.begin(9600);
    while (!Serial) {
    } // for Leonardo
#endif
}

void loop() {
    uint8_t index;

    for (index = 0; index < myLength; index++) {
#ifdef ARDUINO
        Serial.print((char) pm_byte(myString, index));
#else
        printf("%c", pm_byte(myString, index));
#endif
    }

#ifdef ARDUINO
    Serial.println("");
    delay(1000);
#else
    printf("%s", "\n");
    sleep(1);
#endif
}

// emulates the Arduino loop
#ifndef ARDUINO
int main() {
    setup();
    do {
        loop();
    } while (true);

    return 0;
}
#endif

Ich hoffe, dieser kleine Trick hilft dem ein oder anderen bei der Wiederverwendung seiner Codebasis. Für Fragen, Anregungen und Verbesserungen stehe ich natürlich wie immer zur Verfügung. :)

Speichersparende Grüße, Kenny


02. Mai 2013 ~ 0 Kommentare | ÄHNLICHE ARTIKEL

Arduino: Tastatureingaben durchleiten in 100 Zeilen

Und weiter geht's in der Erstellung meines Arduino-Projektes. Nachdem ich beim letzten Mal gezeigt hatte, welche Problem das Arduino-Board beim Ausgeben von Tastaturinformationen hat und nachdem ich dafür eine potentielle Lösung implementiert hatte, wollte ich euch mal zeigen, was man damit zum Beispiel machen kann.

Als Grundlage verwende ich hierfür ein Arduino Leonardo und ein USB-Host-Shield der Firma Circuits@Home (z.B. bei Lipoly.de erhältlich). Es gibt auch noch eine Variante von Sparkfun - diese hat jedoch wohl mit einigen Problemen zu kämpfen und wird aus diesem Grund nicht empfohlen.
Für dieses USB-Host-Shield, das einfach auf das Arduino-Board aufgesteckt werden kann, gibt es eine Bibliothek, die man benutzen sollte, da sie einem sehr viel Arbeit abnimmt. Diese Bibliothek wird ebenfalls von Circuits@Home entwickelt - ein weiterer Grund, das Originalshield von ihnen zu verwenden. :)

Mit Hilfe dieser Bibliothek und der Tastaturausgabe-Lösung, die ich am Anfang des Artikels verlinkt habe, ist es möglich, in 100 Codezeilen Tastatureingaben über das USB-Host-Shield einzulesen und über die Tastaturfunktion des Arduino-Boards wieder auszugeben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <hidboot.h>

class KbdRptParser : public KeyboardReportParser {
    private:
        void handleModifiers(uint8_t mod);
    protected:
        virtual void OnKeyDown(uint8_t mod, uint8_t key);
        virtual void OnKeyUp(uint8_t mod, uint8_t key);
        virtual void OnKeyPressed(uint8_t key);
};

void KbdRptParser::handleModifiers(uint8_t mod) {
    MODIFIERKEYS modifier;
    *((uint8_t*)&modifier) = mod;

    if (modifier.bmLeftCtrl == 1) {
        Keyboard.pressKeycode(KEYCODE_LEFT_CTRL, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_LEFT_CTRL, false);
    }
    if (modifier.bmLeftShift == 1) {
        Keyboard.pressKeycode(KEYCODE_LEFT_SHIFT, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_LEFT_SHIFT, false);
    }
    if (modifier.bmLeftAlt == 1) {
        Keyboard.pressKeycode(KEYCODE_LEFT_ALT, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_LEFT_ALT, false);
    }
    if (modifier.bmLeftGUI == 1) {
        Keyboard.pressKeycode(KEYCODE_LEFT_GUI, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_LEFT_GUI, false);
    }
   
    if (modifier.bmRightCtrl == 1) {
        Keyboard.pressKeycode(KEYCODE_RIGHT_CTRL, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_RIGHT_CTRL, false);
    }
    if (modifier.bmRightShift == 1) {
        Keyboard.pressKeycode(KEYCODE_RIGHT_SHIFT, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_RIGHT_SHIFT, false);
    }
    if (modifier.bmRightAlt == 1) {
        Keyboard.pressKeycode(KEYCODE_RIGHT_ALT, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_RIGHT_ALT, false);
    }
    if (modifier.bmRightGUI == 1) {
        Keyboard.pressKeycode(KEYCODE_RIGHT_GUI, false);
    } else {
        Keyboard.releaseKeycode(KEYCODE_RIGHT_GUI, false);
    }
}

void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) {
    if (digitalRead(2) == LOW) {
        handleModifiers(mod);
        Keyboard.pressKeycode(key, true);
    }
}

void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key)   
{
    if (digitalRead(2) == LOW) {
        handleModifiers(mod);
        Keyboard.releaseKeycode(key, true);
    }  
}

void KbdRptParser::OnKeyPressed(uint8_t key)   
{
    // do nothing
};

USB                            HidUsb;
HIDBoot<HID_PROTOCOL_KEYBOARD> HidKeyboard(&HidUsb);
KbdRptParser                   HidKeyboardParser;

void setup() {
    if (HidUsb.Init() != -1) {
        // activate Arduino Leonardo HID keyboard driver
        Keyboard.begin();

        // enable security pin
        // will only work when
        // PIN 2 is connected to ground
        pinMode(2, INPUT);
        digitalWrite(2, HIGH);

        HidKeyboard.SetReportParser(0, (HIDReportParser*)&HidKeyboardParser);
    }
}

void loop() {
    HidUsb.Task();
}

Beachtet, dass Pin 2 mit Ground verbunden sein muss, damit das ganze funktioniert. Warum ich das so gemacht habe, könnt ihr bei den Informationen zur Maus- und Tastatur-API nachlesen:

A word of caution on using the Mouse and Keyboard libraries: if the Mouse or Keyboard library is constantly running, it will be difficult to program your board. Functions such as Mouse.move() and Keyboard.print() will move your cursor or send keystrokes to a connected computer and should only be called when you are ready to handle them. It is recommended to use a control system to turn this functionality on, like a physical switch or only responding to specific input you can control.

Aber wofür ist das ganze nun gut?

Im ersten Schritt zeigt es, wie einfach es sein kann, Tastatureingaben auszulesen und Tastatureingaben zu tätigen. Wie schon gesagt: Die verfügbaren Libraries nehmen einem hierbei viel Arbeit ab. Zudem ist es ein toller Ausgangspunkt, um weiterführende Dinge zu implementieren. Man könnte statt einer normalen Tastatur zum Beispiel einen Nummernblock nehmen und das Arduino zum Taschenrechnung umfunktionieren, der beim drücken der Enter-Taste das berechnete Ergebnis an den Computer überträgt. Oder ihr seid so fies wie Darran aus Neuseeland und bastelt einen Aprilscherz, der nach einem zufälligen Muster die Tasten vertauscht. :)

Tastaturgesteuerte Grüße, Kenny


29. April 2013 ~ 2 Kommentare | ÄHNLICHE ARTIKEL

Arduino Leonardo und das Keyboard-API-Problem

Nachdem ich letztens die erste Revision meines Hardwareprojektes fertiggestellt habe, habe ich nun damit begonnen, die eigentliche Ein- und Ausgabe zu entwickeln. In meinem Fall soll das Arduino als eine Art Tastatur dienen. Mit dem Arduino Uno war das leider nicht möglich...

...glücklicherweise gibt es seit letztem Jahr das Arduino Leonardo, das eine eigene Keyboard-API mitbringt. Damit kann es normale Tastenanschläge an den Computer senden - wie eine richtige Tastatur. Das ganze hat jedoch einen Haken: Tastaturen sind komplizierter als man denkt.

Die Zeichen, die man normalerweise auf dem Computer sieht, werden als sogenante ASCII-Codes dargestellt. Tastaturen, wie man sie alltäglich verwendet, kennen jedoch kein ASCII. Sie verwenden sogenannte Keycodes, die erstmal in ASCII-Codes umkodiert werden müssen. Welcher Keycode nun genau welches Zeichen darstellt, das definieren die so genannten Universal Serial Bus Human Interface Device Usage Tables (kurz: "HUT") in Kapitel 10. Dort findet man die "Keyboard/Keypad Page" des USB-Standards. Die dort beschriebene Zuordnung gilt jedoch nur für amerikanische Tastaturen. Hierzu gibt es im Dokument sogar einen entsprechenden Hinweis:

A general note on Usages and languages: Due to the variation of keyboards from language to language, it is not feasible to specify exact key mappings for every language. Where this list is not specific for a key function in a language, the closest equivalent key position should be used, so that a keyboard may be modified for a different language by simply printing different keycaps. One example is the Y key on a North American keyboard. In Germany this is typically Z. Rather than changing the keyboard firmware to put the Z Usage into that place in the descriptor list, the vendor should use the Y Usage on both the North American and German keyboards. This continues to be the existing practice in the industry, in order to minimize the number of changes to the electronics to accommodate other languages.

Hier nun das Problem des Arduino Leonardo: Dem Arduino kann man nicht den Keycode mitgeben, das er an den PC senden soll. Dieser könnte anhand der Spracheinstellung des Betriebssystems herausfinden, welches Zeichen auf der Tastatur gedrückt worden ist. Stattdessen muss man dem Arduino ein ASCII-Zeichen übergeben und er wandelt es dann in den entsprechenden Keycode um. Dummerweise sind auf deutschen und englischen Tastaturen zum Beispiel die Buchstaben Y und Z vertauscht. Der Arduino selbst geht aber IMMER davon aus, dass man ein englisches System verwendet. Wenn man nun dem Arduino sagt, er soll ein Y an den PC schicken, wandelt er dies in den Keycode für das amerikanische Y um und schickt es an den PC. Wenn der nun auf Deutsch gestellt ist, denkt er, dass ein Z geschickt worden ist. Hier mal ein Beispiel dazu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void setup() {
  Keyboard.begin();
 
  pinMode(2, INPUT);
  digitalWrite(2, HIGH);
}

void loop() {
  while (digitalRead(2) == HIGH) {
    delay(500);
  }
  delay(1000);
 
  // prints "qwerty" on German OS
  Keyboard.print("qwertz");
}

Das ist nicht nur sehr schwer zu verstehen, sondern auch noch sehr umständlich. Denn es gibt keine Möglichkeit, selbst die Umwandlung in die Keycodes vorzunehmen. Dann könnte man das in Abhängigkeit der gewünschten Sprache sehr einfach implementieren. Stattdessen muss man gucken, welchen Text man ausgeben will und muss das in eine falsche ASCII-Repräsentation überführen. Aus diesem Grund habe ich hierzu auch ein Issue beim Arduino-Projekt eröffne. Da ich am Wochenende ein wenig Zeit hatte, habe ich mich zudem mal in den Arduino-Quelltext eingegraben und selbst eine mögliche Lösung implementiert. Mit der kann ich jetzt schon einmal weiterarbeiten, bis die offizielle Lösung zur Verfügung steht.

Sprachabhängige Grüße, Kenny


25. April 2013 ~ 1 Kommentar | ÄHNLICHE ARTIKEL

Host Europe: Hosting für jeden Bedarf

Dies ist eine gesponserte Rezension.

Host Europe ist ein Hosting-Anbieter, der mir bei meiner Recherche zu Rootservern immer wieder mal über den Weg läuft. Nicht ohne Grund: Das kölner Unternehmen hat in der Tat einige äußerst interessante Produkte im Portfolio.

Da wären zum einen die Storage-Lösungen, die angeboten werden. Dabei wird zwischen Managed Storage (via FTP) und S3-kompatiblem Cloud-Storage (auch via HTTP(S) abrufbar) unterschieden. Während das eine für Offsite-Backuplösungen seinen Reiz hat - zumal es in meinen Augen mit Preisen ab 1€/Monat für 10GB sehr günstig ist - ist das andere eine tolle Lösung für Dienste, die im Zuge der Web-Evolution einen immer größeren Speicherbedarf entwickeln.

Im Bereich der Rootserver bieten sie eine breite Palette an Produkten an. Angefangen bei günstigen Virtual Servern (mit integrierter Backup-Lösung), geht es über virtualisierte Root Server (mit integrierter Backup-Lösung und Remote-Management per VNC) bis hin zu den vollständig dedizierten Individual Servern.
Leute, die zwar die Leistung eines eigenen Servers benötigen, aber nicht das technische Know-How für den Betrieb haben, haben die Wahl zwischen von Host Europe gewarteten virtuellen WebServer Basic (schon ab 14,99€/Monat) und von Host Europe gewarteten dedizierten WebServer Premium.

Natürlich gibt es auch Angebote für Leute, die keinen Bedarf für die hohe Performance eines eigenen Servers haben und einfach nur eine oder mehrere Webseiten betreiben wollen. Hier stehen Angebote für das normale Webhosting in Form der WebPacks bereit. Es gibt jedoch mit dem sogenannten Web Builder auch die Möglichkeit, Webseiten ohne HTML-Kenntnisse zu erstellen. Dieses Produkt, das man 30 Tage kostenlos testen kann und das es bis zum 30.04.2013 für 6 Monate kostenlos gibt, wollte ich mir einmal näher ansehen.

Design auswählen

Design auswählen

Nachdem man sich für die Testphase registriert hat (die automatisch endet und nicht verlängert wird), erhält man einen Testzugang. Dieser wird nach Aussage von Host Europe separat von den bezahlten Kunden betrieben, um deren Performance nicht zu beeinflussen. Wenn man sich nach der Testphase für das Produkt entscheidet, kann man mit Hilfe eines Übernahme-Codes die bereits erstellte Webseite in das bestellte Produkt übertragen lassen.

Designfilter Designfilter

Designfilter

Nach dem Login landet man direkt in der Designauswahl für seine eigene Homepage. Die Designs selbst sind in meinen Augen gut und professionell gemacht. Es fehlen jedoch leider Designs für Blogs. Die gebotenen Designs richten sich vor allem an Unternehmen, die eine statische Webseite für die Präsentation ihres Unternehmens benötigen und nur selten Neuigkeiten auf dieser Seite verbreiten möchten. Bei der Wahl des Designs gibt es einige Filtermöglichkeiten.

Seite wird eingerichtet

Seite wird eingerichtet

Was ich hier ein bisschen merkwürdig finde: Es gibt die Filteroption "einzigartig", wobei es bei solchen Webseitenbaukästen wohl kaum eine einzigartige Designvorlage geben wird. Zum anderen sind viele der Designs auf Medienagenturen ausgerichtet. Mir selbst wäre ehrlich gesagt mulmig, wenn ich an eine Agentur geraten würde, die ihre eigene Webpräsenz mit einem Baukasten erstellt hat - obwohl sie damit doch Geld verdient. Darüber hinaus gibt es leider keine mobilen Designs zur Auswahl.

Bearbeiten-Modus

Bearbeiten-Modus

Nach der Auswahl des Designs landet man direkt im Bearbeitenmodus. Hier lassen sich über einfache Mausklicks und per Drag&Drop der Aufbau, die Gestaltung und der Inhalt der Webseite ändern. Dinge, wie das Navigationsmenü werden durch sogenannte Widgets automatisiert erzeugt. Dadurch muss man dort nicht immer nacharbeiten, wenn man z.B. eine neue Seite erstellt hat.

Fast leere Seite

Fast leere Seite

Apropos Seite erstellen: Hier gibt es in meinen Augen einen Fallstrick: Klickt man nämlich einfach auf "+ Hinzufügen" und dann auf "Seite erstellen", erhält man eine neue Seite, die fast vollständig leer ist. Hier wäre ich davon ausgegangen, das wenigstens das grundlegende Design mit übernommen wird.

Neue Seite anlegenNeue Seite anlegen

Neue Seite anlegen

Um eine neue Seite samt Inhalt und Aufbau zu erhalten ist es - nach meiner Erfahrung - sinnvoller, eine bereits vorhandene Seite samt Inhalt zu duplizieren. Das geht über das kleine Pfeilmenü, das rechts in der Seitenliste sichtbar wird, wenn man dort mit der Maus über den Namen einer Seite fährt. Dadurch wird das gesamte Design und die vollständige Seitenstruktur mit übernommen. Das spart viel Arbeit.

Verwaltung

Verwaltung

Neben der reinen Seitenerstellung gibt es auch noch einen Bereich, in dem die Webseite selbst verwaltet wird. Hier kann man SEO-Informationen hinterlegen, die Domain der Webseite konfigurieren, Weiterleitungen erstellen, die Seite deaktivieren und... die Seite "zurücksetzen".

Webseite zurücksetzen

Webseite zurücksetzen

Diese Funktion halte ich ehrlich gesagt für sehr gefährlich, denn danach ist alles, was man designed und konfiguriert und geklickt und eingefärbt und geschrieben hat... weg. Sollte man die Aufgabe der Seitenpflege also jemandem anvertrauen, dann sollte man sich auch wirklich sehr sicher sein, dass diese Person niemals diesen Knopf drücken wird. Eine Backupfunktion habe ich leider auch nirgendwo gefunden - weder in der Produktbeschreibung noch in der Testoberfläche. Eine Anfrage bei Host Europe hat jedoch erfreulicherweise ergeben, dass man den Hersteller bereits gebeten hat, eine Backupfunktion in den Web Builder zu integrieren.

Trotzdem denke ich, dass das Produkt interessant (und ab 5,99€/Monat auch bezahlbar) für jeden kleineren Betrieb sein könnte, der verstanden hat, dass bereits eine ordentliche Visitenkarte im Internet zu mehr Vertrauen und zu mehr Aufträgen führen kann, der jedoch nicht das technische Verständnis für die Erstellung oder den Betrieb einer eigenen Webseite hat. Dank der kostenlosen Testmöglichkeit ist es zudem problemlos möglich, zu gucken, ob einem das Angebot zusagt.

Hosting-Grüße, Kenny


25. April 2013 ~ 11 Kommentare | ÄHNLICHE ARTIKEL

[Update] 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


488
no-www.org extra-www.org
IPv6 ready XHTML 1.0 Transitional

Datenbank: 47 Abfragen | Generierung: 0,22397 Sekunden