USB-RS232 scale indicator on Pi: permission error, ttyUSB0/ttyUSB1 keeps changing, readline hangs
Translated from Türkçe by AI ·
Hi. We have a weighing indicator in the warehouse (RS232 output, continuously transmitting weight). I connected it to a Raspberry Pi 4 with a USB-RS232 converter; my goal is to read the weight with Python and send it to Hermetry via MQTT. On the Pi I’m running Raspberry Pi OS Lite, Python 3.11, pyserial 3.5.
On the first attempt I got this error:
serial.serialutil.SerialException: [Errno 13] could not open port /dev/ttyUSB0:
[Errno 13] Permission denied: '/dev/ttyUSB0'
The code is simple:
ser = serial.Serial('/dev/ttyUSB0', 9600)
while True:
line = ser.readline()
print(line)
What should I do? Also, I’d eventually like this to run on its own as a service, so I’d appreciate suggestions with that in mind.
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.
Translated from Türkçe by AI ·
Does it happen when you run it with sudo? It happened to me too.
sudo ile çalıştırınca oluyor mu? Bende öyle olmuştu.
Translated from Türkçe by AI ·
That’s fine, but don’t run the service as root. Add the user to the dialout group: sudo usermod -aG dialout $USER, then log out and log back in.
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.
Translated from Türkçe by AI ·
The permission problem is gone after adding the user to dialout, thanks. But I have two new issues: after rebooting the Pi, sometimes the scale indicator becomes ttyUSB1 (there is also a USB-RS485 on the same Pi), and readline sometimes waits forever, with nothing being printed. The indicator data does flow in a terminal program, though.
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.
Translated from Türkçe by AI ·
I experienced both, in a weighing scale project.Port name: the ttyUSB number is assigned based on enumeration order, so don’t trust it. Check with ls -l /dev/serial/by-id/, there is a permanent name containing the converter’s serial number, use that. If you have two of the same chip and no serial numbers, you can name them by USB port with a udev rule, but most of the time by-id is enough.readline: by default it waits for . Most indicators end lines with
, so it never returns. Also, if you don’t set a timeout, it waits forever when the cable is unplugged. What I use:
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 # no data for 2 s, log here
buf += chunk
while b'' in buf:
line, buf = buf.split(b'', 1)
w = parse_weight(line) # e.g. b'ST,GS,+0012.45kg'
if w is not None:
client.publish('v1/telemetry', json.dumps({'weight_kg': w}), qos=1)
If the indicator prints several times a second, don’t send every line. Send once per second, or only the ST (stable) lines. Write a systemd unit for the service, put your own user in the User= line, and use 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.
Translated from Türkçe by AI ·
The line ending really is , I checked with hexdump. The port problem is also solved with by-id. Now I just send stable readings once a second, and it has been running without issues for 2 days with systemd. Thanks.
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.
Translated from Türkçe by AI ·
Cheap CH340-based converters have no serial number, and both show up the same under by-id. In that case, use /dev/serial/by-path/; it stays tied to the USB port.
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.
- You must be logged in to reply to this topic.
Join the conversation
Sign in to ask and answer, like helpful posts and mark the reply that solved your problem. Every contribution earns points and levels.

