Take the 2-minute tour ×

I am using pyserial and need to send some values less than 255. If I send the int itself the the ascii value of the int gets sent. So now I am converting the int into a unicode value and sending it through the serial port.


However it throws this error:
'ascii' codec can't encode character u'\x9a' in position 24: ordinal not in range(128)

Whats the best way to convert an int to unicode?

share|improve this question
Python2 or Python3? (guessing Python2, but makes quite the difference) Are you quite sure unichr is the call crashing? How are you doing the actual sending of the unichr returned data? –  Joachim Isaksson Jul 13 '13 at 7:11
unichr() does not exist in Python 3, so this is Python 2. unichr() is named chr() in Python 3 (conversion to a Unicode character). –  EOL Jul 13 '13 at 11:37

3 Answers 3

up vote 1 down vote accepted

Just use chr(somenumber) to get a 1 byte value of an int as long as it is less than 256. pySerial will then send it fine.

If you are looking at sending things over pySerial it is a very good idea to look at the struct module in the standard library it handles endian issues an packing issues as well as encoding for just about every data type that you are likely to need that is 1 byte or over.

share|improve this answer
that works thanks a lot –  user2578666 Jul 13 '13 at 9:17
@user2578666: If a response is useful to you and you mark it as accepted, it is only fair to up-vote it too. Welcome to StackOverflow! –  EOL Jul 13 '13 at 11:35
No rep yet.Got to earn it:-) –  user2578666 Jul 13 '13 at 12:37
@user2578666: I see—I did not remember this rule. May you reputation grow fast. :) –  EOL Jul 14 '13 at 3:40

I think that the best solution is to be explicit and say that you want to represent a number as a byte (and not as a character):

>>> import struct
>>> struct.pack('B', 128)
>>> '\x80'

This makes your code work in both Python 2 and Python 3 (in Python 3, the result is, as it should, a bytes object). An alternative, in Python 3, would be to use the new bytes([128]) to create a single byte of value 128.

I am not a big fan of the chr() solutions: in Python 3, they produce a (character, not byte) string that needs to be encoded before sending it anywhere (file, socket, terminal,…)—chr() in Python 3 is equivalent to the problematic Python 2 unichr() of the question. The struct solution has the advantage of correctly producing a byte whatever the version of Python. If you want to send data over the serial port with chr(), you need to have control over the encoding that must take place subsequently. The code might work when the default encoding used by Python 3 is UTF-8 (which I think is the case), but this is due to the fact that Unicode characters of code point smaller than 256 can be coded as a single byte in UTF-8. This adds an unnecessary layer of subtlety and complexity that I do not recommend (it makes the code harder to understand and, if necessary, debug).

So, I strongly suggest that you use the approach above (which was also hinted at by Steve Barnes and Martijn Pieters): it makes it clear that you want to produce a byte (and not characters). It will not give you any surprise even if you run your code with Python 3, and it makes your intent clearer and more obvious.

share|improve this answer
Bravo @EOL - one of the, (possibly many), misleading things about C that C++ inherited is the lack of any distinction between a string that has a length of 1, a single character - both text n the local encoding - and a byte. –  Steve Barnes Jul 13 '13 at 19:02

Use the chr() function instead; you are sending a value of less than 256 but more than 128, but are creating a Unicode character.

The unicode character has to then be encoded first to get a byte character, and that encoding fails because you are using a value outside the ASCII range (0-127):

>>> str(unichr(169))
Traceback (most recent call last):
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa9' in position 0: ordinal not in range(128)

This is normal Python 2 behaviour; when trying to convert a unicode string to a byte string, an implicit encoding has to take place and the default encoding is ASCII.

If you were to use chr() instead, you create a byte string of one character and that implicit encoding does not have to take place:

>>> str(chr(169))

Another method you may want to look into is the struct module, especially if you need to send integer values greater than 255:

>>> struct.pack('!H', 1000)

The above example packs an integer into a unsigned short in network byte order, for example.

share|improve this answer
I guess you meant "bytes", not "a byte character"? "byte character" is not a common expression, and is almost an oxymoron. Furthermore, the default encoding does not have to be ASCII: it is officially sys.getdefaultencoding(). –  EOL Jul 13 '13 at 7:42
@EOL: This is Python 2, this is a string object, which is really a sequence of bytes. But looping over it gives you strings of length 1; byte characters. –  Martijn Pieters Jul 13 '13 at 7:43
@EOL: The default encoding is ASCII on Python 2, when it comes to implicit encodings (concatenating strings and unicode, comparing for equality, etc.). –  Martijn Pieters Jul 13 '13 at 7:43
@EOL: Do not confuse that with the print statement / function encoding to the codec of sys.stdout. –  Martijn Pieters Jul 13 '13 at 7:45
Do you have a reference that states this? I have always been looking for it. –  EOL Jul 13 '13 at 7:45

Your Answer


