Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

NI-USB 6525 Not getting register_signal_event callbacks with cfg_change_detection_timing

Solved!
Go to solution

I'm toggling inputs on an NI-USB6525 and trying to detect the change with a Python script.

I'm able to write the lines and read them successfully after the write, but I am not detecting the changes. I can set an input to True or False and then use another script to manually read the input and get the correct result. I need this script to automatically detect the change.

import sys
import time
import nidaqmx

def readControlSimulator(niDaqDevice = "Dev1"):

    # On NI-USB6501 all IOs are configurable.
    # On NI-USB6525 port0 are outputs, port1 are inputs.
    INPUT_PORT = 'port1'

    # read command line arguments
    for arg in sys.argv[1:]:
        niDaqDevice = arg

    # Set up NIDAQ line detection for all lines
    with nidaqmx.Task() as task:        
        # Will only work if using a compatible device.
        try:
            print("SET UP CHANGE DETECTION")
            task.di_channels.add_di_chan(niDaqDevice + '/' + INPUT_PORT + '/line0:7')
            task.timing.cfg_change_detection_timing(rising_edge_chan = niDaqDevice + '/' + INPUT_PORT + '/line0:7',
                                                    falling_edge_chan = niDaqDevice + '/' + INPUT_PORT + '/line0:7',
                                                    sample_mode=nidaqmx.constants.AcquisitionType.CONTINUOUS)

            def callback(task_handle, signal_type, callback_data):
                print("CHANGE LINE")
                return 0

            task.register_signal_event(nidaqmx.constants.Signal.CHANGE_DETECTION_EVENT, callback)
            task.start()
        except nidaqmx.DaqError as e:
            print(str(e))

    time.sleep(10)

if __name__ == '__main__':
    readControlSimulator()

The code should print "CHANGE LINE" if a line changes, but it doesn't.

Thanks for any and all help.

0 Kudos
Message 1 of 10
(3,661 Views)

Hi hthrun,

 

Thanks for reaching out. Sorry you are having issues. I'm a little bit unsure about what works and what doesn't for you. Could you provide a few more details on what you can read, and what you can't?

 

Secondly, have you tried any of the shipping examples for python that we have. These might be a good place to start to just continuously read digital data in from a port, and toggle a boolean on and off to read it.

Keddy C.
Staff Software Engineer
National Instruments
0 Kudos
Message 2 of 10
(3,629 Views)

Hi Keddy,

Thanks for the response.  In the code I posted I'm not seeing the callback function run even though I'm toggling the lines.  I am able to read all the lines and am currently using a polling method like what you described.  I am hoping that I can replace the polling with the interrupt callback from the change detection.  This is ultimately going to be in a gui and using the change detection would greatly reduce its workload and also increase the responsiveness.

 

0 Kudos
Message 3 of 10
(3,626 Views)

Hthrun,

 

What do you have as the values of your variables in the callbacks. It's setup correctly, but it's not obvious why it's not changing detection. Could you print before, and after it to ensure it's at least executing, and not breaking out of the function?

 

Secondly, could you see if just reading the lines works instead of using the change detection callback?

 

Thanks! Goodluck

Keddy C.
Staff Software Engineer
National Instruments
Message 4 of 10
(3,613 Views)

Hi Keddy,

For the values in the callbacks, do you mean the parameters task_handle, signal_type, and callback_data?

I tried printing before and after with reading lines and that works, it just doesn't appear to get into the callback.

Here's updated code with more prints:

import sys
import time
import nidaqmx
import logging
              
