¿ªÔÆÌåÓý

Locked A bit stuck on inverting sensor states/values


 

Hi!

Running JMRI 4.14 and already tested 4.16, I'm still a bit stuck on how "invert" sensor works.

I'm receiving S88N based block occupancy signals: LOW (0V) is block occupied. HIGH (5V) is block empty. These signals are coming into JMRI via a serial link.?
A serial input script translates the messages to set/reset internal sensors IS1..IS16 with user names S88 BIT:1 .. S88 BIT:16.

(block occupancy messaging and S88N master control is done by a little? atMega8 board, having a serial link to RasPi/JMRI. A serial input script links message bytes to JMRI sensors. This is tested well and works fine).

Checking the invert box, or checking the box when creating the sensor in the sensor table, both result in the same behaviour:

Not inverted, normal use: LOW? becomes INACTIVE and HIGH becomes ACTIVE. So far so good.

When checking the invert box: the state is inverted, ACTIVE -> INACTIVE and vice versa. But, when the layout/block sends the same message again (e.g. LOW/ACTIVE) the sensor table switched to the "old"? not inverted state. The checkbox is still checked. So, basically only when checking the box, the invertion takes place and only until the next S88 message arrives.?

I assume that this "invert check box"? is present to let the system continuously invert selected sensors, if desired.

My quick fix would be to invert the sensor value in the serial input script. But, I rather like to use JMRI offered functionality which should do the job.

What am I missing, or doing wrong?

Groet!

Bart


 

The invert box comes from things like XpressNet, LocoNet, etc where it¡¯s working to invert the traffic between the JMRI Sensor object and whatever is on the actual wire.

It sounds like you have a script that is handling that wire communications. If that¡¯s the case, if you want the invert handled properly, you have to have that script check the getInverted() method (see ) and take that into account when sending and receiving messages over the S88 link.

Bob

On Sep 4, 2019, at 2:03 PM, bartsanders@... wrote:

Hi!

Running JMRI 4.14 and already tested 4.16, I'm still a bit stuck on how "invert" sensor works.

I'm receiving S88N based block occupancy signals: LOW (0V) is block occupied. HIGH (5V) is block empty. These signals are coming into JMRI via a serial link.
A serial input script translates the messages to set/reset internal sensors IS1..IS16 with user names S88 BIT:1 .. S88 BIT:16.

(block occupancy messaging and S88N master control is done by a little atMega8 board, having a serial link to RasPi/JMRI. A serial input script links message bytes to JMRI sensors. This is tested well and works fine).

Checking the invert box, or checking the box when creating the sensor in the sensor table, both result in the same behaviour:

Not inverted, normal use: LOW becomes INACTIVE and HIGH becomes ACTIVE. So far so good.

When checking the invert box: the state is inverted, ACTIVE -> INACTIVE and vice versa. But, when the layout/block sends the same message again (e.g. LOW/ACTIVE) the sensor table switched to the "old" not inverted state. The checkbox is still checked. So, basically only when checking the box, the invertion takes place and only until the next S88 message arrives.

I assume that this "invert check box" is present to let the system continuously invert selected sensors, if desired.

My quick fix would be to invert the sensor value in the serial input script. But, I rather like to use JMRI offered functionality which should do the job.

What am I missing, or doing wrong?

Groet!

Bart
--
Bob Jacobsen
rgj1927@...


 

Bart,

If the script is setting the ACTIVE/INACTIVE, then that's the state you get.
At least from what I recall, that scripts are setting the state. It sounds
like your script needs to set ACTIVE when the value coming in is LOW. If the
sensor was reading real hardware, the invert would have told it to think LOW
== ACTIVE.

-ken cameron


 

On Wed, Sep 4, 2019 at 03:23 PM, Ken Cameron wrote:
It sounds
like your script needs to set ACTIVE when the value coming in is LOW.
Thanks, Ken and Bob,

Ken's answer points in my "quick fix" direction. That would be Plan "B".

I will check the getinverted() method (and setinverted() as well) referenced by Bob. From what I understand now, the input script has to know if the user has used the invert sensor value (by checking the little box). Otherwise, the actual 1/0 value is simply stuffed into the Internal Sensor, overriding the user setting(s).
Will check this and report.

By the way, the serial input script is based on serial input samples in the JMRI distribution, plus actual code offered to this forum by Geoff Bunza.

Groetjes,

Bart


 

Yes, if you referenced the getInverted() for that sensor, then you could do
the right action with an if/else for which is ACTIVE. Pretty simple really
and that lets you use other sensors that are not active low via your serial
script.

-Ken Cameron, Member JMRI Dev Team
www.jmri.org
www.fingerlakeslivesteamers.org
www.cnymod.org
www.syracusemodelrr.org


 

Chapeau, gentlemen!

Works.

And in the best possible, user controlled way. Invert the sensor you want to be inverted, leave the rest as is.

Code snippet, as simple as Ken wrote:
s = sensors.getByUserName( mesg )
? ? ? ? if s is None :
? ? ? ? ? ? ? ? print mesg, " Not Available"
? ? ? ? ? ? ? ? return 1
? ? ? ? if sensor_state == 0x80 :
? ? ? ? ? ? ? ? if s.getInverted() :
? ? ? ? ? ? ? ? ? ? s.setKnownState(INACTIVE)
? ? ? ? ? ? ? ? else :
? ? ? ? ? ? ? ? ? ? s.setKnownState(ACTIVE)
? ? ? ? if sensor_state == 0 :
? ? ? ? ? ? ? ? if s.getInverted() :
? ? ? ? ? ? ? ? ? ? s.setKnownState(ACTIVE)
? ? ? ? ? ? ? ? else :
? ? ? ? ? ? ? ? ? ? s.setKnownState(INACTIVE)

Great support, by the way.

Groet!

Bart


 

You can also go into the sensor's table, and clic kthe inverted checkbox, to invert specific sensors.

On Thu, Sep 5, 2019 at 9:04 PM <bartsanders@...> wrote:
Chapeau, gentlemen!

Works.

And in the best possible, user controlled way. Invert the sensor you want to be inverted, leave the rest as is.

Code snippet, as simple as Ken wrote:
s = sensors.getByUserName( mesg )
? ? ? ? if s is None :
? ? ? ? ? ? ? ? print mesg, " Not Available"
? ? ? ? ? ? ? ? return 1
? ? ? ? if sensor_state == 0x80 :
? ? ? ? ? ? ? ? if s.getInverted() :
? ? ? ? ? ? ? ? ? ? s.setKnownState(INACTIVE)
? ? ? ? ? ? ? ? else :
? ? ? ? ? ? ? ? ? ? s.setKnownState(ACTIVE)
? ? ? ? if sensor_state == 0 :
? ? ? ? ? ? ? ? if s.getInverted() :
? ? ? ? ? ? ? ? ? ? s.setKnownState(ACTIVE)
? ? ? ? ? ? ? ? else :
? ? ? ? ? ? ? ? ? ? s.setKnownState(INACTIVE)

Great support, by the way.

Groet!

Bart