Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

How to distribute vb6 app without installing NIDAQmx

I found several posts that mentioned that this was difficult if not possible.  I hope someone at NI is listening, because this is a serious defect in the software if its true....
 
I have a VB app that we use on about 300 computers.  Maybe 20 of those use an NI digital IO board, mostly PCI-DIO-96.  Previously I had been using version 6 and just including the DIO ocx control in my vb6 project.  I needed to add support for a new card, 6528.  According to the web site, I had to upgrade to NiDAQmx to use the new card.  So I updated my project, recompiled the installer package and thought I was done.  Of course, now I find out that the exe won't run on the 280 PCs that don't use the NI card because I have to install the NI software separately!   It takes 15 minutes or more to install the package, plus having to visit each PC.  That is crazy!
 
So I either have to spent 5 weeks updating all the PCs, or don't support the new card, or maybe find a better IO board supplier.
 
Someone tell me I'm wrong, please!  I will gladly add all the dll's to my project manually if that will work, but I tried manually copying them to eliminate the missing dll errors but then got an initialization error (maybe need to register each one too?)
 
Help!
 
Matt
0 Kudos
Message 1 of 17
(5,992 Views)

Hey Matt,

I understand your frustration. You could call a batch file that launches the DAQmx installation (even silently) so that you do not need to do this. I am not aware, however, of Visual Basic 6.0 installers' capability to launch a batch file after installing. It might be possible, but I have not heard of a way to launch a .bat file after installation using the built-in installer capability. That being said, once the application is run, you could check whether the DAQmx driver is installed (through several different methods, most basically a file existence check) and, based on that response, launch the DAQmx installer from the Visual Basic code. With this method, you could silently launch the DAQmx installation (or even a DAQmx runtime version if space is a problem).

Another way you could ensure that DAQmx is installed during installation is to use another application (such as CVI or LabVIEW) to provide a more customized installer. For instance, with CVI installers, you have the ability to target your distributables to whatever directories you wish and the DAQmx installer is a built-in capability. Even using Visual Basic .NET, you have the ability to launch batch files (*.bat) post-installation.

Are these 300 computers not the same image?  Typically in lab situations, several computers would use the same image.  In that case, you could install DAQmx on the image.

Best regards,

Thanks,

Andy McRorie
NI R&D
0 Kudos
Message 2 of 17
(5,975 Views)
Hey Matt,
 
Another thing that you could do in your application that might help is this:
 
If you are not needing DAQmx in every instance of the application, you could only load the DAQmx driver if the functionality is required.  To do this, you could isolate all DAQmx calls into a separate DLL.  Then you can load that DLL at runtime (via late-binding in VB) only if DAQmx is installed on the system (If it's not, you could install it at that point).  This way, you won't always need DAQmx to be installed on the computer, and you can load it only when the DAQ card is required.
 
By the way, in my previous post a referenced a method to check a file existence to see if DAQmx is installed.  A good file to reference is nicaiu.dll, which is always located in the system32 folder.  If that file is not present, DAQmx is not installed.
Thanks,

Andy McRorie
NI R&D
Message 3 of 17
(5,958 Views)

The suggestion for "late-binding" sounds like it may work, but I haven't used that before.  Is there example code I can copy  (I haven't googled it yet to check)?

The root cause though is the decision by NI to change the architecture.  I'm sure there are 100 reasons why it was done, but the end result is an inconvience to the the end (paying) customer.  If you have a means to bring it to the attention of the right people, maybe someone will put it back the way it was....1 install and done.  Isn't that kind of the point of Visual Basic and ocx controls?  The only reason to install the whole thing should be if I need to use some of the other tools or interfaces. 

Thanks for your suggestions!

Matt

0 Kudos
Message 4 of 17
(5,952 Views)

Sorry, I wasn't aware of the term.  Sure, I can do a CreateObject() to get a nidaq object.  I'm still trying to find the correct object to create, something like CreateObject("NiDAQmxCAPI.DAQmx").  Any hints would be appreciated.

Matt

0 Kudos
Message 5 of 17
(5,934 Views)
Hi Matt,
 
I understand your frustration of finding an appropriate and simple method of distribution when deploying your VB applications that incorprate NI-DAQmx.  We evolved going from Traditional DAQ to NI-DAQmx for multiple reasons that all benefit you.  I would check out the Advantages of NI-DAQmx and Answers to Frequently Asked Questions about NI-DAQmx and Traditional NI-DAQ (Legacy) tutorials. These documents provide some great insights into our choices of heading down the DAQmx path. 
 
