long zu char[] und zurück

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
hr3
User
Beiträge: 15
Registriert: Freitag 26. Januar 2018, 17:48

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.
Zuletzt geändert von hr3 am Freitag 2. Februar 2018, 17:08, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

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
hr3
User
Beiträge: 15
Registriert: Freitag 26. Januar 2018, 17:48

'\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.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
hr3
User
Beiträge: 15
Registriert: Freitag 26. Januar 2018, 17:48

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.
Zuletzt geändert von hr3 am Freitag 2. Februar 2018, 17:30, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
hr3
User
Beiträge: 15
Registriert: Freitag 26. Januar 2018, 17:48

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?
hr3
User
Beiträge: 15
Registriert: Freitag 26. Januar 2018, 17:48

Damit scheint es zu funktionieren.

Code: Alles auswählen

dat = struct.unpack('L', bytearray(var))
Hat jemand eine bessere Lösung?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@hr3: das ist doch schon eine gute Lösung.
Antworten