Pyton 3 Serial Fehler

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.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Hallo zusammen,

ich beschäftige mich zur Zeit mit Serieller Schnittstelle und würde gerne diese mit Python 3 auslesen.
Zu Testzwecken hab ich ein paar Zeilen gefunden die ich in Idle dann übernommen und getestet habe.

Code: Alles auswählen

import serial
ser = serial.Serial('COM1')  # open serial port
print(ser.name)         # check which port was really used
ser.write(b'hello')     # write a string
ser.close()             # close port
habe auch schon über pip Seriel und Pyserial installiert beides hat geklappt. Leider bekomme ich ständig folgene Meldung.

Traceback (most recent call last):
File "C:/Users/x/Documents/script/serial.py", line 1, in <module>
import serial
File "C:/Users/x/Documents/script\serial.py", line 2, in <module>
ser = serial.Serial('COM1') # open serial port
AttributeError: module 'serial' has no attribute 'Serial'

Für mich sieht das so aus als ob es ein Problem mit dem Modul gibt?

Bevor ich mich an die eigentliche zu lösende Aufgabe machen will, wollte ich zumindest die Funktion testen das auch am COM1 was passiert aber leider tut sich da nix egal was ich probiere.

Hat jemand eine Idee? LG

EDIT: das Problem lag wohl daran das der Script Name "serial.py" war.
Habe diesen geändert und nun fehlt nur noch das Zugriffs Recht.

Edit Edit: Problem gelöst fürs erste Com Port wurde noch belegt von einem anderen Programm.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Aber jetzt mal eine andere Frage stehe jetzt wirklich auf dem Schlauch.

Code: Alles auswählen

import serial
ser = serial.Serial()
ser.baudrate = 19200
ser.port = 'COM1'
ser.timeout = 1
ser.open()


print(ser.name)         
ser.readline()
print (ser.readline())
ser.close()             
input ()
Funktioniert an sich nur wenn ich am Laptop den ich mit RS232 verbunden habe bei Hyperterminal einen Buchstaben Tippe kommt nur folgene Antwort an:

b'\x80\x00\x80'

wie kann ich das umwandeln in normale ASCII Zeichen.

Ich will quasi vom Sender Text empfangen und den am Empfänger (wo das Script läuft) anzeigen.

Wäre erfreut über einen Denk anstoß.

LG
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dir ist klar, das dein erstes readline Daten abgreift & wegwirft? Man kann das nicht mehrfach aufrufen, und erwarten die Daten bleiben verfügbar.

Wenn die Daten so sehr nicht passen zur Eingabe, liegt es ggf an der Baudrate. Die ist sehr niedrig bei dir. Ist sie gleich auf beiden Seiten?
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Ja liegt beides bei 19200 als Test tippe ich am Sender nur Bsp. ein Buchstabe.

Mir war das nicht Bewusst das, dass erste readline () die Daten schon vorwegnimmt habe das jetzt entfernt und nur

print (ser.readline())

stehen.

Ausgabe ist jetzt auch nur noch b'' .

Edit: Mit ser.write(b'hello') kann ich auch den Text senden an Hyperterminal wird erkannt ohne Probleme.
nur anders rum halt nicht und Habe die Rate auf 38400 angehoben.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dann pack das mal in eine while-Schleife und druck *alles* aus, was da so kommt. Denn die Verbindung steht, das liegt wahrscheinlich daran, dass hyperterminal ein anderes Zeilenende liefert, als readline erwartet.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Mit einer schleife und einem time.sleep damit es nicht so schnell geht sieht es so in etwa aus.

============= RESTART: C:/Users/x/Documents/script/test 2.py =============
COM1
b'\xff'
b''
b'hallo'
b''
b'test'
b''
b''


tätige ich eine Eingabe am Sender wird diese auch erkannt und gesendet und wie man sieht zwischen die Striche gesetzt.
Das kommt mir aus diesem Code bekannt vor : ser.write(b'das ist ein Test') quasi ohne Text (b'').

Hatte die Idee mit der Schleife auch schon um zu testen ob man überhaupt eine Eingabe machen kann.

Leider wird die Schleife nicht weiter abgefragt sobald ich die in # gesetzten Zeilen hinzufüge bin noch am forschen wie ich das Problem lösen kann bzw ein Timeout einbinde so das nach einer gewissen zeit die Schleife gestoppt wird sollten keine Daten mehr Empfangen werden.

Danke schonmal für die mühe und anregungen.

LG

Code: Alles auswählen

import serial, time
ser = serial.Serial()
ser.baudrate = 38400
ser.port = 'COM1'
ser.timeout = 1
ser.open()

if ser.isOpen():
    print(ser.name)


while 1:
    serial_line = ser.readline() 
    print(serial_line)

    time.sleep(3)

    #cmd = input()
    #if cmd == 'exit':
        #ser.close()
        #exit()
    
#ser.write(b'das ist ein Test')
#ser.close()
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Habe das Problem gelöst.

Es liegt daran das Bytes empfangen werden und Python 3 daher " b'text' " ausgibt.

Code: Alles auswählen

while 5:
    serial_line = ser.readline()
    print(serial_line.decode("utf-8"))
hat das Problem gelöst.
narpfel
User
Beiträge: 645
Registriert: Freitag 20. Oktober 2017, 16:10

