添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Hi All,

I've been using my best googling skills into getting this working but it evades me. I am trying to open a serial port, write a handful of bytes in hex, listen to the port, then close the port.

I cannot get past writing the bytes. My best guess is I'm having trouble satisfying the java bytearray requirements. This is the code I'm using in the interpreter.

system.serial.configureSerialPort(\
	port="COM7",\
	bitRate=system.serial.BIT_RATE_9600,\
	dataBits=system.serial.DATA_BITS_8,\
	handshake=system.serial.HANDSHAKE_NONE,\
	hardwareFlowControl=False,\
	parity=system.serial.PARITY_NONE,\
	stopBits=system.serial.STOP_BITS_1)
system.serial.closeSerialPort("COM7")
system.serial.openSerialPort("COM7")
system.serial.writeBytes("COM7","\xCA\x00\x01\x70\x00\x8E")
system.serial.closeSerialPort("COM7")

Firing the script returns an angry traceback that the serial module trial is expired. Restarting the trial via gateway webpage and relaunching the designer have no effect. Not sure what to do here...

Java Traceback:
Traceback (most recent call last):
  File "<input>", line 14, in <module>
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.checkTrialExpired(SerialScriptModule.java:154)
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.writeBytes(SerialScriptModule.java:616)
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.writeBytes(SerialScriptModule.java:599)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
com.inductiveautomation.ignition.modules.serial.scripting.TrialExpiredException: com.inductiveautomation.ignition.modules.serial.scripting.TrialExpiredException: Serial module trial period has expired.
	at org.python.core.Py.JavaError(Py.java:547)
	at org.python.core.Py.JavaError(Py.java:538)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:192)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:208)
	at org.python.core.PyObject.__call__(PyObject.java:477)
	at org.python.core.PyObject.__call__(PyObject.java:481)
	at org.python.pycode._pyx6.f$0(<input>:16)
	at org.python.pycode._pyx6.call_function(<input>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1687)
	at org.python.core.Py.exec(Py.java:1731)
	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:277)
	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:130)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:611)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:599)
	at java.desktop/javax.swing.SwingWorker$1.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.desktop/javax.swing.SwingWorker.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: com.inductiveautomation.ignition.modules.serial.scripting.TrialExpiredException: Serial module trial period has expired.
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.checkTrialExpired(SerialScriptModule.java:154)
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.writeBytes(SerialScriptModule.java:616)
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.writeBytes(SerialScriptModule.java:599)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
	... 19 more
Traceback (most recent call last):
  File "<input>", line 14, in <module>
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.checkTrialExpired(SerialScriptModule.java:154)
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.writeBytes(SerialScriptModule.java:616)
	at com.inductiveautomation.ignition.modules.serial.scripting.SerialScriptModule.writeBytes(SerialScriptModule.java:599)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
com.inductiveautomation.ignition.modules.serial.scripting.TrialExpiredException: com.inductiveautomation.ignition.modules.serial.scripting.TrialExpiredException: Serial module trial period has expired.

It's because this isn't a byte array. It is a jython string whose codepoints match the bytes you want to send. You need to construct your byte array with jython's jarray module.

(Beware: java byte arrays have signed 8-bit values.)

Dang you are fast.

My apologies for my ignorance. I had a feeling I was murdering the requirements for the array.

Would you be able to walk me through constructing a simple 2-byte array that can handle unsigned values and is a valid argument for system.serial.writeBytes ?
So far I've been taking guidance from these forum posts but am lost as how to construct the array:
https://forum.inductiveautomation.com/t/serial-module-possible-error/5920/11
https://forum.inductiveautomation.com/t/solved-get-nmea-sentence-system-serial/48783

Again, my apologies for the ignorance. Any help is appreciated. Thank you!

unsignedBytes = [0xCA, 0x00, 0x01, 0x70, 0x00, 0x8E] signedBytes = [((x + 0x80) & 0xff) - 0x80 for x in unsignedBytes] byteArray = jarray.array(signedBytes, 'b')

Rather than rely on jython math, I usually do this:

import jarray
from java.lang import Long
unsignedBytes = [0xCA, 0x00, 0x01, 0x70, 0x00, 0x8E]
signedBytes = [Long.valueOf(x).byteValue() for x in unsignedBytes]
byteArray = jarray.array(signedBytes, 'b')

This latter implementation will simply chop the upper bits off of whatever you feed it.

Apparently, that no longer works. Jython is turning the Long back into its own long. ):

Thanks for the help! That snippet got me off to the races. I'll post more to this topic when my example is more complete... or if I'm completely lost :slightly_smiling_face:

Thanks again!

Using bytearray you can get the same affect without the '0x' in the strings/values.

msg = '4142'
data = bytearray.fromhex(msg)
print data  #should print 'AB'
              

Hey All,

For anyone watching this thread, these are the commands I ended up using to sign and unsign byte arrays, and pipe those arrays to and from the serial port. Device documentation was all in raw hex so that's the reason for working back and forth. I'm sure there's prettier code out there but this does work.

commands = [
    [0xCA, 0x00, 0x01, 0x70, 0x00, 0x8E],  # Current Setpoint
    [0xCA, 0x00, 0x01, 0x10, 0x00, 0xEE],  # Process Flowrate
for command, tag_path in zip(commands, tag_paths):
    # Convert unsigned byte array to signed byte array
    signedCommandBytes = [((x + 0x80) & 0xff) - 0x80 for x in command]
    commandByteArray = jarray.array(signedCommandBytes, 'b')
    # Send the message
    system.serial.writeBytes("COM7", commandByteArray)
    # Receive the reply
    chillReply = system.serial.readBytes("COM7", 9)
    # The reply is an unsigned array stored as a signed array
    # Can't use the jarray function as before though, as it creates overflows
    signedReplyBytes = [((x + 0x80) & 0xff) - 0x80 for x in chillReply]
    unsignedReplyBytes = bytearray([(byte + 256) % 256 for byte in signedReplyBytes])
    packet = unsignedReplyBytes

This snippet was part of a rudimentary driver for Neslab / Thermoflex chillers using "NC protocol". Please drop me a PM if you would like the entire script.