High-Speed Digitizers

cancel
Showing results for 
Search instead for 
Did you mean: 

Python with NI-SCOPE DLL

Hi, I'm trying to use ctypes in Python to import the NI-SCOPE_32.DLL and interface with a 5105 and 5124.

So far, I have successfully (I think) created a new session with the 5124. I can't do anything else as trying to access any constants results in an error such as "AtrributeError: function 'NISCOPE_VAL_NORMAL' not found" when trying to access any of these constants. I can look in the niscope.h file and see that they are #defined, but it seems the compiled DLL doesn't contain these definitions, or I can't access them for some reasons. Has anybody got this to work correctly or have any advice?
0 Kudos
Message 1 of 9
(8,969 Views)
Hi snelltaylor,

 

National Instruments has not tested our drivers in the Python environment, and does not officially support Python. Other users have had success getting drivers working in unsupported environments before, and hopefully they can give some assistance. I may also suggest posting on the LAVA forums, which is an active LabVIEW community.

Regards,


David L.
Systems Engineering
National Instruments
0 Kudos
Message 2 of 9
(8,950 Views)


@snelltaylor wrote:
Hi, I'm trying to use ctypes in Python to import the NI-SCOPE_32.DLL and interface with a 5105 and 5124.

So far, I have successfully (I think) created a new session with the 5124. I can't do anything else as trying to access any constants results in an error such as "AtrributeError: function 'NISCOPE_VAL_NORMAL' not found" when trying to access any of these constants. I can look in the niscope.h file and see that they are #defined, but it seems the compiled DLL doesn't contain these definitions, or I can't access them for some reasons. Has anybody got this to work correctly or have any advice?

As you might have already realized, you could use the actual numeric value which is represented by NISCOPE_VAL_NORMAL - remember that #define is a compiler directive to substitute the literal with whatever value compiler encounters on that line, so the compiled niscope_32.dll will certainly not know anything about the string literal NISCOPE_VAL_NORMAL (which is defined as IVISCOPE_VAL_NORMAL which is defined as 0, just FYI).

Now, niscope_32.dll links in some type library information which makes constants such as NISCOPE_VAL_NORMAL usable in an environment such as Visual Basic 6.0, but I am not sure how one goes about importing the type library information into Python to get to these constant definitions. To actually see what I mean, you can download OLEViewer utility from Microsoft (you might have to get an additional dll to get this to work properly), and load niscope_32.dll to view its type library information.

But, as far as using NI-Scope functions in Python, I had no problems as long as I used the actual numeric values for parameters.
Regrads,
Sead Suskic
National Instruments
Message 3 of 9
(8,937 Views)
Thanks for the input. I had been looking for the #define's in the headers, and found them, but the definitions were just to other strings - such as IVISCOPE_VAL_NORMAL.

Where would I go about finding what the values these represent are? Do I just have to chase them down through the headers?

Also, what kind of value should I be getting back from the niScope_init function? Right now, it gives a return value of -10something, maybe 5 or 6 digits, but the viSession pointer (which I pass using ctypes.byref()) ends up with a value of 0. The two booleans that are passed were just Python's False, so the function call looked like:

import ctypes
scope = ctypes.cdll.niscope_32
viSession = ctypes.c_long() #do I need a value here for an actual variable rather than null?
scope.niScope_init("PXI2::13::INSTR",False,False,ctypes.byref(viSession))

Does this seem reasonable? Am I missing something big here?

Thanks,
Sean
0 Kudos
Message 4 of 9
(8,938 Views)


@snelltaylor wrote:
Thanks for the input. I had been looking for the #define's in the headers, and found them, but the definitions were just to other strings - such as IVISCOPE_VAL_NORMAL.

Where would I go about finding what the values these represent are? Do I just have to chase them down through the headers?

Also, what kind of value should I be getting back from the niScope_init function? Right now, it gives a return value of -10something, maybe 5 or 6 digits, but the viSession pointer (which I pass using ctypes.byref()) ends up with a value of 0. The two booleans that are passed were just Python's False, so the function call looked like:

import ctypes
scope = ctypes.cdll.niscope_32
viSession = ctypes.c_long() #do I need a value here for an actual variable rather than null?
scope.niScope_init("PXI2::13::INSTR",False,False,ctypes.byref(viSession))

Does this seem reasonable? Am I missing something big here?

Thanks,
Sean