def readControlSimulator(niDaqDevice = "Dev1"):
    
    # On NI-USB6501 all IOs are configurable.
    # On NI-USB6525 port0 are outputs, port1 are inputs.
    INPUT_PORT = 'port1'
    
        # Function for reading a line
    def readLine(lineNumber):
        # Read the corresponding line
        with nidaqmx.Task() as line:
            try:
                line.di_channels.add_di_chan(niDaqDevice + '/' + INPUT_PORT + '/line' + str(lineNumber))
                logging.debug("HPT line {} = {}".format(lineNumber, line.read()))
            except nidaqmx.DaqError as e:
                logging.debug(str(e))
                    
    # read command line arguments
    for arg in sys.argv[1:]:
        niDaqDevice = arg
   
    logging.basicConfig(format="%(asctime)15s - %(levelname)8s: %(message)s", level=logging.DEBUG)
    
    for line in range(8):
        readLine(line)
                
    # Set up NIDAQ line detection for all lines
    with nidaqmx.Task() as task:        
        # Will only work if using a compatible device.
        try:
            logging.debug("SET UP CHANGE DETECTION")
            task.di_channels.add_di_chan(niDaqDevice + '/' + INPUT_PORT + '/line0:7')
            task.timing.cfg_change_detection_timing(rising_edge_chan = niDaqDevice + '/' + INPUT_PORT + '/line0:7',
                                                    falling_edge_chan = niDaqDevice + '/' + INPUT_PORT + '/line0:7',
                                                    sample_mode=nidaqmx.constants.AcquisitionType.CONTINUOUS)
            
            def callback(task_handle, signal_type, callback_data):
                logging.debug("task_handle {}".format(task_handle))
                logging.debug("signal_type {}".format(signal_type))
                logging.debug("callback_data {}".format(callback_data))
                logging.debug("CHANGE LINE")
                return 0
        
            task.register_signal_event(nidaqmx.constants.Signal.CHANGE_DETECTION_EVENT, callback)
            task.start()
        except nidaqmx.DaqError as e:
            print(str(e))
    
    time.sleep(10)
    for line in range(8):
        readLine(line)
    return
                
if __name__ == '__main__':
    readControlSimulator()
    

And here's the output I get while playing with the connected switches:

 

$ py src/read_controlSimulator.py
2019-06-24 10:17:04,370 - DEBUG: HPT line 0 = False
2019-06-24 10:17:04,374 - DEBUG: HPT line 1 = True
2019-06-24 10:17:04,377 - DEBUG: HPT line 2 = True
2019-06-24 10:17:04,381 - DEBUG: HPT line 3 = False
2019-06-24 10:17:04,385 - DEBUG: HPT line 4 = False
2019-06-24 10:17:04,388 - DEBUG: HPT line 5 = False
2019-06-24 10:17:04,391 - DEBUG: HPT line 6 = False
2019-06-24 10:17:04,395 - DEBUG: HPT line 7 = False
2019-06-24 10:17:04,395 - DEBUG: SET UP CHANGE DETECTION
2019-06-24 10:17:14,434 - DEBUG: HPT line 0 = True
2019-06-24 10:17:14,438 - DEBUG: HPT line 1 = False
2019-06-24 10:17:14,442 - DEBUG: HPT line 2 = False
2019-06-24 10:17:14,446 - DEBUG: HPT line 3 = False
2019-06-24 10:17:14,450 - DEBUG: HPT line 4 = False
2019-06-24 10:17:14,455 - DEBUG: HPT line 5 = False
2019-06-24 10:17:14,458 - DEBUG: HPT line 6 = False
2019-06-24 10:17:14,462 - DEBUG: HPT line 7 = False

0 Kudos
Message 5 of 10
(3,609 Views)

Hthrun,

 

Sorry for not being clear. Yes, do you have those values set somewhere else? What you have in there are just the default ones, correct?

 

Capture.PNG

Keddy C.
Staff Software Engineer
National Instruments
Message 6 of 10
(3,600 Views)

Hi Keddy,

That may be where I need help.  The code I'm posting here is the entire script.  When I was troubleshooting and read that description earlier I wasn't sure what to set them to, especially the callback_data.  I tried some different things and was unsuccessful.  Here's my latest attempt, setting the task_handle to task, the signal_type to CHANGE_DETECT_EVENT, and callback_data to 1 because I didn't want to unregister the function:

import sys
import time
import nidaqmx
import logging
              
