Premise Millisecond resolution timers in VB

Motorola Premise
I was poking at a driver in VB, wanting to have a light weight millisecond resolution timer to change the button Press state to Hold state after 500ms. Attached is a first cut of a driver that seems to work. It would be good to know if anyone else finds this useful. It is a weird sort of driver in that it is not a container and does not create controller objects. You just interact with the driver object itself. Source included of course.
 

Attachments

  • Premise mstimer.zip
    32.9 KB · Views: 3
Modified to optionally add assignment of a specific value in order to, in my case, change the value of the Button State directly. So one can optionally specify "[property name]=[value]" rather than just specifying the property name. Still defaults to otherwise setting the property to TRUE/1.
 

Attachments

  • Premise mstimer.zip
    33.2 KB · Views: 6
Do you have an example you can share?
btw, welcome to the cult...
 
Thanks for taking the time to share this and welcome!  I think your idea is cleaver and a worth-while endeavor.
 
As you probably discovered, the addtimer method in Premise was not designed for millisecond resolution (and this sucks anytime you want to use a timer to reset a button state, etc...).  This thread thoroughly documents the previous issue and a sloppy workaround I found using a timer of zero length (in a module that uses the buttonstate property):  http://cocoontech.com/forums/topic/16340-addtimer-mishap-caught-in-debugview-and-repeatable/
 
My testing of your code:

To test your add-in, I used the attached xdo file.  It employs a for loop to delay vbscript program execution, a DelayMacro, and of course your add-in "mstimer."  I also used DebugView to view what was going on within the module.

 
I initially tried your method using debugview on a test machine (with no for loop delay) and it worked well, within +/- 10 ms for a small sample size of 100.  I've attached the excel file showing the scatter plots for 10ms and 100ms.  This is on a test machine install of Premise with no other devices.
 
However, since vbscript stuff is ran in a common thread, there is no guarantee that the property will be triggered in x milliseconds as the property will still be part of a vbscript based module, and as such, it will be reliant on the programmatic flow of the vbscript interpreter.  Sadly, this is the case as demonstrated by the attached module and discussed below.
 
A few issues and recommendations:
  • I cannot get DeleteTimer to work without throwing an error (upon the first restart, thereafter there is no error, but nothing happens).  I've attached the xdo I used for my test.  To test it just create a TestTimer device object.
  • I think it would be useful if your add-in could be passed vbscript, and then create a scriptmacro containing that vbscript, trigger the scriptmacro, then delete it.  I'm not sure how much this would degrade the performance (if at all), but I can test such an add-in if you have time to create it.  However, what would be lost is whatever "this" points to, so such a feature may not be useful in all cases.
  • It appears this will not work reliably if there is anything else tying up program execution (for vbscripts/modules).  To test this theory, my attached module uses a loop delay (just a for loop followed by a debugout once loop execution is complete).  This delay is called whenever the test is started.  Note that for ~6 seconds, nothing happens.  I think this is a limitation to the vbscript interpreter that Premise (aka SYS) uses.  Add-ins by themselves run in their own thread, but since yours is interacting with a module, it becomes reliant on program flow of the vbscript interpreter.  This throws a wrench into what you are attempting to do.
DISCLAIMER:  I'm not a professional programmer and learned programming for the sole purpose of building Premise modules in vbscript.  I welcome a discussion on how to solve this issue (as it would improve a few of my modules), but I don't think there is a solution (besides never using modules and only add-ins).
 

Attachments

  • TestTimer.zip
    12.1 KB · Views: 2
  • error.png
    error.png
    29 KB · Views: 10
Supposedly I was signed up to receive posting notifications, but apparently not.
 
Apparently I did not test using a NULL object. I will look at that.
 
Yes, the notification can indeed be easily delayed. Premise uses the ActiveScript engine, and all callbacks are performed on the same thread. Additionally, although the timer may update the object without too much delay (in fact, you could likely probe the value and see that it has indeed been changed), synchronizing with the VBScript execusion is another matter.
 
Yes, just passing a script, or a path to a method would be useful. I was trying to decrease overhead, but at some point the thing has to sync with the scripting engine. Plus the whole context issue with a this pointer.
 
Actually, I was vbscript in an attempt to delay rewriting an old Premise driver to use a new interface I have to its bus, which changes completely how packets are handled (Phast/Panja h/w with an interface I finally got working to talk directly to the Lonmark bus, removing the MCU). The timer was just to handle things like transitioning a button Press to a Hold, or AutoReset of a relay.
 
Thanks for the response.  This confirms my understanding.  Since normal timers have the same limitation, I'd use your solution any day over my half-baked zero length timer work around that I used in several modules posted here (such as the W800RF32 module).
 
I haven't gotten into using the SDK as I'm not a programmer, but is there any way to install the timer add-in someplace other than devices?  
I think it would be neat if it was installed under the system library (sys://Schema/System/), so it could be called in a similar manner to the native addTimer method.  Devices are instances of a given module class.  So calling a device method directly from a module doesn't really follow the typical Premise architecture, although it works and there's nothing wrong with doing it if we have to.
 
fischershaw said:
Supposedly I was signed up to receive posting notifications, but apparently not.
 
Apparently I did not test using a NULL object. I will look at that.
 
Yes, the notification can indeed be easily delayed. Premise uses the ActiveScript engine, and all callbacks are performed on the same thread. Additionally, although the timer may update the object without too much delay (in fact, you could likely probe the value and see that it has indeed been changed), synchronizing with the VBScript execusion is another matter.
 
Yes, just passing a script, or a path to a method would be useful. I was trying to decrease overhead, but at some point the thing has to sync with the scripting engine. Plus the whole context issue with a this pointer.
 
Actually, I was vbscript in an attempt to delay rewriting an old Premise driver to use a new interface I have to its bus, which changes completely how packets are handled (Phast/Panja h/w with an interface I finally got working to talk directly to the Lonmark bus, removing the MCU). The timer was just to handle things like transitioning a button Press to a Hold, or AutoReset of a relay.
 
I was still in need of a high resolution timer to flash LED indicators within VB, and redid the original attempt. This version relies on two components, a driver (install and then ignore), and a VB module (classes & global scripts). In this version one calls a global function to create/delete by name a Timer object, which are placed into a single folder, like the built-in timers.
 
Since I wanted to stay away from synchronizing with ActiveScript, a Timer can have a sequence of Intervals that are triggered in a round-robin fashion, and each Interval can then set multiple properties. All so I can flash the silly LED on & off from VB.
 

Attachments

  • hrtimer.zip
    33.2 KB · Views: 3
After using this for a bit, corrected errors and such.
 
Always runs the Terminal.
Added a Force flag to property value changes.
 

Attachments

  • hrtimer.zip
    33.8 KB · Views: 3
Back
Top