Issue using Python to write serial command to JRK21V3

Attached is Python code that I am running on an RPi. Most of it works, but some of it doesn’t. The particular issue is how to write a “” with the variable that equals the position in hex. I could never get the code provided in the user manual to work in Python. I did get it to work on the Arduino platform, Can you take a look at the 4 lines below that don’t work and offer a Python alternative?

from time import sleep
import serial
ser = serial.Serial( "/dev/ttyACM0", 115200)
print("connected to: " + ser.portstr)
endpt1="\xDF"
endpt2="\x7F"
startpt1="xC0"
startpt2="x00"
print("sending target 4095 - works")
ser.write(endpt1)
ser.write(endpt2)
sleep (10.0)
print ("returning to zero position")
# neither of the versions below worked
ser.write("0"+startpt1) 
ser.write("0"+startpt2) 
ser.write("\\"+startpt1) 
ser.write("\\"+startpt2) 
sleep (10.0)
print ("returning to zero position - works")
ser.write("\xC0") 
ser.write("\x00")
quit()

btw, when I wrote the post there were two 's, but when I posted it one of the 's disappeared. So the attempted code that did not work is: ser.write("*"+startpt1) without the “*”

Darn it. The second backslash disappeared again. The code that did not work is: ser.write(“two backslashes here”+startpt1)

Hello.

I added code tags to your first post so that your code is displayed and formatted properly. You can see the modifications by clicking on the pencil icon in the upper right-hand corner of the edited post and view the raw source.

Both versions of your serial command are incorrect. Please see this post for details on how to escape hex values in Python.

The backslash can be used to escape certain characters on this forum, which is why the code in your second post was displayed incorrectly. To avoid this, you should use code tags whenever you post code in the future so that your code is displayed correctly.

- Amanda

I looked at your other post. Thanks for trying to offer advice. I understand how to send a hardcoded series of hex codes for example ser.write("\xDF\x7F") to send the position 4095. What I’m unable to determine is how, in Python, to send the equivalent of:

Convert 4095 to Position_in_hex
Ser.write(position_in_hex)

As mentioned previously. I did get this working in Arduino using the basic format:

word target = x;
mySerial.write(0x40 + (target & 0x1F));
mySerial.write((target >> 5) & 0x7F);

I don’t know how to do the same in Python. (e.g. Python does not have a “word” 16 bit unsigned data type)

The closest I have gotten is an approach of converting the input value to a 12 char string of the binary equivalent and then manipulating that as a string:

def jrkTarget (target):
    str = "{0:12b}".format(target)
    binaryTarget = str.replace(" ", "0")
    lowBitCmd = "110" + binaryTarget[7: 12]
    hexCmdA=hex(int(lowBitCmd, 2))
    print("low bit:", lowBitCmd, " integer=", int(lowBitCmd, 2))
    hexCmdB ="\\"+hexCmdA[0:4]
    ser.write(hexCmdB)
    HighBitCmd = "0" + binaryTarget[0:7]
    hexCmdA=hex(int(HighBitCmd, 2))
    hexCmdB = "\\"+hexCmdA[0:4]
    ser.write(hexCmdB)

btw, this code also gets close, but fails on the line ser.write(highByte) with the error “TypeError: object of type ‘int’ has no len()”.

    lowByte = (target & ord("\x1F")) | ord("\xC0")
    highByte = (target >> 5) & ord("\x7F")
    ser.write(highByte)
    ser.write(lowByte)

The pySerial write function accepts instances of bytes, bytearray, and str. You can find more information about that function here.

In your jrkTarget function, it looks like you are writing hexCmdB as a literal representation of a hex number. You need to convert that into bytes. You might find this post helpful.

In your last code example, you are trying to send an integer to write, which is not an object it accepts. You would need to use chr to convert the integer to a byte.

- Amanda

Thanks for trying to help. I’m assuming no one to your knowledge has ever written python code to send commands to one of your JRK’s using a variable for position. Thanks anyway.

We do not have any Python example code for the jrk. However, you might consider looking at the setTarget function in maestro.py, a Python class that controls the Maestro via its TTL serial interface. The Maestro uses a similar TTL serial commands as the jrk, so looking at that function should give you an idea of how to convert the target position value into two bytes and send those values to the jrk in Python.

- Amanda

ser.write(chr(lowByte))
ser.write(chr(highByte))

will work.

1 Like