DIAdem

cancel
Showing results for 
Search instead for 
Did you mean: 

Confusion over the many ways to represent channels

So I'm making progress on my task, but figuring out the intent of each of these channel representations is still throwing me for a bit of a loop.  So far I've run across...

 

Channel Name      : string       : "MyChannel"

Channel Reference : string       : "[1]/MyChannel"

Channel Number    : integer      : "1"

Channel Object    : object

Channel List      : element list : (seems to be a generic list object)

Channel String    : string       : "1-3,5,7-10"

 

There are probably more I haven't encountered yet.  VBScript's variant-with-subtype nature is making it harder for me to make sense of how everything fits together.  Frequently I *think* the arguments and data types match up only to find out the scripting engine disagrees with me.  In any case, the various channel representations combined the mix of object-oriented and functional APIs is making my head spin.  On top of that, the documentation doesn't seem to be entirely consistent with the naming conventions it uses.

 

Does anyone know why there are so many types of channel represenation and what they are each intended to be used for?

 

0 Kudos
Message 1 of 6
(6,908 Views)

Hi Daklu,

 

Yes, there are several representations of a channel. Some are more historical and supported for compatibility reasons (it should be possible to run a script created in the early days of DIAdem – the mid-1990th - with less modification effort). I will try to give an overview of the different channel representations with some comments.

 

<<< Channel Name: string à Example:  "MyChannelName" >>>

Is one of the channel properties, representing the name of a channel, used to identify and address a channel.

Note: Just a channel name is not a full qualified addressing. If you use just the name DIAdem can find only the first channel with this name.

 

<<< Channel Index: integer à Example: 1 >>>

Is one of the channel properties, representing the index within a channel group of a channel, used to identify and address a channel in a channel group.

 

<<< Channel Reference: string à Example:  "[1]/MyChannelName" >>>

Is a full qualified addressing of a channel, referring to a certain channel group and a certain channel within that group. Possible addressing types: channel group index or name – channel index or name in any combination. Examples for scripting…

 

… REPORT:

Report.ActiveSheet.Objects(1).Curves2D(1).Shape.YChannel.Reference = "[1]/MyChannelName"

 

… DATA-API:

Dim oMyChn
set oMyChn = Data.GetChannel("[1]/MyChannelName")

 

<<< Channel Object: object >>>

Is a full qualified representation of a channel as an object in VBScripts.

Note: This is the new way to work with channels.

Examples:

Dim oMyChn
set oMyChn = Data.GetChannel("[1]/MyChannelName")
…
oMyChn.Name = “MyNewChannelName”
...
Call ChnSmooth(oMyChn,"/Smoothed",12,"maxNumber")

Or 

Dim oMyChn, oMyResChn
set oMyChn = Data.GetChannel("[1]/MyChannelName")
set oMyResChn = Data.Root.ActiveChannelGroup.Channels.Add("MyResult", DataTypeChnFloat64)
...
Call ChnSmooth(oMyChn, oMyResChn,12,"maxNumber")

Or 
Dim oMyChn
set oMyChn = Data.GetChannel("[1]/MyChannelName")
...
Report.ActiveSheet.Objects(1).Curves2D(1).Shape.YChannel.Reference = oMyChn.GetReference(ExtendChnName)

 

<<< Channel List: element list of channel objects >>>

Is a full qualified representation of a list of channel objects in VBScripts.

Note: This is the new way to work with channel lists.

Examples:

Dim oMyChnList, oMyChn, oMyResChn
set oMyChnList = Data.CreateElementList
set oMyChn = Data.GetChannel("[1]/MyChannelName")
set oMyResChn = Data.Root.ActiveChannelGroup.Channels.Add("MyResult", DataTypeChnFloat64)

...

oMyChnList.Add(oMyChn)
oMyChnList.Add(Data.GetChannel("[2]/MySecondChnName"))
Call ChnAverage(oMyChnList,oMyResChn)

 

