17

serial.write() method in pyserial seems to only send string data. I have arrays like [0xc0,0x04,0x00] and want to be able to send/receive them via the serial port? Are there any separate methods for raw I/O?

I think I might need to change the arrays to ['\xc0','\x04','\x00'], still, null character might pose a problem.

Artem Zankovich
  • 2,269
  • 20
  • 36
Atilla Filiz
  • 2,355
  • 8
  • 28
  • 43

3 Answers3

12

An alternative method, without using the array module:

def a2s(arr):
    """ Array of integer byte values --> binary string
    """
    return ''.join(chr(b) for b in arr)
Eli Bendersky
  • 248,051
  • 86
  • 340
  • 401
11

You need to convert your data to a string

"\xc0\x04\x00"

Null characters are not a problem in Python -- strings are not null-terminated the zero byte behaves just like another byte "\x00".

One way to do this:

>>> import array
>>> array.array('B', [0xc0, 0x04, 0x00]).tostring()
'\xc0\x04\x00'
dF.
  • 71,061
  • 29
  • 127
  • 135
1

I faced a similar (but arguably worse) issue, having to send control bits through a UART from a python script to test an embedded device. My data definition was "field1: 8 bits , field2: 3 bits, field3 7 bits", etc. It turns out you can build a robust and clean interface for this using the BitArray library. Here's a snippet (minus the serial set-up)

from bitstring import BitArray

cmdbuf = BitArray(length = 50)     # 50 byte BitArray
cmdbuf.overwrite('0xAA', 0)       # Init the marker byte at the head

Here's where it gets flexible. The command below replaces the 4 bits at bit position 23 with the 4 bits passed. Note that it took a binary bit value, given in string form. I can set/clear any bits at any location in the buffer this way, without having to worry about stepping on values in adjacent bytes or bits.

cmdbuf.overwrite('0b0110', 23)

# To send on the (previously opened) serial port 
ser.write( cmdbuf )
jbartas
  • 191
  • 1
  • 4