python convert bit hex to binary - python

ok, im fairly new to python but not programming, I know php, C, bash, etc... My question is:
How do I convert data = "b'\x16'" to binary "0001 0110" ??
im trying to read the response from an esc printer from DLE
x = 1
while x:
time.sleep(3)
ser.write("\x10\x04\x01".encode())
bytesToRead = ser.inWaiting()
data = ser.read(bytesToRead)
while data:
print(data)
data = ""
all that ends up printing is: b'\x16' i assume hex but a simple hex to bin is not working because of the b?

What you get back is a bytes object. (think: raw array of bytes) You can get the number itself from the first byte via data[0]. That will give you 0x16 as an int, which you can convert however you want.

Related

Recording binay data with pyserial and convert the data back to a readable output

I am trying to record binary sensor data with pyserial and convert it back to a readable output.
I recorded the data as a bytearray. This is a short example:
bytearray(b'~P\x1a\x004>e\x7f!>\xa2\xfa\x1dA\xff\x05]\xbd\xf5\xe6\x88\xbc!\x8eL\xbc1\xd5IV~Q\x1a\x004>bC\x1b>^j\x1dA00\xee<\xba\xf8\x88\xbb!\x8e\x00\x00\x00\x00O\xc7~R\x1a\x009>\x98k\x1a>Y\xf2\x1dA\x0f\x14*=\xa9\xb1\x88\xbb!\x8e\xaa<\xa9\xb1\xe38~S\x1a\x00;>\xa9\x0f\x19>HN\x1dA>\x02\x99=\xe4\x9f\xee\xbc\xba\xf8\x88;!\x8e\xa5~T\x1a\x00>>\xccW\x1c>j\x96\x1cA\xae\xfb\x88\xbc!\x8e\x88;!\x8e\x08\xbd!\x8e\xb1%~U\x1a\x006>x_\x19>HN\x1dA\xaf\x19\x88\xbc!\x8e\x08\xbd!\x8e\xaa\xbc\xa9\xb1<c~V\x1a\x004>e\x7f\x15>#\xca\x1dA00\x80=>\x05\xcc\xbc1\xd5\x88;!\x8eZ\x05~W\x1a\x00<>\xbb\xb3\x17>6\xaa\x1dAP.\x88\xbb!\x8e\xaa<\xa9\xb1*=\xa9\xb1(;~X\x1a\x00?>\xdd\xfb!>\x9e\x82\x1dA_\x0f\x88\xbc!\x8e\x08\xbd!\x8e\x08\xbc!\x8es\x1f~Y\x1a\x00A>\xf1\xdb\x1e>\x80\xb2\x1cA\xae\xfb\x88\xbb!\x8e\x08<!\x8e\x08\xbd!\x8e\xc0\xde~Z\x1a\x00;>\xa9\x0f\x14>\x11&\x1cAn\xff\x08<!\x8e\x88;!\x8e\x08\xbc!\x8e>:~[\x1a\x00;>\xa9\x0f\x10>\xed\xa1\x1dA\xa0)\x08<!\x8e\xee\xbc\xba\xf8;\xbdm\xc3\x1a\x10~\\\x1a\x00A>\xf1\xdb\x19>E\x12\x1dA0!L\xbc1\xd5\x08\xbc!\x8e\x08<!\x8e\xd3\x0f~]\x1a\x003>V\x17\x10>\xed\xa1\x1dA\xc16\x88;!\x8e\xcc<1\xd5\x88\xbc!\x8e\x07\x05~^\x1a\x00A>\xf1\xdb\x10>\xeae\x1cA\x1e\xf5\xee\xbc\xba\xf8\x08<!\x8e\x88;!\x8e\x8dh~_\x1a\x00<>\xbb\xb3\x12>\xfeE\x1dA\xff\x05\x88<!\x8e\x08\xbd!\x8e\x19=\xe4\x9f\xcfd~\x1a\x004>g\xbb\x10>\xed\xa1\x1dA "\x08\xbc!\x8e\x08\xbc!\x8e\xaa\xbc\xa9\xb1M\xc8~a\x1a\x009>\x98k\x12>\xfb\t\x1dA0!\x00\x00\x00\x00\x08<!\x8e\x88\xbb!\x8e\x12\xb4~b\x1a\x008>\x8a\x03\x1c>j\x96\x1dA\xef\x15]\xbd\xf5\xe6\x19=\xe4\x9f\x08\xbd!\x8e\xa3Z~c\x1a\x007>\x85\x8b\x12>\x00\x82\x1dA>\x02\x08<!\x8e\xcc<1\xd5\x08\xbc!\x8e\x84\x11~d\x1a\x00<>\xbb\xb3\x13>\x0f\xea\x1cAn\xff\x08<!\x8e\xcc\xbc1\xd5*=\xa9\xb1#6~e\x1a\x00<>\xbd\xef\x14>\x11&\x1dA\xef\x15\x88\xbb!\x8e\x88\xbc!\x8e\x88\xbb!\x8e\xcc\xa9~f\x1a\x00>>\xccW\x1c>j\x96\x1dA\x0f\x14\x80\xbd>\x05\x88<!\x8e\xcc<1\xd5Y\xe1~g\x1a\x00E>\x13$!>\xa0\xbe\x1dA\xb0(\xaa\xbc\xa9\xb1*=\xa9\xb1\xee<\xba\xf8R\xa1~h\x1a\x00#>\xe07\x19>HN\x1dA\xe04\xee<\xba\xf8\xee<\xba\xf8\x88;!\x8eI3~i\x1a\x00<>\xbd\xef\x19>HN\x1dAO\x10*=\xa9\xb1L<1\xd5\xee<\xba\xf8$f~j\x1a\x00#>\xe07%>\xc5B\x1cA\xae\xfb\x88;!\x8e\x08\xbc!\x8eL\xbc1\xd5\xa4\x12~k\x1a\x004>bC)>\xec\x02\x1cAn\xff\x88\xbc!\x8e*=\xa9\xb1\x08\xbc!\x8e\xe0\xb1~l\x1a\x00->\x1d\xb3,>\x0fK\x1dA\xcf\x08\x00\x00\x00\x00\x08<!\x8e\xee<\xba\xf8\x8b\x15~m\x1a\x00,>\x0c\x0f">\xa7r\x1dA\xef\x06L<1\xd5\xcc\xbc1\xd5\x08<!\x8e\x1eA~n\x1a\x005>q\xab >\x91V\x1cAm\xe1\xcc<1\xd5\x08=!\x8e\xcc\xbc1\xd5\xb4\x8d~o\x1a\x00,>\x0c\x0f.>"+\x1dA\x8f\x1b]\xbd\xf5\xe6\xaa\xbc\xa9\xb1;\xbdm\xc3\xcaN~p\x1a\x004>bC">\xa56\x1dAN\x01\x08<!\x8e\x88\xbc!\x8e\x19=\xe4\x9f\n')bytearray
Now I need to convert the data back to a readable out. The structure should look like:
Byte: SYNC = 0x7E
Byte = sample counter 0...255
Byte = Package length
Followed by:
3 * float_32 (IACC) -> Sensor1
3 * float_32 (IOMG) -> Sensor2
2 Byte CRC16
Thank your for the help.