def readControlSimulator(niDaqDevice = "Dev1"):
    
    # On NI-USB6501 all IOs are configurable.
    # On NI-USB6525 port0 are outputs, port1 are inputs.
    INPUT_PORT = 'port1'
    
        # Function for reading a line
    def readLine(lineNumber):
        # Read the corresponding line
        with nidaqmx.Task() as line:
            try:
                line.di_channels.add_di_chan(niDaqDevice + '/' + INPUT_PORT + '/line' + str(lineNumber))
                logging.debug("HPT line {} = {}".format(lineNumber, line.read()))
            except nidaqmx.DaqError as e:
                logging.debug(str(e))
                    
    # read command line arguments
    for arg in sys.argv[1:]:
        niDaqDevice = arg
   
    logging.basicConfig(format="%(asctime)15s - %(levelname)8s: %(message)s", level=logging.DEBUG)
    
    for line in range(8):
        readLine(line)
                
    # Set up NIDAQ line detection for all lines
    with nidaqmx.Task() as task:        
        # Will only work if using a compatible device.
        try:
            logging.debug("SET UP CHANGE DETECTION")
            task.di_channels.add_di_chan(niDaqDevice + '/' + INPUT_PORT + '/line0:7')
            task.timing.cfg_change_detection_timing(rising_edge_chan = niDaqDevice + '/' + INPUT_PORT + '/line0:7',
                                                    falling_edge_chan = niDaqDevice + '/' + INPUT_PORT + '/line0:7',
                                                    sample_mode=nidaqmx.constants.AcquisitionType.CONTINUOUS)
            
            def callback(task_handle=task,
                         signal_type=nidaqmx.constants.Signal.CHANGE_DETECTION_EVENT,
                         callback_data=1):
                logging.debug("task_handle {}".format(task_handle))
                logging.debug("signal_type {}".format(signal_type))
                logging.debug("callback_data {}".format(callback_data))
                logging.debug("CHANGE LINE")
                return 0
        
            task.register_signal_event(nidaqmx.constants.Signal.CHANGE_DETECTION_EVENT, callback)
            task.start()
        except nidaqmx.DaqError as e:
            print(str(e))
    
    time.sleep(10)
    for line in range(8):
        readLine(line)
    return
                
if __name__ == '__main__':
    readControlSimulator()
    

And here are the following results, same as last time:
$ py src/read_controlSimulator.py
2019-06-25 09:53:58,757 - DEBUG: HPT line 0 = True
2019-06-25 09:53:58,760 - DEBUG: HPT line 1 = True
2019-06-25 09:53:58,766 - DEBUG: HPT line 2 = True
2019-06-25 09:53:58,772 - DEBUG: HPT line 3 = False
2019-06-25 09:53:58,777 - DEBUG: HPT line 4 = False
2019-06-25 09:53:58,781 - DEBUG: HPT line 5 = False
2019-06-25 09:53:58,786 - DEBUG: HPT line 6 = False
2019-06-25 09:53:58,791 - DEBUG: HPT line 7 = False
2019-06-25 09:53:58,792 - DEBUG: SET UP CHANGE DETECTION
2019-06-25 09:54:08,838 - DEBUG: HPT line 0 = False
2019-06-25 09:54:08,842 - DEBUG: HPT line 1 = False
2019-06-25 09:54:08,847 - DEBUG: HPT line 2 = True
2019-06-25 09:54:08,852 - DEBUG: HPT line 3 = True
2019-06-25 09:54:08,856 - DEBUG: HPT line 4 = False
2019-06-25 09:54:08,860 - DEBUG: HPT line 5 = False
2019-06-25 09:54:08,865 - DEBUG: HPT line 6 = False
2019-06-25 09:54:08,871 - DEBUG: HPT line 7 = False

Do I need to set those values differently?

Thanks for all the help,

Henry

0 Kudos
Message 7 of 10
(3,597 Views)
Solution
Accepted by topic author hthrun

Hi hthrun,

 

That looks a little better to me, but I still think your task value might be wrong. Check out this KB on how it should be formatted:

 

https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z0000019TuoSAE&l=en-US

 

Message 8 of 10
(3,591 Views)

Thanks for the link, SSPTest.  I tried updating my callback based on the information:

            def callback(task_handle=task._handle,
                         signal_type=nidaqmx.constants.Signal.CHANGE_DETECTION_EVENT,
                         callback_data=1):
                logging.debug("task_handle {}".format(task_handle))
                logging.debug("signal_type {}".format(signal_type))
                logging.debug("callback_data {}".format(callback_data))
                logging.debug("CHANGE LINE")
                return 0

But I still got the same output.  Does anything else look wrong?

I'm wondering if anyone else has a 6525 they could try running this script with...

0 Kudos
Message 9 of 10
(3,586 Views)

Someone on Stack Overflow was able to help me out.  I simply needed to put time.sleep(10) in the with nidaqmx.Task() statement.

Thanks for all the help!

0 Kudos
Message 10 of 10
(3,544 Views)