Forum: PC-Programmierung COM Port mit python und senden von Daten


von Max (Gast)


Lesenswert?

Hallo Leute,
hab schwierigkeiten mit Python über dem COM-Port daten zu senden. Ich 
wollte einfach mal nach dem Enter einen reboot befehl senden, allerdings 
bekomme ich immer "error communications". Woran kann es liegen? Hier ein 
kleiner Code:

import serial
import sys
import threading
import re
import time

ser = serial.Serial( port=COM1,
         baudrate=115200,
         bytesize=serial.EIGHTBITS,
         parity=serial.PARITY_NONE,
         timeout=2)
try:

    print ("Serial port is open")
    ser.isOpen()

except Exception:

    print ("error open serial port: " + str(e))

    exit()

if ser.isOpen():
    try:
        ser.write('\r')
        ser.write('reboot')
        print("write data: reboot")

    except Exception:
        print ("error communicating...: " + str())
else:
    print ("cannot open serial port ")

Vielen Dank im Vorraus!

Gruß
Max

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Max schrieb:
> ser = serial.Serial( port=COM1,

Sofern Du nicht vorher eine Zuweisung wie z.B. COM1='COM1' durchgeführt 
hast, ist das falsch. Korrekt wäre z.B. unter MS Windows:

ser = serial.Serial( port='COM1',

von Kaj (Gast)


Lesenswert?

Andreas Schweigstill schrieb:
> ser = serial.Serial( port='COM1',
Wenn er wirklich COM1 haben will, muss er (glaube ich) 'COM0' angeben, 
da das bei M$ immer um eins verschoben ist.

ser = serial.Serial( port='COM0'

oder:

COM1 = 'COM0'
ser = serial.Serial( port=COM1,

Aber sonsten hast du natuerlich recht: der Portname muss als string 
angegeben werden, wie unter linux auch (port='/dev/ttyUSB0', z.B.)

Gruesse

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Kaj schrieb:
> Wenn er wirklich COM1 haben will, muss er (glaube ich) 'COM0' angeben,
> da das bei M$ immer um eins verschoben ist.

Das ist doch eher umgekehrt. Die Beschriftungen an Motherboards und 
Einsteckkarten beziehen sich meist auf die alte DOS-Konvention mit COM1 
als erstem Port. Unter unixoiden BS beginnt die Zählung jedoch mit 0, 
z.B. /dev/ttyS0 == COM1.

von Max (Gast)


Lesenswert?

Hallo,
erstmal danke für die Feedbacks. Ich habe es nun korrigiert. Nun wenn 
ich es so ändere:
"ser = serial.Serial( port='COM1',..."
dann habe ich die gleiche Meldung wieder "error communicating..." . Wenn 
ich es nun auf 'COM0' ändere dann bekomme ich eine menge von 
Fehlermeldungen beim compilieren.

Gruß
Max

von Yalu X. (yalu) (Moderator)


Lesenswert?

Max schrieb:
>         ser.write('\r')
>         ser.write('reboot')

Du verwendest offensichtlich Python 3. Dort sind die Strings '\r' und
'reboot' Unicode-Strings, mit denen pySerial nichts anzufangen weiß.
Nimm stattdessen Byte-Strings:
1
         ser.write(b'\r')
2
         ser.write(b'reboot')

von Max (Gast)


Lesenswert?

Hi Yalu X.,
vielen Dank! nun funktioniert es :-)

Schönen Gruß
Max

von Yalu X. (yalu) (Moderator)


Lesenswert?

Noch ein paar Anmerkungen:

port='COM1' läuft nur auf Windows, port='/dev/ttyS0' nur auf Linux,
port=0 hingegen auf beidem. Die 0 wird von pySerial automatisch in den
richtigen Pseudodateinamen umgesetzt.

Das erste try-except sollte das Öffnen der Schnittstelle umschließen,
sonst steigt das Programm im Fehlerfall dort schon aus, ohne die von dir
vorgesehene Fehlermeldung auszugeben. Die Abfrage ser.isOpen() kannst du
dir dann sparen.

Die prints in den except-Zweigen sind beide fehlerhaft: Im ersten Fall
ist die Variable e undefiniert, im zweiten Fall hat die str-Funktion
kein Argument und liefert somit immer den Leerstring zurück.

Hier ist eine korrigierte Fassung des PRogramms:
1
import serial
2
import sys
3
import threading
4
import re
5
import time
6
7
try:
8
    ser = serial.Serial( port=0,
9
                         baudrate=115200,
10
                         bytesize=serial.EIGHTBITS,
11
                         parity=serial.PARITY_NONE,
12
                         timeout=20000 )
13
    print ("Serial port is open")
14
except Exception as e:
15
    print ("error open serial port: " + str(e))
16
    exit()
17
18
try:
19
    ser.write(b'\r')
20
    ser.write(b'reboot')
21
    print("write data: reboot")
22
except Exception as e:
23
    print ("error communicating...: " + str(e))

von Max (Gast)


Lesenswert?

Hi,
hab dies nun auch angepasst. Danke!

von Max (Gast)


Lesenswert?

Hallo Leute,
vieleicht noch eine kurze Frage:
Wie ist es in Python3 das lesen vom COM Port möglich?

ser.read('Waiting for connection','r')

anscheinend funktioniert es so nicht!

Gruß
Max

von Yalu X. (yalu) (Moderator)


Lesenswert?

Max schrieb:
> ser.read('Waiting for connection','r')
>
> anscheinend funktioniert es so nicht!

Wie kommst du darauf, dass das funktionieren könnte?

Die read-Methode erwartet 1 Integer-Argument, nämlich die Anzahl der zu
lesenden Bytes. Man darf dieses Argument auch weglassen, dann wird ein
Default von 1 genommen. Du übergibst stattdessen aber 2 Strings. Was
möchtest du damit überhaupt bezwecken?

Hier ist noch die Doku zu read:

1
Help on method read in module serial.serialposix:
2
3
read(self, size=1) method of serial.serialposix.Serial instance
4
    Read size bytes from the serial port. If a timeout is set it may
5
    return less characters as requested. With no timeout it will block
6
    until the requested number of bytes is read.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.