@AnDre86: Warum schreibst du `while 5:`? Warum nicht `while 42:` oder `while 27:`?

Warum nicht die offensichtliche Variante `while True:`?
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Hallo,

COM1
Traceback (most recent call last):
File "C:/Users/x/Documents/script/test 2.py", line 12, in <module>
while true:
NameError: name 'true' is not defined

warum auch immer, hatte eigentlich eine 1 stehen war wohl beim herum probieren stehen geblieben die 5.

LG
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

"Warum auch immer" ist deine Kleinschreibung, wenn es in Python True ist statt true.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Oh das ist mir garnicht aufgefallen.

Nach einer gewissen Zeit wird man Blind scheint es mir :) Danke für den Hinweis.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Hallo nochmal,

kann es sein das bei längerer Byte folge es zu Fehlern kommt hatte jetzt mal eine Textdatei gesendet und bekam folgenen fehler:

Traceback (most recent call last):
File "C:\Users\x\Documents\script\test 2.py", line 16, in <module>
print(serial_line.decode("utf-8"))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

Bin das jetzt mal umgangen mit

Code: Alles auswählen

while True:
    serial_line = ser.readline()
    
    if len(serial_line) > 0:
        #print(serial_line.decode("utf-8"))
        print(serial_line.decode(encoding='utf-8',errors='replace'))
        time.sleep(1)
Ergebnis ist:
COM1
Test Daten Test Daten � � � Test Daten Test Daten
Test Daten Test Daten � � � Test Daten Test Daten
Test Daten Test Daten � � � Test Daten Test Daten
Test Daten Test Daten � � � Test Daten Test Daten
Test Daten Test Daten � � � Test Daten Test Daten
Test Daten Test Daten � � � Test Daten Test Daten
Test Daten Test Daten � � � Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten � � � � � Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten
Test Daten Test Daten Test Daten Test Daten

gibt es eine andere möglichkeit?
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wer schickt denn die Daten? Prinzipiell ist eine serielle Leitung so mittel gut. Da kann es sich je nach Anwendungszweck schon lohnen, ein Protokoll zu fahren, mit Prüfsummen & expliziten Bestätigungen.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Momentan über einen Laptop via Hyperterminal. Später will ich das Script nutzen um eine Serieleschnittstelle auszulesen. Wollte mir den weg über Hyperterminal sparen und halt nur das Script öffnen.

Mir ist aufgefallen das bei jeweils 3 gleichen Zeichen ein Error kommt.
Die Hardware lässt leider nix anderes zu, es wird ein Text Log gesendet welches mehrere Zeichen enthält die gleich sind.


COM1
aa�a
ss�s
dd�d
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich würde da auf eine wie auch immer geartete schlechte Verbindung tippen. Kann natürlich auch sein, das einer der beteiligten PCs spinnt. Musst du dann experimentieren mit anderen Komponenten.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Also an sich sollte das Funktionieren ja? Dann kann ich mir nur vorstellen das es an der PCIE liegt die das Problem verursacht den normale Texte ohne Zeichen wiederholung funktionieren ja auch. OK danke sehr für den Tip ich werde das mal Testen und das Script erweitern :)

LG
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Habe mal etwas gelesen hoffe ich habe das so richtig verstanden, kann es sein das am ASCII von Hyperterminal hapert?
Quasi das problem mit den bit gibt?
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Noe. Ein A ist ein A ist ein A.
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Ok,
nachdem ich jetzt im Hyperterminal, bei Zeilenverzögerung und Zeichenverzögerung jeweils 1 Millisekunde hinzugefügt habe scheint es zu funktionieren.

Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>>
============= RESTART: C:\Users\x\Documents\script\test 2.py =============
COM1
Test Daten Test Daten Test Daten Test Daten


Test Daten Test Daten Test Daten Test Daten


Test Daten Test Daten Test Daten Test Daten


Eine Textdatei lasse ich mir auch erstellen, muss nur noch herausfinden wie immer eine neue erstellt wird wenn ich das script neu starte.

Aufjedenfall vielen Dank für eure Hilfe.

LG

Code: Alles auswählen

import serial, time
ser = serial.Serial()
ser.baudrate = 19200
ser.port = 'COM1'
ser.timeout = 1
ser.open()


if ser.isOpen():
    print (ser.name)
    
while True:
    serial_line = ser.readline()
     
    if len(serial_line) > 0:
        print(serial_line.decode(encoding='utf-8',errors='replace'))
        time.sleep(1)
        date = time.strftime("%d.%m.%Y")
        log = str(serial_line.decode(encoding='utf-8'))
        f = open(r"C:\Users\x\Desktop\Test\Messung.txt", "a")
        f.write(log)
        f.close()
AnDre86
User
Beiträge: 31
Registriert: Dienstag 2. Januar 2018, 14:35

Hallo nochmals,

habe nochmal eine Frage, da das ja jetzt läuft hätte ich gerne eine möglichkeit beim erneuten Ausführen des Scriptes das immer eine neue .txt erstellt wird ohne die alte .txt zu überschreiben oder was hin zu zu schreiben. Momentan füge ich immer nur neues hin zu.

Würde gerne auch das Aktuelle Datum im Namen haben aber habe noch keine passende Lösung gefunden.

Habt ihr nen Tip dazu?
Antworten