Interrupt bei Zeichen an serieller Schnittstelle (pySerial)?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
SwissMäc
User
Beiträge: 20
Registriert: Freitag 26. Februar 2010, 21:36

Hallo zusammen
Ich versuche unter Linux (später OSX) die an "/dev/ttyUSB0" ankommenden Zeichen via Interrupt (also signal) zu verarbeiten, genauer in einem String zu sammeln bis ein "Enter" kommt.

Nun finde ich keinen Hinweis, wie ich das mit pySerial machen kann, ich finde kein "signal.serial" ?

Kann mir jemand auf die Sprünge helfen oder kennt sogar ein Beispielscript ?
BlackJack

@SwissMäc: Wie kommst Du darauf dass das etwas mit Signals zu tun hat? Warum liest Du das nicht einfach normal ein?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@SwissMäc:
Du kannst von dem Device normal lesen, also einfach auf das Eintreffen des "Enters" warten. Wie das "Enter" in Bytes kodiert ist, hängt vom System/Terminaleinstellungen der Gegenstelle ab.

Das hat nichts mit Signalen oder Interrupts zur Prozesssteuerung zu tun. Ich rate Dir, nicht mit Signalen rumzuhantieren, wenn Dir nicht deren Einsatzzweck und Konsequenzen für Deinen Code klar sind. Korrekte Signalbehandlung ist alles andere als trivial.
Benutzeravatar
SwissMäc
User
Beiträge: 20
Registriert: Freitag 26. Februar 2010, 21:36

Ich komme darauf, weil ein Computer besseres zu tun hat als zu warten.
Beim Mikroprozessor wird das über ein Interrupt gemacht: Zeichen kommt, IRQ wird ausgelöst, liest das Zeichen ein und schreibt es in einen String, ist es ein Enter, wird ein Flag gesetzt.
Nun möchte ich das auf dem grossen Computer genauso machen, denn wenn die Schnittstelle auf Eingabe wartet, kann ich doch nicht senden.
BlackJack

@SwissMäc: Ein grosser Computer ist da ein wenig anders als ein Mikroprozessor. Beim PC ist da zum Beispiel noch ein Betriebssystem zwischen Deinem Programm und der Hardware. Und das abstrahiert so etwas wie serielle Schnittstellen über Treiber zu Dateien. Wenn es möglich ist werden diese Treiber schon Interrupts verwenden statt ständig zu Pollen. Die Interrupts werden aber nicht an Dein Programm weiter geleitet sondern intern verarbeitet. Und Signals ist nicht dazu da um beliebige Hardware-Interrupts an Programme weiter zu leiten. Selbst wenn das ginge, würde man das nicht machen wollen, weil es unhandlich zu Programmieren ist wenn Programme an beliebigen Stellen unterbrochen werden dürfen.

Benutze `threading` wenn Du während des Empfangens noch etwas anderes machen möchtest.
lunar

Alternativ "select()", um vor dem Lesen der Daten zu prüfen, ob tatsächlich Daten bereit stehen.
BlackJack

@lunar: Hatte ich auch beinahe in meinem Beitrag erwähnt, aber die Frage ist ob das plattformunabhängig und im Zusammenhang mit `serial.Serial`-Exemplaren überhaupt möglich ist.
lunar

@BlackJack Es ist möglich, aber nicht plattformunabhängig. Unter Windows kann "select()" nur mit Sockets verwendet werden. Der OP sprach aber nur von Linux und OS X.
Benutzeravatar
SwissMäc
User
Beiträge: 20
Registriert: Freitag 26. Februar 2010, 21:36

Hier meine Lösung, falls jemand das selbe Problem hat und auch in die Tcl Mac-Falle tappt:

Code: Alles auswählen

from Tkinter import *
import serial
import thread

...

def bgreader():
    while 1 :
        bgout = ser.readline()

        if bgout == "An\r\n":
            gottext.set("LED ist an")
            feedback["background"] = "red"

...

thread.start_new_thread(bgreader,())
Wenn das mit Tcl/tk auf einem Mac gemacht werden soll, dann kann es die "TclError: out of stack space (infinite loop?)"-Fehlermeldung geben.
Entweder man kompiliert Tcl neu mit "--enable-threads" oder installiert mit MacPorts einen anderen Threader: "port install tcl +threads".
Ich habe den installiert und es funktioniert super. :mrgreen:

Nochmals danke an alle ! :D
BlackJack

@SwissMäc: Dass das keine Lösung ist schreibst Du ja gleich selber. Man braucht dazu eine spezielle Tk-Version. Die wird kaum jemand haben. Also wäre es besser es gleich so zu programmieren, dass es mit jeder Tk-Version läuft. Also ohne aus einem anderen Thread heraus die GUI zu manipulieren.

Das `thread`-Modul sollte man übrigens nicht mehr verwenden. In dessen Dokumentation wird gleich am Anfang auf das `threading`-Modul verwiesen.
Antworten