Non-POSIX parity (mark/space) with Python-Serial on Linux.

David Riley fraveydank at gmail.com
Mon Nov 21 12:22:28 EST 2011


On Nov 21, 2011, at 11:52 AM, Matthew Lenz wrote:

> Ahh. Ok.  So how would I go about doing that with python?  I think in perl (sorry for the naughty word) I could use the tr// (translate) but is there a quick way to do so with python?  Is it going to be necessary to convert commands I SEND to the device or only convert what I receive?

The high-level overview is that you'll want to OR in 0x80 on transmit, and AND 0x7F on receive (thus inserting the high bit when you send it out and removing it when you receive).  If you wanted to be extra-sure you're receiving things correctly, you should also check to see if your value ANDed with 0x80 is not zero.

In Python 2.x, as mentioned, when you iterate over a string, you get a bunch of tiny one-character strings, which you then need to convert into numbers with ord() and back into strings with chr() when you re-concatenate it.  ord() and chr() may be familiar to you from Perl.  For example, you could do this on reception:

----

# However you get your data out of serial
received_str = receive_my_string()

ord_str = [ord(x) for x in received_str]

# An exception may be extreme in this case, but hey.  Note that
# the filter() function actually returns a list of all the
# characters that don't have the high bit set, so you could
# actually use that if you wanted to.
if filter((lambda x: x < 0x80), ord_str):
   raise IOError("Received character without mark parity")

return "".join([chr(x & 0x7F) for x in received_str])

----

In Python 3.x, iterating over a bytes array (which is, hopefully, what your serial interface returns) will give you a bunch of ints, so you shouldn't need to do the conversions:


----

# However you get your data out of serial
received_bytes = receive_my_string()

# In Python 3.x, filter() returns an iterator, which is generally a
# better thing to return, but doesn't test as nicely for a bool.
for b in received_bytes:
   if b < 0x80:
       raise IOError("Received character without mark parity")

# None of this "".join() nonsense with byte arrays!
return bytes([(x & 0x7F) for x in received_bytes])


----


There are surely more efficient ways to do what I've typed up there, but those should work pretty well for whatever you're looking to do.  For sending, you pretty much want to swap (x & 0x7F) with (x | 0x80) to insert that high bit.


- Dave





More information about the Python-list mailing list