Seite 1 von 1
Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Mittwoch 22. Dezember 2021, 17:06
von Crix1990
Hallo,
ich hoffe, ihr könnt mir hier weiterhelfen.
Ich steuere Über Python Skripte meine Stereo Anlage (via Seriellem Interface).
Nachdem ich mir einen neuen Computer gekauft habe, habe ich aber leider regelmäßig Probleme damit.
Das USB-Serial Interface ist das gleiche geblieben. USB Anschlüsse habe ich mehrere durchprobiert.
Hier mal ein Biespiel für die Skripte:
Code: Alles auswählen
import serial
import sys
import threading
import re
import time
try:
ser = serial.Serial( port="COM7",
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=20000 )
print ("Serial port is open")
except Exception as e:
print ("error open serial port: " + str(e))
exit()
try:
s = "Test"
print (s)
ser.write(b'\r')
ser.write(b'#1,01,0\r')
s = ser.read(6)
if s == (b'#11,01'):
print ("Was already off.")
ser.write(b'#1,01,1\r')
print (s)
except Exception as e:
print ("error communicating...: " + str(e))
Als Fehlermeldung kriege ich dieses zurück:
Code: Alles auswählen
Python 3.10.1 (tags/v3.10.1:2cd268a, Dec 6 2021, 19:10:37) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
= RESTART: C:\Program Files (x86)\Corsair\CORSAIR iCUE Software\Macros\Python\Power_Toggel.pyw
error open serial port: could not open port 'COM7': PermissionError(13, 'Zugriff verweigert', None, 5)
w
Ich hatte auf meinem alten Rechner Python 3.7 und PySerial 3.4.
Jetzt habe ich 3.10 und 3.5.
Ein Versuch mit den alten Versionen ist aber erfolglos geblieben.
Im Moment leuft es nur so in 10% der Fälle.
Wenn es nicht funktioniert hilft nur PC Neustart.
Kein Anderes Programm nutzt (bewusst) dieses Interface.
Neustart des Interfaces über die Systemsteuerung hilft nur ganz selten.
Komplette Neuinstallation der Treiber hat leider auch nichts gebracht.
Ich hoffe ihr könnt mir helfen...
Grüße,
Felix
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Mittwoch 22. Dezember 2021, 18:44
von sparrow
Irgend etwas benutzt den Port bereits, bevor du ihn öffnest.
Möglicherweise du selbst, denn du schließt den Port nirgends. Deshalb öffnet man,
wie in der Dokumentation beschrieben mit dem with-Statement, um sicherzustellen, dass die Schnittstelle korrekt wieder geschlossen wird.
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Mittwoch 22. Dezember 2021, 18:48
von darktrym
Oder einfach die Verbindung explizit schließen.
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Mittwoch 22. Dezember 2021, 18:55
von sparrow
Das finde ich keine gute Idee, denn da tun sich Fallstricke auf, die man umgehen kann, wenn man einfach das with-Statement verwendet. Ich würde fast darauf wetten, dass es sonst nicht korrekt verwendet wird.
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Mittwoch 22. Dezember 2021, 20:09
von Sirius3
`sys`, `threading`, `re` und `time` werden importiert, aber gar nicht gebraucht.
Das Exceptionhandling ist ziemlich unsinnig, weil Du nur informative Tracebacks durch weniger aussagekräftige Meldungen ersetzt, die können also weg.
Der serielle Port muß auch wieder geschlossen werden. Ist das Zeilenende wirklich nur \r? Das ist sehr ungewöhnlich. Dass Du nur 6 Bytes liest und nicht eine ganze Zeile, sieht genauso falsch aus.
Besser sähe das wohl so aus:
Code: Alles auswählen
import serial
with serial.Serial(
port="COM7",
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=20000) as port:
port.write(b'\r\n')
port.write(b'#1,01,0\r\n')
data = port.readline()
if data.startswith(b'#11,01'):
print("Was already off.")
port.write(b'#1,01,1\r\n')
print(data)
Du hast ein Konsolenprogramm, warum heißt das dann Power_Toggel.pyw, mit w am Ende?
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Sonntag 26. Dezember 2021, 04:32
von Crix1990
Danke schon mal für die Rückmeldungen!
Ich werde versuchen mir das morgen mit dem sauberen Schließen anzulesen.
Um schon mal auf die anderen Fragen einzugehen:
Das /r ist hier ein Enterersatz, wird der Befehl damit nicht geschlossen, wird er vom Verstärker nicht ausgeführt (simple RS-232 Schnittstelle). Das vorausgehende /r soll quasi die Zeile frei machen, falls da noch "Reste drin sind".
Dass ich nur 6 Bytes auswerte liegt daran, dass der Verstärker maximal 6 Bytes zurück gibt. Auf die meisten Befehle gibt es gar keine Rückmeldung.
.pyw nutze ich, damit das Skript fensterlos im Hintergrund aufgerufen wird (ich habe die Skripte auf Tasten meiner Tastatur gelegt).
Wiegesagt, das ganze hat die letzten 6 Jahre problemlos funktioniert.
Erst mit dem neuen PC gibts Probleme...
Ich hab deinen Vorschlag mal ausprobiert, fliege aber auf massig Fehlermeldungen:
Code: Alles auswählen
Traceback (most recent call last):
File "C:\Users\Felix\Desktop\Power_Toggel.pyw", line 8, in <module>
with serial.Serial(
File "C:\Program Files\Python39\lib\site-packages\pyserial-3.5-py3.10.egg\serial\serialwin32.py", line 33, in __init__
super(Serial, self).__init__(*args, **kwargs)
File "C:\Program Files\Python39\lib\site-packages\pyserial-3.5-py3.10.egg\serial\serialutil.py", line 244, in __init__
self.open()
File "C:\Program Files\Python39\lib\site-packages\pyserial-3.5-py3.10.egg\serial\serialwin32.py", line 64, in open
raise SerialException("could not open port {!r}: {!r}".format(self.portstr, ctypes.WinError()))
serial.serialutil.SerialException: could not open port 'COM7': FileNotFoundError(2, 'Das System kann die angegebene Datei nicht finden.', None, 2)
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Sonntag 26. Dezember 2021, 06:47
von __blackjack__
@Crix1990: Das weniger als 6 Bytes von der Gegenseite kommen kann eigentlich nicht sein, weil ``read(6)`` wartet/blockiert bis 6 Bytes gelesen wurde. Ausser die Zeitüberschreitung von 20.000 Sekunden wird überschritten. Das heisst wenn weniger als 6 Bytes kommen, dann blockiert Dein Programm etwas mehr als 5½ Stunden die serielle Schnittstelle. Womit wir vielleicht dem ursprünglichen Problem auf der Spur wären‽ Kann es sein, dass ein alter/vorheriger Prozess Deines Programms den Port blockiert und verhindert, das ein erneuter Programmstart den benutzen kann‽
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Sonntag 26. Dezember 2021, 19:08
von Crix1990
So, um positive Nachrichten zu bringen:
Das grundsätzliche Problem war, dass der Port nicht geschlossen wurde (in jedem Skript).
Ich schließe ihn jetzt nach jedem Skript explizit mit ser.close() und habe den Timeout auf 2 Sekunden reduziert.
Um sauberer zu laufen habe ich das Auslesen der Antworten auf readline() gesetzt (wobei es nach den vorherigen Änderungen auch mit ser.read(6) geklappt hat.
Ich habe dann auch mal die Imports ausgedünnt, wobei time mit Absicht drin war, da es in der Hälfte der Skripte genutzt wird.
Wahrscheinlich hatte ich mit dem alten PC (warum auch immer) nur Glück, dass die Ports kein Problem mit dem schließen hatten.
Danke euch nachmals und schöne Weihnachten!
Felix
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Sonntag 26. Dezember 2021, 19:23
von __blackjack__
@Crix1990: Statt den manuell mit `close()` zu schliessen solltest Du ``with`` verwenden. Dann ist egal *warum* der Block verlassen wird, es wird immer geschlossen. Zum Beispiel auch wenn das Programm wegen einer Ausnahme abbricht während der Port offen ist.
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Sonntag 26. Dezember 2021, 19:30
von Crix1990
Kannst du mir dafür ein Beispiel geben?
Ich habe mir meine Python Kentnisse quasi nur an diesen Skripten beigebracht und hab sonst keine Ahnung...^^
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Sonntag 26. Dezember 2021, 19:35
von sparrow
Dehalb habe ich dir in meiner ersten Antwort sogar einen Link zur Dokumentation gepackt.
Re: Serielles Interface lässt sich unter Windows oft nicht aufrufen
Verfasst: Sonntag 26. Dezember 2021, 19:52
von Crix1990
Danke, das war für mich am Anfang nicht klar, wie da die Syntax aufgebaut wird, habs jetzt aber mit Probieren raus bekommen.
Nur um sicher zu sein, so ists sauber?
Code: Alles auswählen
import serial
with serial.Serial( port="COM3",
baudrate=9600,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=2 ) as ser:
ser.write(b'\r')
ser.write(b'#1,02\r')
print("write data: Volume Up")