Mensuration device parameterization scheme [VERY long]

Hi,

Apologies in advance for the length of this post. :< But, it's probably an unusual design issue for most of the designs that are likely encountered here.

Basically, what I am trying to do is come up with a

*generic*, *extensible* means for configuring "devices" AT RUN TIME without a priori knowledge of the devices' characteristics. I'm pretty sure there isn't an *ideal* way of doing this -- but I am hoping for something that is at least "adequate" :>

I'm prototyping this under Inferno as it is *great* for hacking together ideas quickly (though as a production environment, it has been disappointing).

For purposes of example, I have a scale (i.e., a device that is used to measure mass) that I want to talk to. The scale is cabled to a "computer" (let's say PC just to save typing). A copy of Inferno runs on that PC. An application runs under that Inferno instance that communicates with the scale continuously. For this particular scale, that's just a serial port and the communication consists of ASCII messages passed between the PC and the scale (i.e., easy to prototype). This allows that application to determine:

- if the scale has been unplugged/powered off

- if the scale has slipped into a different "mode" (the scale has intelligence; perhaps a user has done something that has told it to change its behavior in a way that makes it unuseful to "us"; or, perhaps it needs to be re-told to behave the way that we *want* it to behave -- reinitialized)

- if the scale appears to need to be re-tared etc. This allows the local intelligence to handle many of these problems without involving the "application" itself.

In essence, the constant communication serves as a (poor) substitute for embedding the "application" within the scale itself (since we don't want to have to design scales!)

[Remember, "PC", "scale", "serial", "ASCII" are just for the purpose of this example -- something I can quickly play with -- but I am looking for a more general purpose solution/approach in all this]

The application running on that PC acts as a server -- it "serves up" the scale to *other* applications. Those applications might be running on that same PC or elsewhere on the network.

Under Inferno, it is common to represent device interfaces as points in a device-specific file hierarchy. For example, a serial port may look like:

.../uart/data .../uart/control .../uart/status

where "..." represents some parent path anchoring the file tree into the overall namespace.

In this case, reading "data" would give you the most recently received character (the read could block until a character was available; or, could return some indication if none was present so your application could elect to spin on it). Likewise, *writing* "data" would let you push a character *out* the port.

Writing to "control" could let you alter parameters that govern the operation of the serial port. So, writing "baud 19200" would cause the baudrate to be set to 19200.

Reading from "status" could report transmission errors (framing, parity, etc.) for the most recent character read from "data". Or, it could tell you how deep the incoming FIFO is. Or, whatever else you decide it *should* do.

[N.B. the Inferno implementation has their own notion of how serial ports should work. My example is for illustration, only]

Of course, this all works because there is something

*active* hiding behind these filesystem names. I.e., when you write "baud 19200" to "control", you are actually passing a message to a piece of code that interprets it and actually causes the baudrate to be changed in the hardware. Presenting the interface in the filesystem (like UN*X) is just a convenient way of getting to it (using fwrite's instead of some ad hoc API like "write_UART_control_register()", etc.) [N.B. There are other *huge* wins to this approach in the namespace but they aren't germane, here]

OK. So, thinking of how to model a generic *mensuration* device, you could envision a similar interface:

.../device/data .../device/control .../device/status

where:

"data" would be read only (since these devices *produce* data, they don't *consume* it!) and would present the "current 'reading'";

"status" would qualify the most recently read "data";

and

"control" would let the application control any of the mensuration/reporting characteristics of the device.

Referencing this to a "scale", one possible design:

"data" would indicate the weight of the object;

"control" would allow the application to specify the units of measurement (pounds vs. kg)

and

"status" might report the accuracy to be expected in the weight reported (i.e., the scale might have an accuracy of "+/- 0.5 pounds or 2%" so a 1 pound measurement might be [0.5,1.5] whereas a 100 pound measurement might be [98,102])

The problem lies in the fact that mensuration devices have far more parameters than these obvious ones. These need to be reported to *and/or* controlled by the application.

For example, a scale would have a range of weights that it can accommodate. For a bathroom scale, perhaps [0,300] (when I was a kid, scales were [0,200]. I guess newer scales reflect the fact that we're getting fatter as a society :< ). For a pallet scale, [0,2000] might be a better range!

Of course, a scale can't report weights with infinite resolution. A postal scale might report tenths of ounces while one used for measuring shipping containers or rail cars might just hope for the nearest hundredweight.

Scales might have different reporting rates. Depending on the technology used, these might be faster or slower than other scales. A related issue -- reporting LATENCY -- might also vary (e.g., a scale that reports weights via a serial interface has inherent transmission delays that a scale which reports by a parallel A/DC).

And, we've already mentioned the issue of accuracy along with units of measure...

OK, so each of these parameters can be ascertained by simply endowing the interface with appropriate reporting and controlling means. This could take the form of a lengthier "status" message: "range [0,200] resolution 0.5 rate 12 latency 0.35" or equivalent. Alternatively, the namespace could be cluttered a bit more to support: .../device/range .../device/accuracy .../device/rate .../device/resolution .../device/latency wherein each handle reports a single parameter (e.g., reading "range" returns "[0,200]").

OK, with that *background* in place, the real issue lies in devices (which, nowadays, are *smart* and highly configurable) that can change their characteristics easily.

So, I might be able to configure the hypothetical scale to report a wider range of weights if I am willing to settle for less (absolute) accuracy. Or, perhaps, update the weight report more frequently if I settle for less resolution. Etc.

But, how do you design a *generalized* interface that lets the application(s) examine the characteristics of each device at run time to chose how best to configure the device for their particular needs? One approach would be to list the devices' capabilities in some standardized form of indeterminant length (i.e., you don't know a priori how many different *ways* a device can be configured!). So, a report might be:

range [0,200] resolution 0.1 accuracy +0.5 -0.5 1% range [0,500] resolution 0.5 accuracy +2 -2 1% range [100,1000] resolution 1.0 accuracy 2%

etc. The application would then have to parse each "line" (i.e., possible configuration) to find the one that is most appropriate to its (current!) needs.

Another approach is to have a *single* configuration reported -- the *current* configuration. Then, allow the application to change parts of this configuration (via a "control" port) and examine the consequences of that change.

So, the default configuration might be:

"range [0,200] resolution 0.1 accuracy +0.5 -0.5 1%"

If the application now sends the message (command) "range [200,400]" to the device, it (remember, the "device" is actually a piece of code sitting between the *real* device and the application) can use its own heuristics to decide how it can satisfy this configuration requirement. In this example, it might opt to pick the configuration:

"range [100,1000] resolution 1.0 accuracy 2%"

The application can examine this and further refine its desired configuration by sending "resolution 0.1" which would cause the device to reconfigure itself as:

"range [0,500] resolution 0.5 accuracy +2 -2 1%"

Etc.

Of course, the fallacy in all this is how you handle cases where the requested configuration *can't* be met! I.e., what if the application sought a resolution of 0.1? Or, even 0.05? How do you report to the application the choices that it has available in this case?? (since this interface model doesn't report "lists of configurations" but, rather, just the *current* configuration!)

A trial and error algorithm could have the application keep tweaking its requested configuration (e.g., resolution 0.4, resolution 0.3, etc.) until the device complains and then deduce the approximate limits available from the device. But, that's kind of crappy.

Have I missed a third possibility? Or, is this just one of those problems that can't be solved nicely?

Thanks!

--don

Reply to
D Yuniskis
Loading thread data ...

9500 chars in your post, but you can't type in a real name and email address?
Reply to
Jim Stewart

And it certainly seemed unusual for the first couple of paragraphs until I realised I'd misread the title and it wasn't a "Menstruation device parameterisation scheme" :-P

Nobby

Reply to
Nobby Anderson

You'll note there *is* a real name on my post. As for an email address: why would I want to open the door to spammers? :-(

Reply to
D Yuniskis

SCPI (skippy) or XML or something..

Reply to
bigbrownbeastie

+1. I was thinking GPIB as I read the OP.
Reply to
L!TH!UM

Hmmm... this was interesting but, I think, misses the mark that I'm aiming for.

It seems to be focused on how to bring the controls of the various instruments *to* the application (and, probably, to the *user*). I.e., a standardized interface for controling 'scopes, function generators, etc.

To put this in the context of my "scale" example, if the scale had a built-in "memory" function (think of a bathroom scale that remembers your weight from the prior day), this IVI interface would want to *expose* that function to the user through the API.

By contrast, I deliberately want to *hide* all of these details in the "driver" (within the device "server"). I want it to focus on getting the data of interest to the application -- not the details of how the instrument goes about getting that data!

E.g., if I want a certain accuracy or resolution THAT THE DEVICE AVERTISES AMONG ITS CAPABILITIES, then I will explicitly acknowledge my unconditional acceptance of the magic by which the instrument acquires that data at that accuracy/resolution -- without having to get involved in maniulating the individual settings on the instrument!

For this example, the application doesn't care if the scale can measure in pounds vs. kilograms vs. stones! All that matters is that the application knows that "(ALL) scales present their data in units of XXXX". The driver/server that virtualizes the scale figures out how to configure the scale for "whatever" units and convert *those* into the "XXXX" units that, BY CONVENTION, the applications expect.

(if the application then wants to present those values to the human user in some *other* units, the application can perform the necessary conversion)

The IVI interface is *fat* and heavy. It is unlikely that it would scale well to real-time control. And, probably hasn't been designed with that in mind (since it seems to strive to just replace the human operator's fingers on the various instrument dials -- and since those instruments aren't typically designed to react quickly to user actions).

I need something that lets me quickly convey the info that an application needs and explore capabilities without executing millions of instructions.

I *think* I've figured out an approach that will let me do this. I need to hack together a protoype before I can formally specify it -- so I can see "from example" if there are any big holes that I've missed. Thankfully, Inferno is a reasonably good platform for "quick and dirty" ;-)

Thanks!

--don

Reply to
D Yuniskis

Well, it took a while to prototype (bad time of year to get anything *done* :< ) but this seemed to work quite well. I still haven't figured out how to resolve conflicting requests -- except to push that decision into the applications themselves -- but, as with anything "new", experience will suggest a suitable fix.

Reply to
D Yuniskis

Ooops! That was intended for an email message! :-( (a hazard of having email and news handled in the same client!)

Sorry...

D Yuniskis wrote:

Reply to
D Yuniskis

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.