Seite 1 von 1

long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 16:47
von hr3
Hallo,
ich möchte Daten zwischen Raspi und Arduino per I2C austauschen. Hier geht es um den Python-Teil.

Ich verwende bus.write_i2c_block_data() und bus.read_i2c_block_data(). (Third argument must be a list of at least one, but not more than 32 integers)

Code: Alles auswählen

lo = long(4294967295)
buf = [0] * 4
buf[0] = lo         & 0xFF
buf[1] = (lo >>  8) & 0xFF
buf[2] = (lo >> 16) & 0xFF
buf[3] = (lo >> 24) & 0xFF
Damit funktioniert es für long. Für byte ist es einfach und für 2Byte habe ich etwas ähnliches.

Alternativ habe ich es jetzt mit pack/unpack probiert, bekomme dabei aber direkt keine Liste, sodaß ich mit list() nachbearbeiten muß. Alles nicht sehr elegant.

Gibt es einen einfachen Weg mit jeweils einer einzigen Anweisung?

Auf der Arduino-Seite (c++) verwende ich z.B. memcpy() und (byte*)&lo.

Re: long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 16:51
von __deets__
Hast du mal probiert, was passiert, wenn du direkt den von struct gelieferten byte-string als Argument verwendest? Ansonsten ist ein list(b"abc") halt noetig :K

Re: long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 16:55
von hr3
'\xff\xff\xff\xff'
führt zu
TypeError: Third argument must be a list of at least one, but not more than 32 integers

Es muß ja auch nicht per pack/unpack sein. Ich suche einfach nach dem elegantesten Weg einen long-Wert in eine 4-Byte-Liste und umgekehrt zu konvertieren.

Re: long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 17:10
von __deets__
Na, das ist schon durchaus struct. Dann muss halt eine list drumrum:

list(struct.pack("IIII", (100, 22, 40, 0)))

Ungetestet. Aber du verstehst die Idee bestimmt.

Re: long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 17:28
von hr3
Danke.
An der Stelle bin ich ja gerade.
Damit bekomme ich z.B. ['\xff', '\xff', '\xff', '\xff']
brauche aber [0xff, 0xff, 0xff, 0xff]
Alles kein Problem.
Eine Erfahrung bei z.B. c++ ist, dass es viel Möglichkeiten gibt zum Ziel zu kommen und ich immer wieder überrascht bin, was Experten dabei aus dem Hut zauben. Das wird bei Python sicher ähnlich sein.
Beschäftige mich jetzt schon ein paar Tage mit dem Problem und fange an im Kreis zu denken, weil es immer zwei Umgebungen in unterschiedlichen Sprachen sind.

Re: long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 17:30
von __deets__
Welche Python Version benutzt du denn? Denn fuer mich ist das mit Python 3 ein BytesObjekt, und das ist dann schon eine Liste von Nummern.

Wenn du Python zwei benutzt, koenntest du statt List zB

map(ord, struct.pack(...))

benutzen.

Re: long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 18:23
von hr3
Python 2.7.13

Code: Alles auswählen

lo = 4294967295

var = struct.pack('L', lo)
print('pL:',var,len(var),type(var))
dat = struct.unpack('L', var)
print('uL',dat,len(dat),type(dat))

var = map(ord, struct.pack('L', lo))
print('pL:',var,len(var),type(var))
dat = struct.unpack('L', var)
print('uL',dat,len(dat),type(dat))
  • ('pL:', '\xff\xff\xff\xff', 4, <type 'str'>)
    ('uL', (4294967295L,), 1, <type 'tuple'>)
    ('pL:', [255, 255, 255, 255], 4, <type 'list'>)
    Traceback (most recent call last):
    File "/etc/openhab2/scripts/tmp1.py", line 31, in <module>
    dat = struct.unpack('L', var)
    struct.error: unpack requires a string argument of length 4
Danke, Schritt 1 funktioniert.
Gibt es für Schritt 2 auch so eine schöne Lösung?

Re: long zu char[] und zurück

Verfasst: Freitag 2. Februar 2018, 19:05
von hr3
Damit scheint es zu funktionieren.

Code: Alles auswählen

dat = struct.unpack('L', bytearray(var))
Hat jemand eine bessere Lösung?

Re: long zu char[] und zurück

Verfasst: Samstag 3. Februar 2018, 17:23
von Sirius3
@hr3: das ist doch schon eine gute Lösung.