Since you are distributing your applications that need the DAQmx driver, I would suggest checking out the NI-DAQmx Run-time Engine Version 8.3 for Windows 2000/XP download page that gives you options of downloading reduced versions of the driver. On that website, you will notice 4 different versions of the run-time engine you can choose from. 
 
As far as examples and information about using NI-DAQmx in Visual Basic 6, I would check out the NI-DAQmx Support in Visual Basic 6.0 and NI-DAQmx Examples for Visual Basic 6.0 KnowledgeBases. 
 
If you are interested in the late binding concepts Andy mentioned, check out the MSDN article Using Early Binding and Late Binding in Automation
 
I know you are using Visual Basic 6, but there is an awesome tutorial out there entitled Transition from Traditional NI-DAQ (Legacy) to NI-DAQmx using Microsoft Visual Basic .NET.
 
Hope this helps!
 
Best Regards,
Jonathan N.
National Instruments
0 Kudos
Message 6 of 17
(5,919 Views)

Probaly I should be more clear.  I am only interested in Digital IO, I don't use any other functions.  I have a very simple app that just sets and reads IO.  This is a pseudo-excerpt of my code...

    ' Create the DAQmx task.
    DAQmxErrChk DAQmxCreateTask("INPUT", taskHandle)
    
    DAQmxErrChk DAQmxCreateDOChan(taskHandle, daq_str, "INPUT", DAQmx_Val_ChanForAllLines)
    
    ' Start the task running, and read from the digital lines.
    DAQmxErrChk DAQmxStartTask(taskHandle)
    DAQmxErrChk DAQmxReadDigitalLines(taskHandle, 1, 10#, _
        DAQmx_Val_GroupByChannel, readArray(0), arraySizeInBytes, _
        sampsPerChanRead, numBytesPerSamp, ByVal 0&)

Currently I include the reference "NiDAQmxCAPI" into the project to allow this to execute.  This does not work for me because then I have to install another app (either the big NiDAQ or the runtime) before my program will even run, whether or not it needs to use the NiDAQ card.  What I need is help to do the above without the reference included in my project, which means it should run fine as long as it does not call a NiDAQ function.  On the small number of computers that need NiDAQ, I will install the NiDAQ software.  Does anyone have that solution?  I think it should be simple, but all the URLs etc... just dance around the concept, no concrete examples.  I'm thinking it would be something like...

   set my_daq = CreateObject( "nidaqmxcapi.daqmx" ) <==this doesn't work in reality

    ' Create the DAQmx task.
    DAQmxErrChk my_daq.DAQmxCreateTask("INPUT", taskHandle)
    
    DAQmxErrChk my_daq.DAQmxCreateDOChan(taskHandle, daq_str, "INPUT", DAQmx_Val_ChanForAllLines)
    
My code is mostly just cut-and-paste from the DIO example code (suggestion:  update the examples to show whatever solution we come up with here).  I'm not a pro developer so I'm not doing rocket science...

 

Matt

 

 

0 Kudos
Message 7 of 17
(5,918 Views)
Hi Matt,
 
The DAQmx C API is not object oriented and thus you cannot instantiate objects. Its C based and therefore the CreateObject method will not work. When we mentioned late-binding, we should have been a litte more clear on what we meant. Basically, you are going to have to abstract out your DAQmx calls and put those in a DLL that you create.  This DLL will be statically linked to the DAQmx type library via adding the type library as a reference to the project.  Then your main project will dynamically load that DLL when needed. When you load that DLL is up to you which would be based off your conditions of determining if DAQmx is going to be used.
 
Anyway, hope this clears things up. Sorry for the misconfusion.
 
Best Regards,
Jonathan N.
National Instruments
Message 8 of 17
(5,894 Views)
OK, I've spent some time updating my software.  Basically my original project continues with the CWDAQ ActiveX object but has an option to use the DAQmx.  When that option it chosen it calls a routine like that shown below which creates an ActiveX object from a dll.  The dll is one that I wrote that makes the actual calls and has the reference to the NiDAQ C API.  Therefore my application can install and run without any NI software installed, only stations using an NI device need the software.
 
