Jump to content

Byte strings in RS485 Bricklet


lspgl

Recommended Posts

Hi

 

Ich versuche einen Bytestring in Python3.X mit dem RS485 Bricklet zu übertragen.

Der call an

rs485.write(send_array)

ergibt mir jedoch einen Fehler wenn das send_array kein String ist, z.B.

b'\x02\x00\x00\x01\x00\xd1'

 

Der Fehler lautet:

  File "/usr/local/lib/python3.6/site-packages/tinkerforge/ip_connection.py", line 1032, in pack_string
    return struct.pack('<' + f, d)
struct.error: char format requires a bytes object of length 1

 

Der Beitrag unter https://www.tinkerunity.org/forum/index.php?topic=1355.0 zeigt ein ähnliches Problem für das IO16 Bricklet. Kann es sein, dass dies das selbe Problem ist und noch nicht für alle Bricklets gefixt wurde?

 

L

Link to comment
Share on other sites

Oh, da hat sich in der Tat ein Fehler in der neuen Streaming API bei Python3 eingeschlichen (Python2 ist da weniger strikt und es funktioniert einfach). Vielen Dank für den Hinweis!

 

Wir fixen das mit dem nächsten Bindings-Release, so dass man auch ein bytes-Objekt übergeben kann.

 

In der Zwischenzeit kannst du als Workaround das hier verwenden:

rs485.write(list(map(chr, send_array)))

Link to comment
Share on other sites

  • 3 weeks later...

Hi nochmals,

 

Es sieht danach aus, als ob dieser Fix noch nicht ganz vollständig ist.

In meiner Anwendung sehe ich, dass ein byte welches grösser als 128 ist, nicht korrekt übertragen werden. Kann es sein, dass dies mit der ASCII range zu tun hat (0-127)? Da in Python 3 unichr und chr zusammengelegt wurden könnte es sein, dass eine andere map notwendig ist um auch bytes in der oberen hälfte der range (128 - 255) zu übertragen.

 

Edit:

Hat sich erledigt - Das Problem liegt daran, dass bei UTF-8 bei bytes > 128 ein \xc0 Byte prepended wird. Sobald man sich um dieses kümmert funktioniert alles so wies soll.

Link to comment
Share on other sites

Edit:

Hat sich erledigt - Das Problem liegt daran, dass bei UTF-8 bei bytes > 128 ein \xc0 Byte prepended wird. Sobald man sich um dieses kümmert funktioniert alles so wies soll.

 

Teste mal bitte die angehängte Version der Python Bindings. Die braucht jetzt keine UTF-8 Trickserei mehr. Dort ist die ganze Behandlung für Strings und Listen von Chars überarbeitet und verbessert worden.

 

Strings und Listen von Chars werden jetzt als jegliche listenartige Darstellung von Bytes (0-255) angenommen:

 

- str, wird intern mittels

map(ord, string)

in eine Liste von Bytes (0-255) umgewandelt

 

- bytes und bytearray

 

- list mit ints im Bereich 0-255

 

- list mit 1-Zeichen langen str, wobei wiederum ord intern zur Umwandlung verwendet wird

 

- list mit 1-Element langen bytes oder bytearray

 

Für die Umwandlung zwischen der internen Protokolldarstellung als Liste von Bytes und der str Darstellung der Python Bindings wird nur ord/chr verwendet. Die Kombination funktioniert in Python 2 und 3 ohne Problem für alle Werte von 0 bis 255. Es wird keinerlei UTF Kodierung mehr verwendet.

 

Wenn dir die Bindings Strings und Listen von Chars per Getter/Callback zurückgeben, dann wird ein String als str zurückgegeben der per

"".join(map(chr, list_of_bytes))

aus eine Liste von Bytes zusammengebaut wurde. Ähnlich wird eine Liste von Chars als [chr(b) for b in list_of_bytes] zurückgegeben.

 

Dadurch funktioniert jetzt auch dein Beispiel aus dem ersten Post direkt:

 

rs485.write(b'\x02\x00\x00\x01\x00\xd1')

tinkerforge_python_bindings_2_1_14_0e494eae3a34499.zip

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...