Sean,

As far as deciphering the various #define's, you will have to look at niscope.h, iviscope.h, and perhaps even ivi.h. Namley, anything IVISCOPE_VAL_xxx will most likely be defined in iviscope.h, and anything IVI_VAL_xxx should be in ivi.h. There might be some definitions elsewhere, but little grep-ing ought to get you all you need. This is where the type library information would come in very handy, but again, I am not sure how to do this in Python.

NI-Scope functions will return a ViStatus (a signed 32-bit integer). Value of 0 means that the function succeeds without an error, a negative value indicates an error, while a positive indicates a warning - one can usually ignore the warnings, while the errors usually mean some run-time condition that will prevent further predictable execution.

In you specific case (from the code snippet), I believe that the first parameter is invalid ("PXI2::13::INSTR"), and niScope_init() function does not generate a valid session - hence the value of 0 for ViSession (by the way, your ViSession definition is just fine). Specifically, the first  parameter for niScope_init() needs to be the device name that you see in MAX under Devices and Interfaces >> NI-DAQmx Devices (something like "Dev1", or "PXI1Slot5", or something similar - you can also give it your own name (both 5105 and 5124 are DAQmx devices). Refer to the NI-Scope (a.k.a. NI High Speed Digitizers Help) for more details on the functions and their parameters.

Hope this helps.
Regrads,
Sead Suskic
National Instruments
Message 5 of 9
(8,922 Views)
Sead,

Thank you for the input. I've been looking through the headers and getting the values for the constants. The only ones I can't find are NISCOPE_VAL_TRUE and NISCOPE_VAL_FALSE, though I'm just going to assume that those are 1 and 0 respectively.

I've replaced name with the name from Max, I though that the IVI logical name was the entire PXI2::etc . . .

Now with the line:

scope.niScope_init(name,False,False,ctypes.byref(session))

I get a return value of 0. I haven't tried any further function yet, but will shortly.

Again, thank you for the input.

Sean
0 Kudos
Message 6 of 9
(8,918 Views)
Another problem has popped up using niScope_ConfigureVertical.

The line is:

scope.niScope_ConfigureVertical(session,1,10,0,1,1,1), and I'm getting the error "WindowsError: exception: access violation reading 0x00000001". First what *should* I be using for the channelList? Just a string, integers? If I try to use a string, Python states that the right number of bytes aren't being sent to the command (12 bytes missing). When using the integer, I'm assuming it gets cast to a long, so I'm not sure where the 12 bytes are coming from.

Thanks,

Sean
0 Kudos
Message 7 of 9
(8,902 Views)
To reply to my own post (since I couldn't find any option to edit), it seems any function I try to use doesn't like the viConstString channelList. Whatever integer I put in for the channel shows up as hex in the previous posted error. What value should I be putting there?

Thanks,
Sean
0 Kudos
Message 8 of 9
(8,904 Views)


@snelltaylor wrote:
To reply to my own post (since I couldn't find any option to edit), it seems any function I try to use doesn't like the viConstString channelList. Whatever integer I put in for the channel shows up as hex in the previous posted error. What value should I be putting there?

Thanks,
Sean

So, it appears that it's not really the issue in viConstString (at least I am not seeing it for niScope_ConfigureVertical function) As you might have discovered, viConstString is const char *, and Python should not have problems with this.

Here is what I did to actually execute the function without any Python run-time errors:

>>> vertRange = c_double(10)
>>> vertOffset = c_double(0)
>>> probeAtt = c_double(1)
>>> scopeDll.niScope_ConfigureVertical(session, "0", vertRange, vertOffset, 0, probeAtt, 1)

Range, offset, and probe attenuation parameters are of the 64-bit floating point (double) type, and it appears that conversion that was happening with the constants the way you provided them ended up passing to the function 32-bit values (which would explain the missing 12 bytes).

Incidentally, to be completely correct, the last parameter is ViBoolean (unsigned short), so I would have instantiated another variable:

>>> vertRange = c_double(10)
>>> vertOffset = c_double(0)
>>> probeAtt = c_double(1)
>>> enabled = c_ushort(1)
>>> scopeDll.niScope_ConfigureVertical(session, "0", vertRange, vertOffset, 0, probeAtt, enabled)

I hope that this helps.

Regrads,
Sead Suskic
National Instruments
Message 9 of 9
(8,875 Views)