Base64 implementation is not giving the desired result

I've followed the following site instructions in order to implement base64 encoding.
Here's my code:
from bitarray import bitarray
from bitarray.util import ba2int
base64mapping = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcd\
efghijklmnopqrstuvwxyz0123456789+/"
testString1 = "49276d206b696c6c696e6720796f757220627261696e206c\
696b65206120706f69736f6e6f7573206d757368726f6f6d"
stringBits = bitarray()
# We create an unitialized bitarray
stringBits.frombytes(testString1.encode('utf-8'))
# We convert the string to bits
b64stringList = [] # To store the corresponding b64 chars
for sequence in range(0, len(stringBits), 6):
# We scan the bitarray 6 bits at a time
b64stringList += base64mapping[(ba2int(stringBits[sequence:sequence+6]))]
# We store the corresponding b64 char into b64stringlist
print(''.join(b64stringList)) # Lets see the result
The testString1 was taken from the cryptopals set 1 - challenge 1 which tells me the result should be:
SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t
However, my implementation gives another result:
NDkyNzZkMjA2YjY5NmM2YzY5NmU2NzIwNzk2Zjc1NzIyMDYyNzI2MTY5NmUyMDZjNjk2YjY1MjA2MTIwNzA2ZjY5NzM2ZjZlNmY3NTczMjA2ZDc1NzM2ODcyNmY2ZjZk
I checked against Wikipedia's example and I get the same output sans the padding at the end (TODO).
What I am doing wrong or missing here?
According to the site, the task is to convert the hex to base64.
Your encoding, seems to be working correctly as the library base64 outputs the same as your result when running it directly over the hex value
t = b'49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d'
base64.b64encode(t)
b'NDkyNzZkMjA2YjY5NmM2YzY5NmU2NzIwNzk2Zjc1NzIyMDYyNzI2MTY5NmUyMDZjNjk2YjY1MjA2MTIwNzA2ZjY5NzM2ZjZlNmY3NTczMjA2ZDc1NzM2ODcyNmY2ZjZk'
Using binascii we can convert the hex value your originally have to readable text by using unhexlify()
binascii.unhexlify(t)
#b"I'm killing your brain like a poisonous mushroom"
Given this information it would be best to take the approach that what you're storing is not a string but a hex representation of the string itself.
Due to this we will need to convert your hex to the readable string before encoding it.
When we pass the resulting string to base64 your output matches the expected output in the link.
base64.b64encode(binascii.unhexlify(t))
#b'SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t'

