Re: Servos, Ardunios, and JMRI #arduino

Bob Jacobsen
 

The problem is that both scripts are using the same global variable for `outputStream`. A single script sets that, then installs some code that listens for changes so that it can later forward those changes to the hardware via outputStream. But when you run two scripts, the second one changes the value of that variable, so now both the first set of listening code _and_ the second set are sending to the second port.

The quickest reliable fix is to make sure that all the variable named in the global (not intended) part of the first script are different from those in the second script. Append a P to one and a S to the other, or something like that.

A better solution would be to move those variables into the Datatransfer class, and then pass the port in as another argument. That would make it much easier for people to use two copies of the script. But that’s a bit more programming.

Note another thing: This script creates internal Turnout objects with names at start with AT and ST. Although it woks for you now, there’s no guarantee that always will. Better would be names like ITAT or ITST, which are the standard form and won’t (possibly) break in the future.

Bob


On Jul 23, 2019, at 4:59 PM, Sam Simons <samusi01@...> wrote:

Bob,

Here you go - the 'P' script first, then the 'S' script.

Also, this is happening on current production 4.16.

Sam
# Transfer "TurnOut" Data from to an Arduino via Serial Transmission
# Author: Geoff Bunza 2018 based in part on a script by
# Bob Jacobsen as part of the JMRI distribution
# Version 1.1
# Connects JMRI Turnout "Watcher" to an Arduino Output Channel
# Note that JMRI must be set up to have a valid
# turnout table; if you're not using some other DCC connection,
# configure JMRI to use LocoNet Simulator
import jarray
import jmri
import java
import purejavacomm
# find the port info and open the port
global extportinP
portname = "COM5"
portID = purejavacomm.CommPortIdentifier.getPortIdentifier(portname)
try:
port = portID.open("JMRI", 50)
except purejavacomm.PortInUseException:
port = extportinP
extportinP = port
# set options on port
baudrate = 19200
port.setSerialPortParams(baudrate,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_NONE)
# get I/O connections for later
inputStream = port.getInputStream()
outputStream = port.getOutputStream()
# define a turnout listener that will
class Datatransfer(java.beans.PropertyChangeListener):
# initialization
# registers to receive events
def __init__(self, id, value) :
self.name = "PT"+str(id)
self.closed = value # write this value to close
self.thrown = value # write this value to throw
turnout = turnouts.provideTurnout(self.name)
turnout.addPropertyChangeListener(self)
turnout.setCommandedState(CLOSED)
return

# on a property change event, first see if
# right type, and then write appropriate
# value to port based on new state
def propertyChange(self, event):
#print "change",event.propertyName
#print "from", event.oldValue, "to", event.newValue
#print "source systemName", event.source.systemName
if (event.propertyName == "CommandedState") :
if (event.newValue == CLOSED and event.oldValue != CLOSED) :
print "set CLOSED for", event.source.userName
outputStream.write(event.source.userName)
outputStream.write(",0")
if (event.newValue == THROWN and event.oldValue != THROWN) :
print "set THROWN for", event.source.userName
outputStream.write(event.source.userName)
outputStream.write(",1")
return
# The following will set up 5 listeners for Turnouts PT1 though PT6 (by username)
for x in range(1,6) :
Datatransfer(x,x+100)

# Transfer "TurnOut" Data from to an Arduino via Serial Transmission
# Author: Geoff Bunza 2018 based in part on a script by
# Bob Jacobsen as part of the JMRI distribution
# Version 1.1
# Connects JMRI Turnout "Watcher" to an Arduino Output Channel
# Note that JMRI must be set up to have a valid
# turnout table; if you're not using some other DCC connection,
# configure JMRI to use LocoNet Simulator
import jarray
import jmri
import java
import purejavacomm
# find the port info and open the port
global extportinS
portname = "COM4"
portID = purejavacomm.CommPortIdentifier.getPortIdentifier(portname)
try:
port = portID.open("JMRI", 50)
except purejavacomm.PortInUseException:
port = extportinS
extportinS = port
# set options on port
baudrate = 19200
port.setSerialPortParams(baudrate,
purejavacomm.SerialPort.DATABITS_8,
purejavacomm.SerialPort.STOPBITS_1,
purejavacomm.SerialPort.PARITY_NONE)
# get I/O connections for later
inputStream = port.getInputStream()
outputStream = port.getOutputStream()
# define a turnout listener that will
class Datatransfer(java.beans.PropertyChangeListener):
# initialization
# registers to receive events
def __init__(self, id, value) :
self.name = "ST"+str(id)
self.closed = value # write this value to close
self.thrown = value # write this value to throw
turnout = turnouts.provideTurnout(self.name)
turnout.addPropertyChangeListener(self)
turnout.setCommandedState(CLOSED)
return

# on a property change event, first see if
# right type, and then write appropriate
# value to port based on new state
def propertyChange(self, event):
#print "change",event.propertyName
#print "from", event.oldValue, "to", event.newValue
#print "source systemName", event.source.systemName
if (event.propertyName == "CommandedState") :
if (event.newValue == CLOSED and event.oldValue != CLOSED) :
print "set CLOSED for", event.source.userName
outputStream.write(event.source.userName)
outputStream.write(",0")
if (event.newValue == THROWN and event.oldValue != THROWN) :
print "set THROWN for", event.source.userName
outputStream.write(event.source.userName)
outputStream.write(",1")
return
# The following will set up 5 listeners for Turnouts ST1 though ST6 (by username)
for x in range(1,6) :
Datatransfer(x,x+100)

--
Bob Jacobsen
@BobJacobsen

Join jmriusers@groups.io to automatically receive all group messages.