I have found one problem, though.  Once NiDAQmx 8.x is installed the CWDAQ 6 ActiveX object can no longer access any ports on the device.  It shows up in the list of "Legacy" devices, but the number of ports is 0.  The test panels work, but neither my app or the example software works. When my app is running that's OK because the correct version of NiDAQ would be installed, but for development it's a pain because I can't validate both the CWDAQ and the NiDAQmx with the same configuration of my workstation.  I would have to reinstall 7.4, test CWDAQ, reinstall 8.3, test NiDAQmx.   Am I missing some sort of configuration secret to get both to work at the same time (or at least with just a config change to swap back and forth)?
 
Thanks for your help (although I'm still irritated at NI for making this so difficult!)
 
Happy New Year
 
Matt
 
 
====================
 
Public Function nidaq_write(dev_name As String, port_num As Integer, io_val As Long)
    Dim my_daq As Object
    Dim status As String
   
    On Error Resume Next
    Set my_daq = CreateObject("GumpDAQmx.NiDAQ")
    If err.Number = 0 Then
        status = my_daq.nidaq_write(dev_name, port_num, io_val)
    Else
        status = err.Description
        err.Clear
    End If
    If status <> "OK" Then
        MsgBox status
        status = "NiDAQmx or the nidaqmx.dll is not installed"
    End If
    nidaq_write = status
End Function
 
The function in my dll
 
Public Function nidaq_write(dev_name As String, port_num As Integer, io_val As Long)
    Dim i As Integer
    Dim sampsPerChanWritten As Long
    Dim arraySizeInBytes As Long
    Dim writeArray() As Byte
    Dim daq_str As String
    Dim mask As Long
    Dim status As String
   
    On Error GoTo ErrorHandler
   
    If taskHandle <> 0 Then
        StopTask
        taskHandle = 0
    End If
   
    arraySizeInBytes = 8
    '  Re-initialize an array that holds the digital values to be written
    ReDim writeArray(arraySizeInBytes)
    mask = 1
    status = ""
    For i = 0 To arraySizeInBytes - 1
        If io_val And mask Then
            writeArray(i) = 1
            status = status & "1"
        Else
            writeArray(i) = 0
            status = status & "0"
        End If
        mask = mask * 2
    Next
    'do_msgbox "Writing: " & status
   
    ' Create the DAQmx task.
    DAQmxErrChk DAQmxCreateTask("OUTPUT", taskHandle)
   
    ' Add a digital input channel to the task.
    Select Case dev_name
        Case IO_NIDAQMX_DEV1
            daq_str = "Dev1/"
        Case IO_NIDAQMX_DEV2
            daq_str = "Dev2/"
        Case IO_NIDAQMX_DEV3
            daq_str = "Dev3/"
        Case IO_NIDAQMX_DEV4
            daq_str = "Dev4/"
    End Select
   
    daq_str = daq_str & "port" & port_num & "/line0:7"
    ' Add a digital output channel to the task.
    'daq_str = "Dev1/port0/line0:7"
    DAQmxErrChk DAQmxCreateDOChan(taskHandle, daq_str, "OUTPUT_CHANNEL", DAQmx_Val_ChanForAllLines)
   
    ' Start the task running, and write to the digital lines.
    DAQmxErrChk DAQmxStartTask(taskHandle)
    DAQmxErrChk DAQmxWriteDigitalLines(taskHandle, 1, True, 10#, DAQmx_Val_GroupByChannel, writeArray(0), sampsPerChanWritten, ByVal 0&)
   
    ' All done!
    StopTask
   
    nidaq_write = "OK"
    Exit Function
ErrorHandler:
    status = Err.Description
    If taskHandle <> 0 Then
        DAQmxStopTask taskHandle
        DAQmxClearTask taskHandle
        taskHandle = 0
    End If
    nidaq_write = status
End Function
0 Kudos
Message 9 of 17
(5,793 Views)
Hi Matt,

The CWDAQ ActiveX controls are purely for Traditional NI-DAQ and do not work with NI-DAQmx.  You can have both drivers installed on the same system.  You can use Traditional NI-DAQ and NI-DAQmx at the same time if you have two DAQ devices and one of them is using Traditional NI-DAQ and the other NI-DAQmx.   If you only have one DAQ device, you can still use both Traditional NI-DAQ and NI-DAQmx but only in sequence – not at the same time. You need to reset your device to switch between Traditional NI-DAQ and the NI-DAQmx driver as part of the sequence.  Refer to the How Do I Convert My Configuration from Traditional NI-DAQ to NI-DAQmx? KnowledgeBase for information.  

Hope this helps!

Best Regards,

Message Edited by Jonathan N on 01-10-2007 01:25 PM

Jonathan N.
National Instruments
0 Kudos
Message 10 of 17
(5,782 Views)