Premise Weeder Technologies Digital I/O Module

Motorola Premise
The latest initializes the board correctly and passes the test you outlined. I did a simulated power outtage and noticed that upon receiving the A! that the module does not reinitialize the board. If I understand things correctly, the board should be initialized after a restart as well.

I only had a few minutes to do the testing so I don't have the debug logs availalbe. Let me know if you need them and I'll try to do the tests again tomorrow evening.
 
.. upon receiving the A! that the module does not reinitialize the board. ...
That is odd.
OnChangeOnNewData handles a restart message (A!) by running the InitAllModules method. I'll need to see DebugView's log.
 
I guess I'm losing my mind. I tried to replicate things using Debug and it is working as advertised. I'm not sure what happened last night but it appears to be working just fine today.
 
Give it a good workout and confirm Inputs and Outputs work properly and that state changes are updated correctly upon a powerdown/powerup and disconnect/reconnect. I'll withhold the release of a new version (with a Watchdog) until you're certain all data communicastions are handled correctly.

BTW, an Output's AutoReset property is unusable with a Home object unless you change one of Premise's core schemas. They had overlooked to make the DigitalOutputEx class's AutoReset property bindable and this post describes how to fix that.
 
Give it a good workout and confirm Inputs and Outputs work properly and that state changes are updated correctly upon a powerdown/powerup and disconnect/reconnect. I'll withhold the release of a new version (with a Watchdog) until you're certain all data communicastions are handled correctly.

I can report that things appear to be in working order. I've tested a good bit last night and went home for lunch and did more testing. Powerdown/powerup functionality is working great and input/outputs are behaving as expected.
 
I can report that things appear to be in working order. ...
Glad to hear it!

I thought about adding a Watchdog and quickly realized it is more complex than I had anticipated.

Normally, one physical device is connected to a serial port. The Watchdog periodically queries the device and expects a response within a second or two. In the case of the WTDIO modules, you can daisy-chain several of them together to the same serial port (up to 32). Each WTDIO module in the chain is distinguished by a unique address ( "A-P" and "a-p" ).

So how should the Watchdog handle these daisy-chained modules?
  1. Poll each module.
    This technique confirms each module is connected and functional. If you have five modules and you break the chain between third and fourth module, the Watchdog will report a problem when either the 4th or 5th module fails to respond to a poll. Unfortunately, this technique introduces quite a bit of overhead. Plus it'd be laborious to code and test under the current arrangement (i.e. I code, you test).
  2. Poll the first module.
    This technique assumes that if the first module in the chain fails to responds to a poll, then all remaining modules will be inaccessible. The problem is that there is no reliable way of detecting the first module. One could assume that the lowest module address represents the first address. However, nothing prevents the end-user from connecting and addressing the modules in whatever order they choose (i.e. D-C-A-F-B ). Plus if the first module responds to a poll, there is no guarantee all other modules are truly connected.
  3. Poll the first and last modules.
    This technique is an enhancement to option #2 and assumes that if the last module in the chain responds to a poll, then all intermediate modules will also be accessible.
My choice would be a slight variation of option #2. The first WTDIO module in the driver's treeview will be the module address polled by the Watchdog. It becomes the end-user's responsibility to ensure that the first module in the treeview corresponds to the first physical module connected to the PC's serial-port.

Your thoughts?
 

Attachments

  • First_WTDIO_in_Treeview.png
    First_WTDIO_in_Treeview.png
    15.6 KB · Views: 11
Your choice sounds good to me. If you can somehow include some documentation that states that the user should put the modules in the correct order then it becomes their problem. I don't plan on getting another module so I really wouldn't be able to test this functionality.
 
... include some documentation that states that the user should put the modules in the correct order ..
The final version will be posted in Premise Downloads and will be documented.

