Zu dem Franzis Lernpaket "Elektronik mit Linux" gehört eine kleine
Platine mit einem FT232R, der als /dev/ttyUSB0 angesprochen wird, die
aber nur sporadisch mit Python-Skripten funktioniert.
Das
1 | dd if=/dev/random of=/dev/ttyUSB0
|
funktioniert (unter Ubuntu 12.04.3 LTS) immer, aber die Python-Skripte
nur sporadisch: Der erst Verschuch funktionierte (nach xhost + vom
User), nach dem Abschalten vom USB-Hub und später wieder einschalten
aber nicht mehr, weil das Skript behauptet /dev/ttyUSB0 nicht mehr
öffnen zu können (Fehlermeldung "Kann /dev/ttyUSB0 nicht oeffnen."),
obwohl ich die gleiche root-Shell wie beim ersten Mal verwende. Auch ein
"chmod a+rwx /dev/ttyUSB0" half nicht.
Da dd keine Probleme hat auf /dev/ttyUSB0 zuzugreifen und dmesg keine
Fehler meldet, sind die Hardware und /dev/ttyUSB0 nicht die Ursache.
Hier ist das Blinker-Skript, das versagt:
1 | import serial, time, os, sys, time, glob
|
2 | from threading import Thread
|
3 |
|
4 | if (os.geteuid() != 0):
|
5 | print "Die Nutzer ID ist nicht 0. Geraetesteuerung wird nicht funktionieren."
|
6 | print "- starten Sie das Programm als root (Administrator)"
|
7 | raise SystemExit
|
8 |
|
9 | try:
|
10 | # begin open connection to /dev/ttyUSB<whatever>
|
11 | for devices in glob.glob("/dev/ttyUSB*"):
|
12 | garbage=42 # appease python
|
13 | conn = serial.Serial(devices, baudrate=9600)
|
14 | # done open connection
|
15 | except:
|
16 | print "Kann /dev/ttyUSB0 nicht oeffnen."
|
17 | print "- Ist die Platine an USB angeschlossen?"
|
18 | sys.exit()
|
19 |
|
20 | def blinker(i):
|
21 | try:
|
22 | while (float(key)!=0):
|
23 | conn.setRTS(True) # RTS stays OFF
|
24 | conn.setDTR(False)
|
25 | conn.setBreak(True)
|
26 | if (float(key)!=0):
|
27 | time.sleep(0.5/float(key))
|
28 | conn.setRTS(True) # RTS stays OFF
|
29 | conn.setDTR(True)
|
30 | conn.setBreak(False)
|
31 | if (float(key)!=0):
|
32 | time.sleep(0.5/float(key))
|
33 | except:
|
34 | garbage=42 # make python happy
|
35 |
|
36 | fd=sys.stdin.fileno()
|
37 | key=1 # initial freq is 1/s
|
38 | try:
|
39 | while True:
|
40 | t=Thread(target=blinker, args=(float(key),))
|
41 | t.start()
|
42 | print "Frequenz?"
|
43 | key=os.read(fd, 5)
|
44 | except:
|
45 | print "Programm beendet"
|
46 | key=0 # thread stoppen
|
47 | raise SystemExit
|
strace zeigt das der Fehler ist das auf eine ganz andere Schnittstelle
zugegriffen wird, nämlich ttyUSB1:
1 | open("/dev/ttyUSB1", O_RDWR|O_NOCTTY|O_NONBLOCK) = -1 ENODEV (No such device)
|
Es sind also in dem kleinen Skript gleich zwei Fehler: Falsche
Fehlermeldung und Zugriff auf das falsche Gerät, denn die letzte
Kernel-Meldung lautet
1 | [973281.259236] usb 1-2.2: FTDI USB Serial Device converter now attached to ttyUSB0
|
Da ich vorwiegend in C/C++ programmiere und in Bash skripte bekomme ich
die Bugs aus dem Python-Skript nicht raus, vermute aber das das für
Python-Programmierer trivial ist.
Was muss man denn an dem Skript ändern um beide Bugs zu beseitigen?