Button templates and/or object pointers?


Recommended Posts

The next system that I'll be building will monitor pH and temp. for each of 32 batches. I'd like to put up 64 buttons, each showing the current pH or temp for a single channel, and when I push one of them, put the data from that channel on a graph, and do some other related work. Two questions about how to do this:

1. Is there any way to do a button template or prototype, so that when I change the template all the related buttons change accordingly? I see how to do this from a sequence, by naming all of the buttons and then setting all the appropriate stuff as component variables, but this seems clumsy. Is there a better way?

2. What's the best way to write a function (sequence) that deals with any channel, passed to it as a parameter? I see how to do this with the "execute" function, but this seems both slow and clumsy, since I may need a bunch of executes. For instance, a calibrate function would need to change the channel's sampling frequency, read it a bunch of times and do the work, change the frequency back to normal, and clear the history. Is there any way to pass a calibrate function a pointer or reference to a channel object, or must I pass it the name of the channel as a string and make it do ALL work on the channel as "execute" commands? Also, if I pass a channel's input history array as a parameter, is that array updated as the channel continues to be read, or is a static copy of the array passed?

Thanks for any help on these,

j

Link to comment
Share on other sites

Unfortunately, no matter what development tool you use, there are always some clumsy aspects. That is until computer's start thinking for us, and really, I don't think you'd like that. Windows does enough of that already and most of the time it does it wrong. But to answer your questions:

1) There are no component templates in the sense that you change in one place and it changes on all. As of 5.70 there is the ability to add functions / events to components as well as your own custom properties, but its not a template. If you duplicate the component, the code duplicates, but if you then change one, the duplicate does not change. We'll add templates to the list of new features. The trick is trying not to make things too confusing, as half the time you want it to be a template so it changes everywhere, and the other half you wonder why your change affected all the other controls.

That said, you can kind of implement it as a template by using a component function and then having that function call a global sequence function with its name as the parameter. A bit clumsy still. Or you could use the new messaging functionality to actually send the component the code it should execute.

Fortunately we also made it so it will auto-name your components, if you put a number at the end. So if you name your first component Button1, and then duplicate it, the duplicate will be named Button2, etc.

Anyhow, I guess I'm going around in circles. If I was doing your app, was using 5.70+, and wanted to be able to change the code on all 64 buttons in one swoop, I'd probably use either use the user properties feature, or determine the property from the channel name (i.e. use the number at the end so I didn't have to type in Channel1, Channel2, etc. for each component). For the display part, I'd use the OnPaint event and set the Expression to the appropriate channel based on the component name. Then I'd probably create a global variable containing the function code to execute when the button is pressed. I'd assign this code in a startup sequence, and then in the button's event, just do Execute(MyGlobalString).

The trick to this method is to understand that Execute() can be used on multiple lines of code with a single call. Just put a chr(10) at the end of each line. So you might do (I'd recommend a different variable name!):

global string MyGlobalString

MyGlobalString = "private x = 2" + chr(10)

MyGlobalString += "x++" + chr(10)

MyGlobalStirng += "? x" + chr(10)

Now if you did Execute(MyGlobalString), it would run that code in whatever context you did the execute(). So you can use local variables from a component, even though they don't exist in the global scope where you created this string. The nice part about it is that you can just edit this string to change all components that use it.

2) Unfortunately, DAQFactory does not yet have pointers, or for those that are scared of the word "pointer", references. We are working on it rapidly and it should be in place by release 6.0. In general, if you are advanced enough to want to use pointers, you might want to consider just using variables instead of channels. With 5.70+ (at least on non-Express versions), there are functions to allow you to add values to variables just like a channel. Its much faster, but you lose the ability to use built in Logging sets (not export sets), and broadcasting, and would have to trigger alarm checking manually. Oh, and you'd have to script the polling loops. But, again, if you are doing advanced stuff, you probably are scripting this stuff anyway so you have more control.

Again I ramble. Until there are pointers, you are going to have to use Execute(). Remember though that you can do a single Execute() command and run lots of code as I described above. A single Execute() with 5 lines will run faster than 5 executes with a single line.

Currently, all function parameters are passed by value, so if you pass a channel history, it copies the current contents first, so any changes to this array will not affect the history.

We hear your pain and are working on making things easier without having the computer think to much for you. 5.7 is a step in the right direction and by 6.0 your dreams will come true B).

Note that 5.7 is that latest release of DAQFactory and is available from our website at www.azeotech.com. Upgrades are free. The Express version of 5.7 has not been released, mainly because we haven't updated the samples, but we'll probably just release it next week and update the samples afterwards. One of the big changes in 5.7 that affect LabJack users in particular is the updated driver that supports almost all the functions of the UD as is, meaning the code you would enter to work with the UD in C, or VB, or other languages, and thus the pseudo code in the LabJack manuals, is almost identical to the code used in DAQFactory, with the exception of streaming, which DAQFactory largely handles for you.

Link to comment
Share on other sites

Thanks very much for the informative reply. There are a lot of ideas there, and some of it is new information for me (I hadn't looked at the new messaging and user property features yet), so it will take me some time to think about and try some of your suggestions.

For the button templates, I was already planning on putting most of the real work in a sequence that they'd all call. What I'd really like in a template, so I could easily change it later, is stuff like colors, text format, etc. I know that can all be set as object variables, but a template would be nice.

Any sense on when 6.0 might be available? Need a beta tester?

Thanks again for the prompt response!

Link to comment
Share on other sites

I forgot to mention. Another thing about 5.7 is that you can select multiple components and change common properties on these components all at once. Among the common properties are the event and function script, so, to some extent, if you need to update script you can just select all the components and make the change. Of course this only really works if the components are on the same page, or overlayed pages.

No sense on 6.0. We just released 5.7, so the programmers deserve at least a day off! We are always looking for beta testers. Send an inquiry using our online form at www.azeotech.com with your interest.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.