Auf COM senden, sonderbare Ergebnisse

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.
Antworten
joedro
User
Beiträge: 3
Registriert: Freitag 30. Juli 2021, 17:41

Guten Tag,

ich wollte via seriell.write(data) Binärdateien auf dem COM-Port ausgeben.

Meine Ergebnisse sind:
5bit senden wird nicht unterstützt, kann man aber Konfigurieren.
50Bd funktioniert sogar, das hatte mich erstaunt.
Dagegen wird 1.5 bei Stopbit nicht unterstützt.
Beim versenden, wie im Test-Script, von Binärdaten
wird anstatt "0x1f" 31 mal 0x00 ausgegeben.
Das habe ich Oszllographisch ermittelt.
Einen Blick in die Bibliothek zu SERIAL konnte ich den Hintergrund nicht ermitteln.

Was habe ich falsch konfiguriert oder wie muß ich das serial.write( .... )
ansprechen - so das die binärdaten ausgegeben werden.

Hintergrund ist ich will einen Lochstreifenstanzer 5/6/7/8 bit ansprechen.

Schon mal ein großes Dankeschön,

Jörg

Das Test-Script:

Code: Alles auswählen

import serial

ser = serial.Serial()
ser.baudrate = 1200 # 50 bd funktioniert
ser.port ='COM1'
ser.parity = 'N'
ser.bits = 8      # keine 5 bit sondern 8 bit
ser.stopbits = 2  # 1.5 Funktioniert nicht, STOPBITS_ONE_POINT_FIVE
ser.open()
variabel = 0x1f
#ser.write(B'HALLO')
i = 0
print(ser.write(B'BA')) # rückgabe 2
print(ser.write(0x1f))  # rückgabe 31, sendet 31 * 0x00
ser.close()
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit Python hat das nichts zu tun. Sondern mit den Fähigkeiten deines seriellen Geräts im/am Computer. Viele unterstützen das einfach nicht. Wenn du keine findest, die das tun, dann würde ich das einfach mit einem Microcontroller “von Hand” bitbangen.
joedro
User
Beiträge: 3
Registriert: Freitag 30. Juli 2021, 17:41

Guten Tag,
das "bitbangen" habe ich, wie bereits gschrieben, per Oszilliskop durchgeführt.
Das Senden der Zeichen "BA" erfolgt auf der seriellen Schnittstelle korrekt.
Während das senden eines Bytes, im Beispiel 0x1f, wird diese nicht gesendet sondern als Zähler - der dann 31 mal die 0x00 sendet!
Da es zwischen beiden Ausgaben einen signifikanten Unterschied gibt, kann es nur in der Umsetzung in Python liegen!
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@joedro: Naja, es liegt im Grunde an Dir/Deinem Aufruf. Wenn Du eine *Zahl* übergibst, dann bedeutet das „schreibe so viele 0 Bytes“. Wenn Du ein Byte mit dem Wert 0x1f senden willst, dann musst Du ein `bytes`-Objekt mit diesem Bytewert übergeben: ``write(b"\x1f")``. Denn `write()` versucht die übergebenen Daten mit der `serial.to_bytes()`-Funktion in Bytes umzuwandeln. Das geht mit ganzen Zahlen (gibt die Anzahl der 0-Bytes an), `bytes`, `memoryview`, `bytearray`-Objekten, und Listen mit Zahlen.

Code: Alles auswählen

In [303]: serial.to_bytes(0x1f)                                                 
Out[303]: b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

In [304]: len(serial.to_bytes(0x1f))                                            
Out[304]: 31

In [305]: serial.to_bytes(b"\x1f")                                              
Out[305]: b'\x1f'

In [306]: len(serial.to_bytes(b"\x1f"))                                         
Out[306]: 1

In [307]: serial.to_bytes([0x1f])                                               
Out[307]: b'\x1f'
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Das liegt daran, dass `write` mit unterschiedlichen Typen unterschiedlich umgeht. Es wird versucht, den Parameter in ein bytearray umzuwandeln.
bytearray(iterable_of_ints) -> bytearray
bytearray(string, encoding[, errors]) -> bytearray
bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer
bytearray(int) -> bytes array of size given by the parameter initialized with null bytes
Du willst also eigentlich

Code: Alles auswählen

from serial import Serial
with Serial(baudrate=1200, port='COM1', parity='N', bits=8, stopbits=2) as serial:
    print(serial.write(b'BA'))
    print(serial.write([0x1f]))
joedro
User
Beiträge: 3
Registriert: Freitag 30. Juli 2021, 17:41

Danke für die Antworten,

ich bezog mich auf die Beschreibungen: Seriel und PySer.
Das war dort nicht ausreichend beschrieben.

Jörg
Antworten