Attached is the latest version containing a Watchdog. Here's how it works:
  • The Watchdog polls the first WTDIO module every 60 seconds (it asks for the state of all channels).
  • The WTDIO module has two seconds to respond.
  • If the WTDIO fails to respond within two seconds, the Watchdog will immediately poll it again.
  • If the WTDIO fails to repond after three queries, the Watchdog will set the CommunicationsFailure flag and record the failure in Premise's Event log.
  • The Watchdog will sleep for 60 seconds and then repeat the polling process.
  • If the WTDIO responds to a poll, the CommunicationsFailure is reset and the Watchdog sleeps for 60 seconds.
You can create an Alarm that is triggered by the logged Event. The Alarm can be scripted to send email.

There's a lot of new code in this version to support the Watchdog function; we may have some debugging to do! I've added many debugging statements so you should see a fair bit of information in DebugView.

The simplest way to test the Watchdog is to disconnect the WTDIO from the PC (or powerdown the WTDIO) and wait for the next polling cycle (within 60 seconds). DebugView should show the Watchdog's attempts to connect to the WTDIO. After three failed attempts, the CommunicationsFailure property will be set and an Event will be logged (if Builder is open, the Event should appear in a popup message). Now reconnect the WTDIO and wait for the next polling cycle. The Watchdog should find the WTDIO and clear the CommunicationsFailure flag.
 

Attachments

  • WeederTech_15.zip
    9.6 KB · Views: 15
Here's the debug from the current version. I pulled power for a few minutes and then reconnected power. The popup did show up in Home Builder as expected.

Code:
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<OnChangeOnNewData>>
[5328] {Raw Packet: [A3FFE] }
[5328] {Polling response: [3FFE]}
[5328] <<DeleteResponseTimer>>
[5328] <<CreatePollingTimer>>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (1)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (2)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (3)>
[5328] <WTDIO is unresponsive. Will try again later.>
[5328] <<CreatePollingTimer>>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (1)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (2)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (3)>
[5328] <WTDIO is unresponsive. Will try again later.>
[5328] <<CreatePollingTimer>>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (1)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (2)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (3)>
[5328] <WTDIO is unresponsive. Will try again later.>
[5328] <<CreatePollingTimer>>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (1)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (2)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (3)>
[5328] <WTDIO is unresponsive. Will try again later.>
[5328] <<CreatePollingTimer>>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (1)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (2)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (3)>
[5328] <WTDIO is unresponsive. Will try again later.>
[5328] <<CreatePollingTimer>>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (1)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (2)>
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<FailedToRespond>>
[5328] <WTDIO failed to respond to polling. (3)>
[5328] <WTDIO is unresponsive. Will try again later.>
[5328] <<CreatePollingTimer>>
[5328] <<OnChangeOnNewData>>
[5328] {Raw Packet: [A!] }
[5328] {Module [A] was reset.}
[5328] <<DeleteResponseTimer>>
[5328] <<DeletePollingTimer>>
[5328] <<InitAllModules>>
[5328] -> WTDIO
[5328] <Sending Echo Off command>
[5328] <<SendCommand>>
[5328] <Send: [AX0]>
[5328] <Initialize Input Channels>
[5328] --> Channel_A
[5328] <<SendCommand>>
[5328] <Send: [ASA]>
[5328] --> Channel_B
[5328] <<SendCommand>>
[5328] <Send: [ASB]>
[5328] --> Channel_C
[5328] <<SendCommand>>
[5328] <Send: [ASC]>
[5328] --> Channel_D
[5328] <<SendCommand>>
[5328] <Send: [ASD]>
[5328] --> Channel_E
[5328] <<SendCommand>>
[5328] <Send: [ASE]>
[5328] --> Channel_F
[5328] <<SendCommand>>
[5328] <Send: [ASF]>
[5328] --> Channel_G
[5328] <<SendCommand>>
[5328] <Send: [ASG]>
[5328] --> Channel_H
[5328] <<SendCommand>>
[5328] <Send: [ASH]>
[5328] --> Channel_I
[5328] <<SendCommand>>
[5328] <Send: [ASI]>
[5328] --> Channel_J
[5328] <<SendCommand>>
[5328] <Send: [ASJ]>
[5328] --> Channel_K
[5328] <<SendCommand>>
[5328] <Send: [ASK]>
[5328] --> Channel_L
[5328] <<SendCommand>>
[5328] <Send: [ASL]>
[5328] --> Channel_M
[5328] <<SendCommand>>
[5328] <Send: [ASM]>
[5328] --> Channel_N
[5328] <<SendCommand>>
[5328] <Send: [ASN]>
[5328] <Sending Read All command>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<CreatePollingTimer>>
[5328] <<OnChangeOnNewData>>
[5328] {Raw Packet: [AAL] }
[5328] {State Change: [L]}
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_A
[5328] <<OnChangeOnNewData>>
[5328] {Raw Packet: [A3FFE] }
[5328] {Read response: [3FFE]}
[5328] <<SetAllChannelStates>>
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_A
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_B
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_C
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_D
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_E
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_F
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_G
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_H
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_I
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_J
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_K
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_L
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_M
[5328] <<SetChannelState>>
[5328] -> WTDIO
[5328] --> Channel_N
[5328] <<PollWTDIO>>
[5328] <Polling module: [A]>
[5328] <<CreateResponseTimer>>
[5328] <<SendCommand>>
[5328] <Send: [AR]>
[5328] <<OnChangeOnNewData>>
[5328] {Raw Packet: [A3FFE] }
[5328] {Polling response: [3FFE]}
[5328] <<DeleteResponseTimer>>
[5328] <<CreatePollingTimer>>
 