<<< Channel Number: integer à Example: 1 >>>

Historical channel addressing, should not be used

 

<<< Channel String: string à Example: "1-3,5,7-10" >>>

Historical channel addressing, should not be used

 

I hope this helps and clarifies the different channel representations a bit.

 

Greetings

Walter

Message 2 of 6
(6,896 Views)

Thanks Walter, that does help.  After reading your post and going over the Channel Refences in the help file for the eleventh time, I think I'm understanding it better.  There are still some things that don't make sense to me.  Mostly I think they are either me just not getting it yet or documentation errors.

 

Example 1

If you type the following code, (and assuming you have at least 3 channel groups)

logfilewrite("----------")

dim chList, chan
set chList = data.GetChannels("[3]/*")
logfilewrite("Count: " & chList.Count)
set chan = chList(

 

the pop-up help tells you the input parameter is a reference, but finishing that line with,

 

set chan = chList("[3]/[1]")

 

results in a type mismatch error.  Just this morning I realized it is actually displaying the help for the GetChannels method, not the ChannelList.Index method like it should.

 

 

Example 2

The help for ChnLinGenImp says the return value "is a String variable type. Receives the name of the new channel."

 

logfilewrite("----------")

dim chans(4), i
for i = 1 to 4
	chans(i) = ChnLinGenImp(i, 100, i, 0)
'	chans(i) = ChnLinGen(i, i, i, 100)
	logfilewrite(chans(i))
next

 

If you run this script you'll see it actually returns the channel reference, not the channel name.  The ChnLinGen function also claims to return the channel name but instead returns a reference.

 

 

Example 3

ChnLinGen and ChnLinGenImp also differ from each other in very important way that the documentation doesn't tell users about.

 

logfilewrite("----------")
dim chans(4), groups(2), i, j

data.Root.Clear

for j = 1 to 2
	set groups(j) = data.Root.ChannelGroups.Add("Group" & j)
	data.Root.ChannelGroups(j).Activate
	for i = 1 to 4
		chans(i) = ChnLinGenImp(i, 100, i, 0)
'		chans(i) = ChnLinGen(i, i, i, 100)
		logfilewrite(chans(i))
	next
next

 

If you run the script like this you get the results I (and probably most people) expect.  Two groups each with 4 channels.  But when you replace ChnLinGenImp with ChnLinGen and run the script instead of adding channels to the (active) second group, it overwrites the channels in the (inactive) first group.

 

I had to read the two help pages pretty closely before I understood what is happening.  ChnLinGenImp will always create a new channel in the active group.  The first argument (the crypticly named "GHdChnName") is for what you want the new channel name (as opposed to channel reference) to be.  If the suggested channel name already exists it will append a number to make the new channel name unique.  ChnLinGen's first argument "specifies the result channel," meaning it will accept any argument that resolves to a single channel.  If that channel already exists, it gets overwritten.  ChnLinGen appears to interpret the first i as a channel index rather than a channel name.

 

Intuitively I expect these two functions to behave similarly.  I understand the ability to generate implied channels may have been added years after generating real channels and it may not have been possible to design the ChnLinGenImp behavior to be the same as ChnLinGen, but they are in the same family of functions and when there are behavioral differences between similar functions those differences need to be highlighted.  Once I understood the behavior of these two functions, the documentation made more sense to me.  It did little to alert me about the differences before the fact.

 

Incidentally, I know I can get ChnLinGen to behave the same by simply changing the call to something like,

 

chans(i) = ChnLinGen("[" & j & "]/" & i, i, i, 100)

 

...but the cost of working with an api isn't driven by how long it takes me to type in the correct code, it's driven by how long it takes me to figure out what the correct code should be.  And while these snippets are clearly contrived examples, I believe they illustrate the underlying problem of an inconsistent api and ambiguous (or sometimes just plain wrong) documentation.

 

I'm new to DIAdem and I like the customizability, but I sure hope NI can allocate sufficient resources to fix the shortcomings.

 

 

Message 3 of 6
(6,880 Views)

Here's another example...

 

Example 4

Help for ElementList.Add says the data element can be Root, a ChannelGroup, or a Channel.  What they don't say is the channel must be a channel object. This doesn't work...

 

 

logfilewrite("----------")
dim newChan, chList

data.Root.Clear

set chList = data.CreateElementList
newChan = ChnLinGenImp("Ones", 100, 1, 0)
logfilewrite(newChan)

call chList.Add(newChan)
logfilewrite(chList.Count)

 

The Add method throws a type mismatch error.  So while the channel parameter for ChnLinGen can accept anything that resolves to a single channel--including a channel object, since the default channel object property is the channel number--the channel parameter for ChannelList.Add does not.  It must be a channel object.  i.e.

 

call chList.Add(data.GetChannel(newChan))

 

In retrospect I can understand why channel objects were designed in a way so they would be backwards compatible with existing functions.  And while I don't want to come across as overly critical of the api design, the lack of symmetry between the functional and the object-oriented api is very confusing for new users (at least it is for this particular new user) and it makes it harder to interpret the help files correctly.

 

 

Edit:

Are you sure we shouldn't be using the channel number?  It seems odd for channel objects to return the number as the default property if we're not supposed to use it.

0 Kudos
Message 4 of 6
(6,873 Views)

Correction to my previous post...

 

"ChnLinGen appears to interpret the first i as a channel index number rather than a channel name."

0 Kudos
Message 5 of 6
(6,870 Views)

Hi Daklu,

 

Here are some more information. Hopefully they can clarify you questions a bit.

 

Example 1

In this certain case it is not possible for DIAdem to display the correct tooltip. Please have a look at the DIAdem help with the keyword CodeCompletion.

 

DIAdem Help:

If a method expects an argument and returns a collection, DIAdem does not know whether the expression in parentheses is the argument or the standard element Item. In this case, you must enter Item to get a CodeCompletion list.

 

Example 2

You are right. The information for the command ChnLinGenImp is incomplete. This function always creates a new channel in the default channel group and just the created channel name as return value. We will add this information to the help.

 

Example 3

For most of the DIAdem commands (e.g. not for ChnLinGenImp) for which you can define a target channel name, the following rules are valid:

 

If the channel with this name doesn’t exist a new channel will be created.

If the channel with this name already exists, this channel will be used for the result.

 

But in any case it is a good way to use a full qualified channel addressing and not just a number. Your example but with the Data-API looks like this:

 

logfilewrite("----------")
dim oChans(8)
dim oGroupChns, i, j

for j = 1 to 2
	set oGroupChns = data.Root.ChannelGroups.Add("Group" & j).Channels
	for i = 1 to 4
		set oChans(i) = oGroupChns.Add("MyName_" & str(i), DataTypeChnFloat64)
                call ChnLinGen(oChans(i), i, i, 100)
		logfilewrite(oChans(i).GetReference(ExtendChnName))
	next
next

 

Example 4

In the help to the elementlist you find:

 

Collection of elements in the script interface for internal data. Use the ElementList collection to access channels, channel groups, or the root. You can add elements to the collection or remove elements from the collection. The data in the Data Portal remain unchanged. Every element of the collection ElementList is an Element.

 

And the help to Element describes that it is an object:

 

The Element object provides a single element in the script interface for internal data. An element can be a data set (Root), a channel group (ChannelGroup), or a channel (Channel).

 

Global information

Sometimes we have more than one way to reach the goal. This is in most every case the result being compatible for a very long time. You know, it is not possible to stay all the time just with old conventions. It is necessary to go new ways, being innovative and implementing new functionality. I understand that it is occasionally difficult for customers to find the best staring point or way to come to a solution. And it is our goal to help you with that and to make things easier – and sometimes we need help for this.

 

Greetings

Walter

0 Kudos
Message 6 of 6
(6,835 Views)