how to convert integer to binary for serial port

I am trying to send a value over serial port. I am unsure how to convert it into the correct format. I tried bin() for binary and format() but it didn't work.
result = 2
ser.open()
ser.write(b'1')
time.sleep(3)
ser.write(result) # wrong format
ser.write("{0:b}".format(result)) # TypeError: unicode strings
# are not supported, please
# encode to bytes: '10'
The first write operation sends '1' as binary string. Now I want the variable to be send as binary string as well.
write() requires a bytes object.
>>> help(serial.Serial.write)
Help on function write in module serial.serialwin32:
write(self, data)
Output the given byte string over the serial port.
To convert an integer to bytes, call int.to_bytes().
>>> result = 2
>>> b = result.to_bytes(4, 'little')
>>> b
b'\x02\x00\x00\x00'
>>> # to convert back to an integer
>>> int.from_bytes(b, 'little')
2
Like this :
import binascii
def write(num):
pack = binascii.unlexlify("%04X"%num)
ser.write(pack)
Important point: Which number system used on device (8,16,32,64 bit) ?
8 Bit = 1 Byte(0-255)
16Bit = 2 Byte(0-65535)
32Bit = 4 Byte(like upside)(0-4294967295)
All ranges are UNSIGNED(look up), but float
got extra definition !
You can't type binary 1 value with keyboard :
binascii.unlexlify("%01X"%1) so equal to \x01 (of course you can use struct package)
write() method accepts a string parameter. You can convert result to string with str() builtin function like this.
result = str(result)
Python 2:
result = 2
ser.open()
ser.write(b'1')
time.sleep(3)
ser.write(str(result))
Python 3:
You have to encode string in bytes.
result = 2
ser.open()
ser.write(b'1')
time.sleep(3)
ser.write(str(result).encode('utf-8'))

Decode data from nextion display [python]

I am trying to communicate with a nextion display over serial in python. Here is my code so far:
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
EndCom = "\xff\xff\xff"
ser.write('n0.val'+EndCom)
That should tell the nextion to return the value of n0, which is 4.
ser.inWaiting() returns 4.
ser.read(4) returns '\x00\xff\xff\xff'.
I am unable to decode this.
Use struct.unpack which unpacks strings according to a given format. In this case your format will be 'i' which means 4 bytes integer.
>>> import struct
>>> result = struct.unpack('i', '\x00\xff\xff\xff')
>>> result[0]
-256
From the docs:
The result is a tuple even if it contains exactly one item.
The code should read:
ser.write('get n0.val'+EndCom)
What I had before was not returning the correct value.

Python 2.7.6 Optimizing code for packing big endian bytes into a string

import struct
varA['Z']['value'] = 8700
varA['Y']['value'] = 8800
varA['X']['value'] = 8900
varA['W']['value'] = 8800
varA['V']['value'] = 8700
varB = ""
varC = ""
for name in 'Z Y X W V'.split(' '):
varB = C[name]['value']
varC += str(struct.pack('>h',varB))
print varC[:-1] + '\n'
What i need is a string of bytes,
where each number is a signed int16 big-endian byte(s).
this code here works for what im trying to do, but i know
theres a far more elegant solution.
I wouldn't spend any time on optimizing the varA as its
only there to set up the code and won't be used in my project.
Also the print is also there to set up the problem, im actually
sending the bytes as a socket.
Initially I had this in an array first few times, but when I converted the
array to a bytearray, I kept running into having 0x00 mixed in.
Same with struct, as you can see in my solution removing the
0x00 at the end.
Here's a simpler way to do it. It's unclear from the question whether this is exactly the result you desire.
values = [varA[name]['value'] for name in 'ZYXWV']
varC = struct.pack('>'+str(len(values))+'h', *values)

Categories

Resources