06-20-2019 01:43 PM
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.
Solved! Go to Solution.
06-21-2019 10:59 AM
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.
06-21-2019 11:19 AM
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.
06-24-2019 09:45 AM
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
06-24-2019 10:20 AM
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
06-25-2019 09:05 AM
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?
06-25-2019 10:00 AM
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
06-26-2019 12:34 PM
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
06-26-2019 04:03 PM - edited 06-26-2019 04:04 PM
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...
07-01-2019 05:49 PM
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!