1

My laptop runs a Python program that reads a joystick to send a speed command to an Arduino that in turn controls the motor on a toy car. To do that the program converts an integer with values between 0 and 255 to a single unsigned byte that it sends over a serial connection to the Arduino.

This code works to do that:

           if event.axis == axis:
                speed = int((event.value + 1.0) / 2.0 * 255.0)
                speedCommand = bytearray(b'\x00')
                speedCommand[0] = speed
                speedCommand = bytes(speedCommand)
                ser.write(speedCommand)
                print(speed, speedCommand)

While that code works, it's not very elegant. I would like to find a one-line instruction that does the same thing as the three lines that start with "speedCommand". I tried this, for example:

            speedCommand = chr(speed).encode()

But it only works for 0 to 127. Any number above 127 encodes to two bytes[, as the character is seen as a signed byte with values above 127 being negative].

EDITED TO ADD: My assumption that "the character is seen as a signed byte with values above 127 being negative" may not be correct.

3
  • " as the character is seen as a signed byte with values above 127 being negative." I don't think that's what's going on, in any case, I've provided an answer Commented Apr 10, 2021 at 22:27
  • FYI speed = chr(speed).encode('latin1') would fix your encoding problem. The encoding defaults to utf8 otherwise Commented Apr 10, 2021 at 22:31
  • Mark Tolonen, that chr(speed).encode('latin1') solution does indeed work in my program. Good to know. Commented Apr 10, 2021 at 23:04

2 Answers 2

2

You just need:

speed_command = bytes([speed])

The bytes constructor accepts an iterable of int objects, so just put it in a list when you pass it to the constructor.

Sign up to request clarification or add additional context in comments.

Comments

2

You can use the pack method from the struct built-in module. It takes as first argument a format, and as next arguments a value (or multiple values) to pack into this format. For an unsigned char, the required format is B. The module supports many other formats, which might be useful for sending other data to your Arduino. See the struct module documentation for more information, including a list of format characters.

>>> import struct
>>> speed = 255
>>> struct.pack('B', speed)
b'\xff'

1 Comment

That struct module is a good one to know about in sending data to the Arduino. I can use it in a couple of other places in my program. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.