Write(), SerialPorts and Arduino in RobotPy

Hey
Our team is trying to turn on an Arduino using one of three USB ports of RoboRIO (Serial Connection). We are following this tutorial: Arduino/RoboRIO Integration - YouTube (minute 11:06)

The problem is that we are using Python for our code and we need a function similar to “new bytes[]” , but we couldn’t find any “byte type”. We tried using bytes() or bytearray(), but these functions still with problems, such as incompatible arguments of the function (using wpilib.SerialPort.write()).

image

How could we convert this function for the Python syntax?

You should be able to use bytes for writing and bytearray for reading… but I haven’t tried it recently. What does your code look like, and what error did you get?

1 Like


TypeError: write(): incompatible function arguments.

Here are the codes:


I think that it can be the wrong connection on the USB ports of RoboRIO too. But I don’t know which port represents kUSB, kUSB1 and kUSB2.

1 Like

I can’t really help with the python code. But for the kUSB enum, kUSB1 and kUSB represent the top USB port (Nearest the edge), and kUSB2 represents the bottom port.

If I had to guess for python code, I think the 1 is unnecessary. bytes() should have a length attached to it,

2 Likes

Yeah, what Thad said:

self.arduino.write(b'\x12')

Calling bytes(0x12) will create an 0x12 bytes that are zero, so that’s not what you want.

For the read you need to create a bytearray of the length you want to read (because bytes cannot be changed, but bytearray can).

b = bytearray(1)
numRead = self.arduino.read(b)

Here are the API docs:

1 Like

image
It worked, but it still doesn’t show the string “yeah 0x12”.
In the video, he shows the readString() for reading the string. I searched on RobotPy docs, but I found only the read(). Maybe this counts for the problem too.

image

WPILib C++ (which RobotPy wraps) doesn’t have a readString API, but Java does (filed bug on github). The Java API appears to be pretty silly, you can emulate it this way:

def readString(port) -> str:
    sz = port.getBytesReceived()
    buf = bytearray(sz)
    sz = port.read(buf)
    return buf[:sz].decode("ascii")

You can leave out the decode piece if you just want it to be bytes.

1 Like

thanks for writing the function, @virtuald! Now it’s returning the string. We’ll use the same logic for other types of value, and now we can use this function as a base :wink: