Script console serial port

Please post code and errors as code, not photographs or screenshots. Use the </> code formatting button to apply syntax highlighting and preserve indentation. Then we can copy and edit it in our answers.

I don’t think you are calling writeBytes correctly, and i don’t think you are giving it a java.lang.byte.
https://docs.inductiveautomation.com/display/DOC81/system.serial.writeBytes

Something is coercing [adress] into a Python ‘singleton’, which likely means True, False or None, but I’m not sure why…

y = 0
portNum = "COM10"
address = 0x80
cmd = 0x04
qty = 0x01
confirm = 0x0B
chkSum3 = adress ^ cmd ^ qty
chkSum2 = adress ^ confirm
chkConfNoError = adress ^ 3 ^ 0 ^ qty
with system.serial.port(
			port = portNum,
			bitRate =system.serial.BIT_RATE_19200,
			dataBits = system.serial.DATA_BITS_8,
			handshake = system.serial.HANDSHAKE_NONE,
			hardwareFlowControl = False,
			parity = system.serial.PARITY_MARK,
			stopBits = system.serial.STOP_BITS_1) as port:
			
	port.writeBytes([adress])

with system.serial.port(
			port = portNum,
			bitRate =system.serial.BIT_RATE_19200,
			dataBits = system.serial.DATA_BITS_8,
			handshake = system.serial.HANDSHAKE_NONE,
			hardwareFlowControl = False,
			parity = system.serial.PARITY_SPACE,
			stopBits = system.serial.STOP_BITS_1) as port2:
			
	port2.writeBytes([cmd, qty, chkSum3])
	#time.sleep(0.001)
	#port2.writeBytes([qty])
	#time.sleep(0.001)
	#port2.writeBytes([chkSum3])
	response = port2.readBytes(5, 5)
	#time.sleep(0.015)
		
with system.serial.port(
			port = portNum,
			bitRate =system.serial.BIT_RATE_19200,
			dataBits = system.serial.DATA_BITS_8,
			handshake = system.serial.HANDSHAKE_NONE,
			hardwareFlowControl = False,
			parity = system.serial.PARITY_MARK,
			stopBits = system.serial.STOP_BITS_1) as port:
	
	port.writeBytes([adress])

with system.serial.port(
			port = portNum,
			bitRate =system.serial.BIT_RATE_19200,
			dataBits = system.serial.DATA_BITS_8,
			handshake = system.serial.HANDSHAKE_NONE,
			hardwareFlowControl = False,
			parity = system.serial.PARITY_SPACE,
			stopBits = system.serial.STOP_BITS_1) as port2:

	while True:
		port2.writeBytes([confirm, chkSum2])
		#time.sleep(0.001)
		#port2.writeBytes([chkSum2])
		res = list(port2.readBytes(5, 5))
		#time.sleep(0.015)
		y = y + 1
		if res == [adress, 3, 0, qty, chkConfNoError]:
			break
			
	print "Dirección " + str(adress)
	print res
	print list(response)
	print str(y)

The point of the system.serial.port context manager is that you don’t have to open and close the port manually - you just write all your code that has to interact with the port within the indented scope.
Try this, and see what the output is of the two print statements before the first write:

y = 0
portNum = "COM10"
adress = 0x80
cmd = 0x04
qty = 0x01
confirm = 0x0B
chkSum3 = adress ^ cmd ^ qty
chkSum2 = adress ^ confirm
chkConfNoError = adress ^ 3 ^ 0 ^ qty

with system.serial.port(
			port = portNum,
			bitRate =system.serial.BIT_RATE_19200,
			dataBits = system.serial.DATA_BITS_8,
			handshake = system.serial.HANDSHAKE_NONE,
			hardwareFlowControl = False,
			parity = system.serial.PARITY_MARK,
			stopBits = system.serial.STOP_BITS_1) as port:

	toWrite = [adress]
	print toWrite
	print type(toWrite)
	
	port.writeBytes(toWrite)
	port.writeBytes([cmd, qty, chkSum3])
	#time.sleep(0.001)
	#port.writeBytes([qty])
	#time.sleep(0.001)
	#port.writeBytes([chkSum3])
	response = port.readBytes(5, 5)
	#time.sleep(0.015)

	port.writeBytes([adress])

	while True:
		port.writeBytes([confirm, chkSum2])
		#time.sleep(0.001)
		#port.writeBytes([chkSum2])
		res = list(port.readBytes(5, 5))
		#time.sleep(0.015)
		y = y + 1
		if res == [adress, 3, 0, qty, chkConfNoError]:
			break
			
	print "Dirección " + str(adress)
	print res
	print list(response)
	print str(y)

I’m trying to understand your code (@PGriffith’s code). Is it possible that port2 isn’t declared? If it is declared somewhere under the hood, where?

The error is right here :

port.writeBytes([address])

That was just a typo from rewriting the original code.

Yeah, I want to see the output from the print statements in my modified code:

	toWrite = [adress]
	print toWrite
	print type(toWrite)
	
	port.writeBytes(toWrite)

Yes , I got a type = list and towrite I got [128] , but If I put 127 everything is fine

y = 0
portNum = “COM10”
address = 0x80
cmd = 0x04
qty = 0x01
confirm = 0x0B
chkSum3 = adress ^ cmd ^ qty
chkSum2 = adress ^ confirm
chkConfNoError = adress ^ 3 ^ 0 ^ qty
with system.serial.port(
port = portNum,
bitRate =system.serial.BIT_RATE_19200,
dataBits = system.serial.DATA_BITS_8,
handshake = system.serial.HANDSHAKE_NONE,
hardwareFlowControl = False,
parity = system.serial.PARITY_MARK,
stopBits = system.serial.STOP_BITS_1) as port:

port.writeBytes([adress])

You might need to work around a Jython bug:

It isn’t really a jython bug. Just that java bytes are signed, so java byte arrays must be made of values from -128 to 127.

I get it , but I need to send 128, do you know if is there more options?
How to send a number without the operator - 128

The simplest expression to get the proper signed byte is ((b + 128) & 0xff) - 128. For each byte.

Seems like we should make these functions easier to call… perhaps by accepting int[] as well.

3 Likes

I understand but we need with no sign

You actually do, because that is how the underlying Java works. You can use the expression @pturmel mentioned in a helper function to format the bytes as they make sense to you to what is required for the array. Combining with what @PGriffith mentioned earlier should yield something like:

y = 0
portNum = "COM10"
adress = 0x80
cmd = 0x04
qty = 0x01
confirm = 0x0B
chkSum3 = adress ^ cmd ^ qty
chkSum2 = adress ^ confirm
chkConfNoError = adress ^ 3 ^ 0 ^ qty

def toSignedBytes(bytesIn):
	''' Convert a list of unsigned byte values to signed values.
	    If a single integer value is given, a list is still returned
	'''
	if isinstance(bytesIn, int):
		bytesIn = [bytesIn]
	return [((byte+128) & 255)-128 for byte in bytesIn]

# Initialize the byte lists
cmdList = toSignedBytes([address, cmd, qty, chkSum3])
confirmList = toSignedBytes([address, confirm, chkSum2])

with system.serial.port(
			port = portNum,
			bitRate =system.serial.BIT_RATE_19200,
			dataBits = system.serial.DATA_BITS_8,
			handshake = system.serial.HANDSHAKE_NONE,
			hardwareFlowControl = False,
			parity = system.serial.PARITY_MARK,
			stopBits = system.serial.STOP_BITS_1) as port:
	# Send the command
	print "Dirección: ", str(adress)
	print "Cmd bytes:", cmdList
	port.writeBytes(cmdList)
	# Get the response
	cmdResponse = list(port.readBytes(5, 5))
	print "Cmd response: ", (cmdResponse)	

	print "Confirm bytes: ", confirmList 	
	while True:
		# Send the confirm
		port.writeBytes(confirmList)
		# Get the response
		confirmResponse = list(port.readBytes(5, 5))
		
		y = + 1
		if res == [adress, 3, 0, qty, chkConfNoError]:
			break
			
	print "Confirm Response: ", confirmResponse
	print "Tries: ", str(y) 
2 Likes

Yes but I am looking for the opposite , I mean upside down

Opening and closing ports is not needed. Should we also avoid delays between calls?

I have a while looking up for posts using the Serial Module with delays in between

As a general practice, a lockable external resource like a serial port should only be held by your application while it’s actively being read to or written from. There are exceptions, but I would stick to that as a guideline before doing something else.

Ok, then it’s a good practice to open and close it.

What about delays within system.serial.port?

There are many time.sleep(0.001) commented in the code. I’ve notice that opening a port, running instructions, and closing the port, always takes around 5 seconds. That’s without any sleep() in it.