USB-RS232-Waagenindikator am Pi: Berechtigungsfehler, ttyUSB0/ttyUSB1 wechselt, readline hängt
Von Türkçe mit KI übersetzt ·
Hallo. Im Lager haben wir einen Wägeindikator (RS232-Ausgang, sendet das Gewicht kontinuierlich). Ich habe ihn mit einem USB-RS232-Wandler an einen Raspberry Pi 4 angeschlossen; mein Ziel ist, das Gewicht mit Python auszulesen und per MQTT an Hermetry zu senden. Auf dem Pi laufen Raspberry Pi OS Lite, Python 3.11 und pyserial 3.5.
Beim ersten Versuch bekam ich diesen Fehler:
serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyUSB0:
[Errno 13] Permission denied: '/dev/ttyUSB0'
Der Code ist einfach:
ser = serial.Serial('/dev/ttyUSB0', 9600)
while True:
line = ser.readline()
print(line)
Was muss ich tun? Außerdem soll das später als Dienst selbstständig laufen. Wenn Sie dafür Vorschläge haben, würde ich mich freuen.
Selam. Depoda bir tartı indikatörümüz var (RS232 çıkışlı, sürekli ağırlık basıyor). Raspberry Pi 4’e USB-RS232 çevirici ile bağladım, amacım ağırlığı Python ile okuyup MQTT ile Hermetry’ye göndermek. Pi’de Raspberry Pi OS Lite, Python 3.11, pyserial 3.5.
İlk denemede şu hatayı aldım:
serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyUSB0:
[Errno 13] Permission denied: '/dev/ttyUSB0'
Kod basit:
ser = serial.Serial('/dev/ttyUSB0', 9600)
while True:
line = ser.readline()
print(line)
Ne yapmam lazım? Bir de ileride bu servis olarak kendi kendine çalışacak, ona göre önerirseniz sevinirim.
Von Türkçe mit KI übersetzt ·
Passiert das, wenn man es mit sudo ausführt? Bei mir war das so.
sudo ile çalıştırınca oluyor mu? Bende öyle olmuştu.
Von Türkçe mit KI übersetzt ·
Gerne, aber starte den Dienst nicht als root. Füge den Benutzer der Gruppe dialout hinzu: sudo usermod -aG dialout $USER, danach abmelden und wieder anmelden.
Olur ama servisi root ile çalıştırma. Kullanıcıyı dialout grubuna ekle: sudo usermod -aG dialout $USER, sonra çıkış yapıp tekrar gir.
Von Türkçe mit KI übersetzt ·
Das Berechtigungsproblem mit dialout ist behoben, danke. Es gibt aber zwei neue Probleme: Nach einem Neustart des Pi wird der Indikator manchmal zu ttyUSB1 (am selben Pi hängt außerdem ein USB-RS485), und readline wartet manchmal endlos, ohne dass etwas ausgegeben wird. In einem Terminalprogramm kommen die Indikatordaten allerdings an.
dialout ile izin sorunu gitti, teşekkürler. Ama iki yeni dert: Pi’yi yeniden başlatınca bazen ttyUSB1 oluyor (aynı Pi’de bir de USB-RS485 var), ve readline bazen sonsuza kadar bekliyor, hiçbir şey basmıyor. Terminal programında indikatör verisi akıyor ama.
Von Türkçe mit KI übersetzt ·
Beides hatte ich selbst, bei einem Wägeprojekt.Portname: Die ttyUSB-Nummer wird nach der Reihenfolge der Erkennung vergeben, also nicht darauf verlassen. Schau mit ls -l /dev/serial/by-id/ nach, dort gibt es einen dauerhaften Namen mit der Seriennummer des Wandlers, den nimm. Wenn du zwei gleiche Chips ohne Seriennummern hast, kannst du per udev-Regel nach USB-Port benennen, aber meistens reicht by-id.readline: Standardmäßig wartet es auf . Die meisten Anzeigen beenden Zeilen mit
, deshalb kehrt es nie zurück. Außerdem wartet es ohne Timeout bei abgezogenem Kabel ewig. Das benutze ich:
PORT = '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A10K3XYZ-if00-port0'
ser = serial.Serial(PORT, 9600, bytesize=8, parity='N', stopbits=1, timeout=2)
buf = b''
while True:
chunk = ser.read(64)
if not chunk:
continue # keine Daten seit 2 s, hier loggen
buf += chunk
while b'' in buf:
line, buf = buf.split(b'', 1)
w = parse_weight(line) # z. B. b'ST,GS,+0012.45kg'
if w is not None:
client.publish('v1/telemetry', json.dumps({'weight_kg': w}), qos=1)
Wenn die Anzeige mehrmals pro Sekunde ausgibt, sende nicht jede Zeile. Sende einmal pro Sekunde oder nur die ST-Zeilen (stabil). Schreib eine systemd-Unit für den Dienst, trag deinen eigenen Benutzer in die Zeile User= ein und nimm Restart=always.
İkisini de yaşadım, bir kantar projesinde.
Port adı: ttyUSB numarası takılma sırasına göre veriliyor, güvenme. ls -l /dev/serial/by-id/ ile bak, orada çeviricinin seri numaralı kalıcı adı var, onu kullan. Aynı çipten iki tane varsa ve seri numaraları yoksa udev kuralıyla USB portuna göre isim verirsin, ama çoğu zaman by-id yetiyor.
readline: varsayılan olarak bekliyor. Çoğu indikatör satırı
ile bitiriyor, o yüzden hiç dönmüyor. Bir de timeout vermezsen kablo çıktığında da sonsuza kadar bekler. Benim kullandığım:
PORT = '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A10K3XYZ-if00-port0'
ser = serial.Serial(PORT, 9600, bytesize=8, parity='N', stopbits=1, timeout=2)
buf = b''
while True:
chunk = ser.read(64)
if not chunk:
continue # 2 sn veri yok, burada log yaz
buf += chunk
while b'
' in buf:
line, buf = buf.split(b'
', 1)
w = parse_weight(line) # örn. b'ST,GS,+0012.45kg'
if w is not None:
client.publish('v1/telemetry', json.dumps({'weight_kg': w}), qos=1)
İndikatör saniyede birkaç kez basıyorsa her satırı gönderme. Hermetry’de cihaz başına varsayılan limit saniyede 10 mesaj, üstü sessizce düşüyor. Saniyede bir, ya da sadece ST (stabil) satırlarını yolla. Servis için systemd unit yaz, User= satırına kendi kullanıcını koy, Restart=always.
Von Türkçe mit KI übersetzt ·
Das Zeilenende ist tatsächlich , ich habe es mit hexdump geprüft. Das Portproblem ist mit by-id ebenfalls gelöst. Jetzt sende ich nur noch stabile Messwerte einmal pro Sekunde, und seit 2 Tagen läuft es mit systemd problemlos. Danke.
Satır sonu gerçekten imiş, hexdump ile baktım. by-id ile port sorunu da bitti. Şimdi sadece stabil okumaları saniyede bir yolluyorum, systemd ile 2 gündür sorunsuz. Sağ olun.
Von Türkçe mit KI übersetzt ·
Bei günstigen Wandlern mit CH340 gibt es keine Seriennummer, und unter by-id sehen beide gleich aus. In diesem Fall verwenden Sie /dev/serial/by-path/, dieser Pfad bleibt an den USB-Port gebunden.
CH340’lı ucuz çeviricilerde seri numarası olmuyor, by-id’de ikisi aynı görünür. O durumda /dev/serial/by-path/ kullanın, USB portuna bağlı kalıyor.
- Du musst angemeldet sein, um auf dieses Thema antworten zu können.
Mitdiskutieren
Melde dich an, um Fragen zu stellen und zu beantworten, hilfreiche Beiträge mit „Gefällt mir“ zu markieren und die Antwort zu kennzeichnen, die dein Problem gelöst hat. Jeder Beitrag bringt Punkte und Stufen.

