Hi to all,
Some may remember that I posted a reference to a new bulk sensor channel for JMRI connecting to an Arduino sensor mux: https://model-railroad-hobbyist.com/node/34392
This uses a jython script for a direct connection into JMRI, independent of the DCC base station connection. Originally I built this with PanelPro 4.12 / Java 1.8.0_151 running on a Win10 Pro 64bit laptop. It ran great. I was asked to make it work on an RPi. My RPi 3 B+ is also running JMRI 4.12 / Java 1.8.0_65. However I had to add a delay on the RPi, that breaks the script on Windows, and a new report is that other modelers had to fiddle with the amoint of delay on their RPi version (unknown).
The sequence of events is normally:
1. Arduino starts and opens Arduino USB serial port
2. JMRI starts and then starts script, which opens usb serial port
3. Arduino detects serial port opening and restarts Arduino comms ignoring serial comms during startup
4. Script sends Arduino starup chars (!!!) indicating script is ready
5. Arduino scans its sensor pins and transmits update messages to script to update sensor table.
My RPi required the added delay to be inserted after step 2.
Adding this delay breaks comms on Windows. The actual complete script is below.
Can anyone give me some insight why no delay is needed on Windows10? Why isn't the 2 second delay universally working on RPi's. I have been at this for well over a week,searched the net repeatedly (and got more than enough bad info). Good, approriate insight would be much appreciated.
Thanks ahead. Have fun!? :-)
Best regards,
Geoff Bunza
scalemodelanimation.com
import jarray
import jmri
import purejavacomm
class SerialSensorMux(jmri.jmrit.automat.AbstractAutomaton) :
??? # ctor starts up the serial port
??? def __init__(self, portname) :
??????? global extport
??????? self.portID = purejavacomm.CommPortIdentifier.getPortIdentifier(portname)
??????? try:
??????????? self.port = self.portID.open("JMRI", 50)
??????? except purejavacomm.PortInUseException:
??????????? self.port = extport
??????? extport = self.port
??????? # set options on port
??????? baudrate = 19200
??????? self.port.setSerialPortParams(baudrate,
??????????? purejavacomm.SerialPort.DATABITS_8,
??????????? purejavacomm.SerialPort.STOPBITS_1,
??????????? purejavacomm.SerialPort.PARITY_NONE)
??????? # Anticipate the Port Opening will restart the Arduino
??????? # Uncomment the following line for use on RPi You may need to fiddle with the 2000
??????? # msec delay this works on my RPi 3 B+
??????? #self.delayMsec(2000)
??? ??? # get I/O connections for later
??????? self.inputStream = self.port.getInputStream()
??????? self.outputStream = self.port.getOutputStream()
??????? return
??? # init() is the place for your initialization
??? def init(self) :
??????? return
??? # handle() is called repeatedly until it returns false.
??? def handle(self) :
??????? global ttest
??????? if ttest == 1 :
??????????????? self.outputStream.write('!')
??????????????? self.outputStream.write('!')
??????????????? self.outputStream.write('!')
??????????????? self.outputStream.write(0x0D)
??????????????? ttest = 0
??????? # get next character???
??????? if self.inputStream.read() != 65 :
??????????????? return 1
??????? sensor_num = self.inputStream.read()
??????? sensor_state = ( sensor_num>>7 ) & 1
??????? sensor_num = sensor_num & 0x7f
??????? mesg = "AR:%d" % (sensor_num)
??????? if sensor_num == 1 and sensor_state == 1 :
??????????? print "Sensor Read Ends"
??????????? self.inputStream.close()
??????????? self.outputStream.close()
??????????? self.port.close()
??????????? return 0
??????? s = sensors.getByUserName( mesg )
??????? if s is None :
??????????????? print mesg, " Not Available"
??????????????? return 1
??????? if sensor_state == 1 :
??????????????? s.setKnownState(ACTIVE)
??????? if sensor_state == 0 :
??????????????? s.setKnownState(INACTIVE)
??????? return 1??? # to continue 0 to Kill Script
??? def write(self, data) :
??????? # now send
??????? self.outputStream.write(data)
??????? return
??? def flush(self) :
??????? self.outputStream.flush()
??????? return
ttest=1
# create one of these; provide the name of the serial port
a = SerialSensorMux("COM5")
# set the thread name, so easy to cancel if needed
a.setName("SerialSensorMux script")
# start running
a.start();
# setup? complete
a.flush()