Open dpshepherd opened 1 month ago
pinging @linshaova, since he just this week has also been struggling with this
The easiest explanation would have been that your card does not support ChangeDetection, but it looks like it does. Can you generate a Trouble Report (Help > Report a Problem), in which you (re-) load the config file?
The NIDAQ adapter generate the Blanking properties only when the call to hub.StartDOBlankingAndOrSequence()
succeeds. That function has some logging output, but it will only appear in debug mode. Hopefully this will shed some light on the issue, but it may be very difficult to fix without access to the hardware (and avoid breaking support for other hardware in the interim).
I can confirm that this model supports ChangeDetection, as we use that property in our own python DAQ control class to control both digital and analog waveform playback.
I'll ask the team to generate the logs.
Here is the report. nidaq_problem_report.txt
pinging @linshaova, since he just this week has also been struggling with this
(probably unrelated to the current topic, but wanted to express my gratitude...)
Thanks for the ping @tlambert03 ! I didn't know about the TriggerInputPin
property of the digital I/O device (while playing with DAQmx in Labview or Python, I found AO and DO tasks can be programmed to share the same PFI as trigger input, hence I had assumed the same for the NIDAQ adapter in uManager). After I connected the PFI trigger to TriggerInputPin (which is p0.31 on my device), I saw the digital sequence being correctly executed. Also blanking works as advertised if I enable it by mmc.setProperty('NIDAQDO-Dev1/port0', 'Blanking', 'On')
.
Here is the key to the problem:
2024-06-10T10:11:39.461152 tid21440 [dbg,dev:NIDAQHub] Created DI task
2024-06-10T10:11:39.466330 tid21440 [dbg,dev:NIDAQHub] Starting on-demand task
2024-06-10T10:11:39.466401 tid21440 [dbg,dev:NIDAQHub] Created task
2024-06-10T10:11:39.467145 tid21440 [dbg,dev:NIDAQHub] Created DO channel
2024-06-10T10:11:39.472429 tid21440 [dbg,dev:NIDAQHub] Wrote Digital out with task autostart: 0
2024-06-10T10:11:39.474882 tid21440 [dbg,dev:NIDAQHub] Stopped task
2024-06-10T10:11:39.475322 tid21440 [dbg,dev:NIDAQHub] Created DI task
2024-06-10T10:11:39.475853 tid21440 [dbg,dev:NIDAQHub] Created DI channel for: Dev1/port0/line4
2024-06-10T10:11:39.475894 tid21440 [dbg,dev:NIDAQHub] Configured change detection timing to use Dev1/port0/line4
2024-06-10T10:11:39.475914 tid21440 [dbg,dev:NIDAQHub] Routed change detection timing to /Dev1/ChangeDetectionEvent
2024-06-10T10:11:39.496855 tid21440 [dbg,dev:NIDAQHub] Started DI task
2024-06-10T10:11:39.497279 tid21440 [dbg,dev:NIDAQHub] Created DO task
2024-06-10T10:11:39.498010 tid21440 [dbg,dev:NIDAQHub] Created DO channel for: Dev1/port0/line0:3
2024-06-10T10:11:39.498053 tid21440 [dbg,dev:NIDAQHub] Configured sample clock timing to use /Dev1/ChangeDetectionEvent
2024-06-10T10:11:39.511634 tid21440 [IFO,dev:NIDAQHub] Specified digital channel contains more bits than supported by the 8-bit version of DAQmx Port Write.
[ ] Use the version of DAQmx Port Write that supports wider digital ports.
[ ] Minimum Write Size (In Bits): 32
[ ]
[ ] Task Name: DOBlankTask
[ ]
[ ] Status Code: -200565
2024-06-10T10:11:39.526527 tid21440 [dbg,dev:NIDAQHub] Stopped task
2024-06-10T10:11:39.526557 tid21440 [dbg,dev:NIDAQHub] Starting on-demand task
2024-06-10T10:11:39.526597 tid21440 [dbg,dev:NIDAQHub] Created task
2024-06-10T10:11:39.527324 tid21440 [dbg,dev:NIDAQHub] Created DO channel
2024-06-10T10:11:39.532776 tid21440 [dbg,dev:NIDAQHub] Wrote Digital out with task autostart: 0
So, NIDAQ advises that the digital port is 32 bits and needs to be addressed as such. The confusing thing is that NIDAQ also reports (correctly I believe) that the port is an 8 bit port (it looks from the documentation that port0 is an 8 pin port and I believe that you also have 8 bits port1 and port2, is that correct?). The NIDAQ adapter has different versions of the function hub.StartDOBlankingAndOrSequence()
for 8, 16, and 32 pin ports, and the adapter chooses the 8 pin version based on the information this port is 8 pins (obtained using the call to DAQmxGetPhysicalChanDOPortWidth
).
https://knowledge.ni.com/KnowledgeArticleDetails?id=kA0VU0000000R6f0AE&l=en-US may be relevant.
What is really strange to me is that setting the output pins high or low directly seems to work for you, and that code uses the exact same (8bit) DAQMx Port Write function.
I could try to catch this error on initialization, then try to instantiate the 32 bit version and hope for the best, but I would feel a lot better more fully understanding what is going on.
The confusing thing is that NIDAQ also reports (correctly I believe) that the port is an 8 bit port (it looks from the documentation that port0 is an 8 pin port and I believe that you also have 8 bits port1 and port2, is that correct?).
Correct. There are three ports, each with eight lines. And two analog outputs.
In Python using PyDAQMx, we only use the PFI pins for capturing input information and ChangeDetection. The relevant setup code from our adapter class (modified for readability here) should be:
import PyDAQmx as daq
channelDI_trigger_from_camera = "/Dev1/PFI0"
channelDI_start_trigger = "/Dev1/PFI1"
channelDI_change_trigger = "/Dev1/PFI2"
taskDI = daq.Task()
taskDI.CreateDIChan("/Dev1/PFI0", "", daq.DAQmx_Val_ChanForAllLines)
# Configure change detection timing (from wave generator)
taskDI.CfgInputBuffer(0) # must be enforced for change-detection timing, i.e no buffer
taskDI.CfgChangeDetectionTiming("/Dev1/PFI0", "/Dev1/PFI0", daq.DAQmx_Val_ContSamps, 0)
# Set where the starting trigger
taskDI.CfgDigEdgeStartTrig("/Dev1/PFI0", daq.DAQmx_Val_Rising)
# Export DI signal to unused PFI pins, for clock and start
taskDI.ExportSignal(daq.DAQmx_Val_ChangeDetectionEvent, "/Dev1/PFI2")
taskDI.ExportSignal(daq.DAQmx_Val_StartTrigger, "/Dev1/PFI1")
The problem is later, when actually sending a digital out sequence to the port using
DAQmxWriteDigitalU8(doTask, samplesPerChan, false, DAQmx_Val_WaitInfinitely, DAQmx_Val_GroupByChannel, samples, numWritten, NULL);
If you are able to compile the NIDAQ adapter, you can try hard coding portWidth_
in NIDigitalOutputPort.cpp
to 32 bit, and see if that works correctly.
Also, can select other ports than port0? If so, do those fail the same way for ChangeDetection?
Also, can select other ports than port0? If so, do those fail the same way for ChangeDetection?
Selecting the other ports individually or selecting all together produces the same error.
If you are able to compile the NIDAQ adapter, you can try hard coding portWidth_ in NIDigitalOutputPort.cpp to 32 bit, and see if that works correctly.
Yes, we can do this. It will probably take a week or two as we'll need the time to setup the build environment.
@nicost - we are starting to work on this. Is there a reason you used an older NIDAQ-mx version for the library? Version 9.2.2 was released in 2010.
No reason other than that it works and the adapter binary is nicely compatible with many runtime version of NIDAQmx. Is there anything specific function you would like to use that is not in the headers of 9.2.2?
Not necessarily, just curious because we've not tested our Python code against that older version. I was also going to try compiling against a newer version once I got it working with 9.2.2.
However, I'm having some trouble building the driver correctly with 9.2.2, partially because I'm having to guess what files should be in the 3rdpartyprivate
to build the adapter. I assume it should be be the .h and .lib file with the described directories, but I'm still getting build failures.
Layout is:
NationalInstruments/DAQmx_9.2 /include/NIDAQmx.h /lib64/msvc/NIDAQmx.lib
Thanks! I have that layout but am getting errors with NIDAQ.
I can build MMCore, DemoCamera, etc.. successfully so I'll keep troubleshooting.
Feel free to post the errors, maybe I (or Mark) can help.
FWIW, here is the output when I build this in VS:
Build started...
1>------ Build started: Project: MMDevice-SharedRuntime, Configuration: Release x64 ------
1>MMDevice.cpp
1>ModuleInterface.cpp
1>MMDevice-SharedRuntime.vcxproj -> C:\projects\micro-manager\mmCoreAndDevices\build\Release\x64\MMDevice-SharedRuntime.lib
2>------ Build started: Project: NIDAQ, Configuration: Release x64 ------
2>NIDAQ.cpp
2>NIAnalogOutputPort.cpp
2>NIDigitalOutputPort.cpp
2>C:\projects\micro-manager\mmCoreAndDevices\DeviceAdapters\NIDAQ\NIDigitalOutputPort.cpp(135,60): warning C4018: '>=': signed/unsigned mismatch
2>C:\projects\3rdpartypublic\boost-versions\boost_1_77_0\boost\math\common_factor_rt.hpp(14,1): warning C4081: expected 'identifier'; found 'string' (compiling source file NIDAQ.cpp)
2> Creating library C:\projects\micro-manager\mmCoreAndDevices\build\Release\x64\mmgr_dal_NIDAQ.lib and object C:\projects\micro-manager\mmCoreAndDevices\build\Release\x64\mmgr_dal_NIDAQ.exp
2>Generating code
2>Previous IPDB was built with incompatible compiler, fall back to full compilation.
2>All 1878 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
2>Finished generating code
2>NIDAQ.vcxproj -> C:\projects\micro-manager\mmCoreAndDevices\build\Release\x64\mmgr_dal_NIDAQ.dll
2>Done building project "NIDAQ.vcxproj".
========== Build: 2 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
I've verified that all of the PATH variables are correct and match what you posted above. I am building via the command line because I have nearly no experience with ant, visual studio, etc... I am using VS2019 for the build and DAQMX v9.2.2. I kept MMCore
in this build to show that it builds correctly.
Very strange. The linker is unable to resolve the symbols that can be found in NIDAQmx.lib
. The path to that file (as can be found in /LIBPATH
looks correct to me. You could try:
grep DAQmxGetSysDevNames NIDAQmx.lib
which for me returns:
Binary file NIDAQmx.lib matches
but it would be very surprising if that were the problem.
B.t.w., it has become quite easy to work with VIsual Studio. You should be able to open the micromanager.sln file (refuse to let it update the toolsets), and build straight from the code checked out from github (as long as the 3rdparty libraries are there). Doubt that will make a difference for you though, your command line build does the same thing.
@marktsuchida, any ideas why the link step fails for @dpshepherd?
Perhaps unlikely, but I think LNK2001 can be caused, among other things, by the .lib having the wrong architecture (32-bit in this case). To check this, you can use dumpbin /headers NIDAQmx.lib
in the Developer PowerShell (or Command Prompt) for Visual Studio. It will print a lot of headers but each will have a Machine
line saying x86 or x64.
Other than that, I don't have any ideas at the moment, since all the compile and link commands look correct to me.
Thanks both! I'll check and redownload the SDK if necessary. The library should be for x64 right?
The library should be for x64 right?
Yes.
I figured out the compilation issue. The installer for NIDAQmx has multiple places with compiler support. The correct header and library files for the NIDAQ device driver are found at Program Files (x86)\National Instruments\Shared\ExternalCompilerSupport\C\include
and Program Files (x86)\National Instruments\Shared\ExternalCompilerSupport\C\lib64
.
When you install compiler support, there also is a Program Files (x86)\National Instruments\NI-DAQ\DAQmx ANSI C Dev
directory, but this only contains the 32-bit (x86) header and library.
Using the correct location, we can compile the NIDAQ device driver.
We'll work to modify as requested and report back.
Hi @nicost -
We are testing the new NIDAQ adapter, it is very nice! We are able to setup our digital output port0, control light switches, and it appears that the sequencing is working based on our oscilloscope. However, there aren't any "blanking" associated properties in the device property browser available when we add the device. It is clear from the digital output that the excitation is not being controlled by the "EXPOSURE OUT" signal from the camera. The NIDAQ webpage mentions it, so I'm hoping it is available and we just need to set up our .cfg file differently.
We are using a USB-6341, X-Series. What else can we provide to help troubleshoot?
Thanks!!