2

I am trying to send and receive rs232 data using pyserial but I don't understand how to properly send the correct data. What little information I have explains the data string and says that it should be split into high and low nibbles. The converting to nibbles is that part I don't get, I tried to read up on it but don't get how to do use it for my case.

So I have this Data string to send over serial. 10,00,00,00,00,00,16,0A,20,20,20,20,00,00,00,00,00,00,00,00,50

It says to split the bytes into high and low nibbles, the 21 bytes are then converted into a data string of 42 characters.

Could someone help explain how to do this for me?

Spacefigher
  • 45
  • 1
  • 1
  • 5
  • 1
    Besides not having tried, this sounds like homework? – vallentin Mar 20 '17 at 05:02
  • Unfortunately I have tried but don't fully understand enough to make it work. I sort of get how it goes to a high and low byte but is it each character? So "ab" would have 2 bytes for a and 2 for b? That is probably wrong so that's why I asked for help. I wish it was homework and had a teacher I could just ask. – Spacefigher Mar 20 '17 at 16:48
  • Take a look at my answer – vallentin Mar 21 '17 at 08:13

2 Answers2

12

If you wanted to get the high and low nibble of a byte. In other words split the 8-bits into 4-bits.

Considering the data string is a string of bytes as hexadecimals, then you could simply do:

high, low = byte[:1], byte[1:2]
print(high, low)

Which for byte = "16" would print 1 6. You can then use int(high, 16) and int(low, 16) to convert it to decimals.

If you've already converted the hexadecimal into a decimal using int(byte, 16) then you can extract the high and low nibble by doing:

high, low = byte >> 4, byte & 0x0F
print(hex(high), hex(low))

Which for byte = 0x16 would print 0x1 0x6 because they're converted back to hexadecimals using hex(x). Note that hex(x) adds a 0x prefix. You can remove it by doing hex(x)[2:].

So considering your data string as:

bytes = "10,00,00,00,00,00,16,0A,20,20,20,20,00,00,00,00,00,00,00,00,50"

Then to print each high and low nibble could be done with something like this:

bytes = "10,00,00,00,00,00,16,0A,20,20,20,20,00,00,00,00,00,00,00,00,50"
bytes = bytes.split(",")

for byte in bytes:
    byte = int(byte, 16)
    high, low = byte >> 4, byte & 0x0F

    print(hex(byte), hex(high), hex(low))

Which yields the byte, high nibble and low nibble all in hexadecimals.

Also if you have it in bits ("{0:08b}".format(byte)) then you can split it like this high, low = bits[:4], bits[4:8], now high, low each having their 4-bits.

vallentin
  • 23,478
  • 6
  • 59
  • 81
2

I don't know if an answer will help you now, but you can also solve this with a so called bit mask

for example split each char from a string in it's high nibble (hl) and low nibble (ln) with python:

input_text = "a fucking amazing input text"
for c in input_text:
  print(bin(ord(c)))
  nh = ord(c) & 0x0F
  nl = ord(c) >> 4 & 0x0F
  print("nh: " + bin(nh))
  print("nl: " + bin(nl))

Why 0x0F, it's 00001111

For example:

Mask: 00001111 (0x0F) Value: 11010101 Result: 00000101

Hope that is still helpfull.

doc.aicdev
  • 96
  • 8