The debug log indicates the WTDIO module was powered down for about 4 minutes and then it was restarted. During this time, the Watchdog polled the WTDIO every minute. Upon restart, the driver initialized the WTDIO. It looks llike this test was succesful.

Please perform one more test. Instead of power-cycling the WTDIO module, simply disconnect/reconnect. Power-cycling causes the WTDIO to transmit a Power-Reset message ("A!") and exercises one part of the driver. Disconnect/reconnect will exercise another part of the driver, namely the Watchdog's ability to detect the presence of the WTDIO.

Please post your results as an attached file (the previous post is a bit loooooong). If it passes this last test, this version of the driver will become the release version.
 
Thanks for the log file.

The second test confirms the Watchdog handles a disconnect/reconnect situation correctly. However, I now realize that it needs to do one more thing.

While the module is disconnected, its channels might change state. When reconnected, the driver and the module will be out of sync unless the Watchdog re-initializes all modules upon re-connection. The latest version of the driver (attached) will handle this situation correctly.

The first test revealed that when the driver receives a Power-Reset message from the WTDIO, it does not clear the CommunicationFailure property. The latest driver version resets this property when it receives a Power Reset from the polled module.

Could you please repeat the two tests and post the resulting two log files. Please pay special attention to the state of the CommunicationFailure property and confirm it is set and reset at the appropriate times.

If the tests are successful, I'll comment out the debugging statements and make this the release version.
 

Attachments

  • WeederTech_16.zip
    9.6 KB · Views: 12
Here's the log file. I tested power first and then cable disconnect.
 

Attachments

  • weeder16.zip
    681 bytes · Views: 26
The log results look good. I think we now have a robust driver. When I have some free time, I'll post the release version in Premise Downloads. Until then, Weeder_16 should serve your needs. Thanks for helping in the development of this driver!
 
The log results look good. I think we now have a robust driver. When I have some free time, I'll post the release version in Premise Downloads. Until then, Weeder_16 should serve your needs. Thanks for helping in the development of this driver!

The thanks goes to you! I've been having this board for quite some time now and am very excited about putting it to use. Hopefully others will be able to get some use out of these relatively cheap IO boards.


On a business note, I've noticed two notifications that the module could not talk to the board, but picked right up on the next poll. I'm not sure why this is happening. It could have something to do with the unorthodoxed set up I have for my serial port (serial-over-lan).
 
Back
Top