LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How should I expand this datalogger to multiple channels?

Solved!
Go to solution

I'm working on a program which will collect data from a USB-6229 DAQ. In its current revision there are a couple of issues, but it does most of what I want it to do. My next goal is to expand the program to allow monitoring of and logging from multiple channels. So, here is my question:

 

1) What is the cleanest way to get this to log from multiple--up to sixteen--channels which could each be measuring different quantities and thus, might require different unit definitions? I know it's possible to select several channels with the "physical channel" control, but as far as I know, all the channels selected that way must have the same units.

 

2) What would be the best way to display up to sixteen channels? I know you can display multiple channels on top of each other in the waveform graph, for example, but any more than three or four data streams and it gets pretty difficult to differentiate them. I thought about making a front panel with sixteen different waveform graphs, but it seems like there should be a more elegant way to do it.

 

Any suggestions are welcome.

0 Kudos
Message 1 of 8
(2,307 Views)

@duwaar wrote:

1) What is the cleanest way to get this to log from multiple--up to sixteen--channels which could each be measuring different quantities and thus, might require different unit definitions? I know it's possible to select several channels with the "physical channel" control, but as far as I know, all the channels selected that way must have the same units.


You can either read them as all voltages and scale them yourself, or you can use DAQmx Create Channel multiple times, each with their own custom scale. Your example code leaves Task In unwired, so just add another Create Channel and wire the Task Out from the first one into the Task In on the second one. Each channel can have its own units that way. You'll have to make a custom scale for each one, which you can do either from MAX (I think) or you can do it programmatically (how I do it).

 


@duwaar wrote:

2) What would be the best way to display up to sixteen channels? I know you can display multiple channels on top of each other in the waveform graph, for example, but any more than three or four data streams and it gets pretty difficult to differentiate them. I thought about making a front panel with sixteen different waveform graphs, but it seems like there should be a more elegant way to do it.


It kind of depends on what you want to look for in the data, but the simplest way is to just throw em all on the same plot. Right click the plot -> Visible items -> Plot legend, then right click the legend text (NOT the line indicator thing) -> Visible items -> Plot visibiltiy checkbox. Now your users can pick which plots they want to display with just the plot legend, which you can move around and expand as you'd like.

0 Kudos
Message 2 of 8
(2,274 Views)

Oh, sweet! I think that graphing solution is exactly what I need.

 

Is there some issue with creating channels in a loop? I ask partly because it sounds like you are saying I should just use several "DAQmx Create Channel" vi's (I may be over-reading) and partly because I have had some problems with doing that. For example, everything runs fine the first time through (create the channel, start collecting data, etc.) but if I stop the data collection and try to create a new channel without killing the vi, the "DAQmx Start Task" vi will throw an error saying that some resource is already being used--even if I explicitly release all the resources in use by a task before stopping it.

0 Kudos
Message 3 of 8
(2,240 Views)

How are you releasing the resources? Clear Task? I've never had a problem creating them in a loop IIRC.

0 Kudos
Message 4 of 8
(2,232 Views)

Yeah, it's under the "Collect Data Stop" case in the vi I attached before. I have tried just stopping and clearing the task, and I have also tried stopping, explicitly releasing the resources with the "DAQmx Control Task" vi, then clearing. In both cases, I got the same error at the same place.

0 Kudos
Message 5 of 8
(2,225 Views)
Solution
Accepted by topic author duwaar

Ah, I see it now. You have an architectural issue and a spelling error 🙂

 

First I would recommend not using the Timeout case of the event structure like that. Sending the same case over and over again is fine when you're collecting data, but when you click Stop, it just goes to the Stop case every 100 ms. You don't want to do *anything* in that case until you click Start again. I'd recommend a Producer/Consumer architecture (or Master/Slave, similar implementation for this case) with a Queue, or perhaps DAQmx events. Just something that only calls cases when you need them. Requiring the use of a Timeout case is often signs of a poor design overall, with notable exceptions for timeout values of -1 and 0 (for initialization routines, for instance). Timeouts can be very handy for User Events as well, but in this case you're basically polling the user interface, which isn't a good way to do things. Separate your data acquisition and your UI and you'll thank yourself later on.

 

Your specific issue here is that in the Collect Data Mode case, you have a Case structure where if you click "Channel setup" it sends the next commanded "frame" to be "Collect data stop". There is no frame called "Collect data stop"- the one you want is "Collect Data Stop". Case structures are, by default, case sensitive, so it's not calling the Stop case, it's calling the Default case, which tries to construct a new channel and everything goes to pot.

 

Right click on the main Case structure and select "Case insensitive match" and it'll work with no errors, or just correct the lowercase text in your selector box to match the correct case.

 

This, by the way, is why I prefer to use typedefs for cases, not strings. Lots of people prefer strings because they're a bit easier to use and are quick, but they have the potential for a spelling error. Strings and typedefs both have their place though, so if you like strings you can stick with it. As a tip, create a new case that's just the default case, and have a popup wired to a "Format into string" function with the argument "Error: no case with the name %s exists", then wire the %s to the inside terminal of the case selector. This will give you a popup when you call a case you *think* exists, but isn't actually there due to a spelling error or capitalization error or something.

Message 6 of 8
(2,220 Views)

Ahhh! Thank you so much! I never would have caught that case mismatch on my own. I would fix that, but I think it's time for a complete re-write.

 

And thanks for those best-practice tips. I really appreciate that. Those will help me quite a bit.

0 Kudos
Message 7 of 8
(2,212 Views)

No problem, it's the little stuff that's the most vexing sometimes 🙂

 

Look at the sample template projects for some good example projects (LV splash screen, New Project, Sample Projects). "Continuous Measurement and Logging (NI-DAQmx)" is a great starting point for doing, well... measurement and logging. Looking at the block diagram can be intimidating at first, but it's a quite well laid out program, and breaks acquisition, logging, and display into separate independent loops. It also has a state machine in the UI Message Loop. I wish there was a state diagram to walk you through what each state is, but it'll at least give you a feel for how you might implement this system, even if you start from scratch rather than modifying the project template. Good luck!

0 Kudos
Message 8 of 8
(2,207 Views)