How to transform byte integers into the Python language?

1

I'm using the pyserial module to send serial data, so I have a list of values like:

Valores = [10,20,30,40,50,60,70,80,90,100]

I need to convert the values of the list into bytes to be able to send, because if I try to send it like this:

Serial.write(Valores)

Or so:

Serial.write(10)

I get this error:

File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 518, in write
    d = to_bytes(data)
  File "/usr/lib/python3/dist-packages/serial/serialutil.py", line 61, in to_bytes
    for item in seq:
TypeError: 'int' object is not iterable

But if you submit as the line below works!

Serial.write(b'10')

How can I do this conversion of values?

    
asked by anonymous 19.01.2018 / 18:50

2 answers

4

In Python 3 the built-in "bytes" itself does this:

>>> bytes([40,10,20,30])
b'(\n\x14\x1e'

In Python 2, what are "bytes" today was the equivalent of strings. However in Python 3 they separated: strings are objects containing text, where each element is a unicode codepoint - and does not matter its numeric value, and the old "byte-string" was known as bytes, and it works as in C: if a value has an ASCII representation (numeric value from 32 to 128), it is printed, otherwise it will be printed with the hexadecimal two-digit encoding. Internally, it is just a numeric sequence of bytes, and is already the type supported by all relevant functions that handle the serial port.

In the case of your examples specifically, you can do:

serial.write(bytes((10,))

( (10,) is a tuple of a single number - the final comma is not optional.

Or:

serial.write (b "\ x0a")

The prefix "b" for the quotation marks indicates that it is a literal of bytes, not text - and you can place numbers directly in the hexadecimal notation inside the quotation marks.

While you are using serial communication, you may have to send data records with multiple fields of predetermined size. In this case, you can use the "struct" module that comes with Python: it transforms a sequence of parameters into a bytes object in the correct order according to a format string - link

For example, if you have to send two unsigned 16-bit numbers, followed by a 32-bit floating-point number:

>>> struct.pack("<HHf", 40000, 50000, 3.28)
b'@\x9cP\xc3\x85\xebQ@'    

To extract the numbers of an object of type bytes, just use it as a normal sequence. In Python 3 an element of a sequence of bytes is an unsigned 8-bit number:

>>> a = b"minha_resposta:\xff"
>>> print(list(a))
[109, 105, 110, 104, 97, 95, 114, 101, 115, 112, 111, 115, 116, 97, 58, 255]

In Python 2 you need to explicitly convert the byte element to integer - and you can use the ord function to do this:

Python 2.7.14 (default, Jan 17 2018, 14:28:32) 
>>> a = b"minha_resposta:\xff"
>>> print(list(a))
['m', 'i', 'n', 'h', 'a', '_', 'r', 'e', 's', 'p', 'o', 's', 't', 'a', ':', '\xff']
>>> print(map(ord, a))
[109, 105, 110, 104, 97, 95, 114, 101, 115, 112, 111, 115, 116, 97, 58, 255]
    
19.01.2018 / 19:05
3

You can do:

print((65).to_bytes(1, byteorder='big'))

to_bytes() documentation.

If the preference is to do with a list use this:

bytes([10,20,30,40,50,60,70,80,90,100])

bytes() documentation.

See running on ideone . And no Coding Ground . Also put it in GitHub for future reference .

    
19.01.2018 / 19:05