Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Control digital output using nidaqmx in python

Solved!
Go to solution

Hello

 

I am new to the combination of python and NI Daqmx. I managed to downlaod all needed packages/libraries and want to controll 3 digital outputs using python.

I am aware that the page http://nidaqmx-python.readthedocs.io/en/latest/index.html

exists, however, the syntax there is unclear to me and I would need some examples in order to understand the syntax on that webpage.
I am familiar with C, C++, and Matlab.

 

System:

Device: NI USB-6008

Python 3.6.4 (using PyCharm)

Windows 7

 

What I want to control: port 0 line 0:2 as digital output

What should it do: Set digital output on or off in order to switch connected relais.

 

My questions:

1) How can I address a channel? e.g. port 0 line 0

2) How do I tell a channel whether it is input or output?

3) How do I tell the Daqmx that I want to switch the state (off -> on)?

 

Thank you very much for your attention and I am glad upon each feedback.

0 Kudos
Message 1 of 7
(16,198 Views)
Solution
Accepted by topic author ucalmonte

Hi,

 

I think you will find this example helpful:

https://github.com/ni/nidaqmx-python/blob/master/nidaqmx_examples/do_sw_timed.py

Best Regards,
TK
Certified LabVIEW Architect (CLA)

0 Kudos
Message 2 of 7
(16,182 Views)

Hi,

 

thanks for the hint, however, in my opinion these examples are not that helpful for a beginner as there is no prober explanation of the code.

best regards

uc

0 Kudos
Message 3 of 7
(16,154 Views)

# Each port has 8 lines. This function will take each port it's activated lines.
# Assuming the lines start from 0 to 7
def activate_lines(mod_name, port1_lines, port2_lines, port3_lines):
sum_port1_line = 0
for i in range(0, len(port1_lines)):
val = port1_lines[i];
sum_port1_line += 2**val;

sum_port2_line = 0
for i in range(0, len(port2_lines)):
val = port2_lines[i];
sum_port2_line += 2**val;

sum_port3_line = 0
for i in range(0, len(port3_lines)):
val = port3_lines[i];
sum_port3_line += 2**val;

#Set all channels to output channels (standard configured as input at start-up of module)
# Module1, 2742xxxx
with nidaqmx.Task() as task:
task.do_channels.add_do_chan(mod_name + '/port0/line0:7')
task.do_channels.add_do_chan(mod_name + '/port1/line0:7')
task.do_channels.add_do_chan(mod_name + '/port2/line0:7')
List = [sum_port1_line, sum_port2_line, sum_port3_line]
print("Binary values for each port:")
print(List)
task.write(List)
time.sleep(0.200)
return


def get_lines_forSpecificCase(case_num):
return {
# CaseNum: [[port_0],[port1],[port2]]
# Keep in mind index starts from 0, I have 18 test cases in total with 20 relays to be controlled(0-17), in each case I have to control certain line with NI6501 

# so lets take case zero as an example, 0 : [[4], [1,6], [3]],  [4] means that I am making line 0.4 (port 0) high output and other lines are low and so on for the other ports(1,2)
0 : [[4], [1,6], [3]],
1 : [[4,5,6], [1,6], [3]],
2 : [[4], [1,6], [1,2,3]],
3 : [[1,2,4], [1,6], [3]],
4 : [[0,4], [1,6], [3]],
5 : [[4,7], [1,6], [3]],
6 : [[3,4], [1,6], [3]],
7 : [[3,4], [1,6], []],
8 : [[7], [1,6], [3]],
9 : [[4], [], [3]],
10: [[], [1,6], [3]],
11: [[4], [1,6], []],
12: [[7], [1,6], [0]],
13: [[4], [3], [1,2]],
14: [[5,6], [0,4], [3]],
15: [[7], [1,3,6,7], [0]],
16: [[7], [0,1,4,6], [0]],
17: [[1,2,7], [1,6], [0]],
}[case_num]

 

#Unique serial number NI digital I/O modules NI6501
serial_nr1 = 2742xxxx #Module 1 Hexadecimal number 1A28250
#find and assign the I/O modules to the correct Dev_numbers
system = nidaqmx.system.System.local()
a = system.driver_version
print(a)
print('')

 

device_dict = {} #empty dictionary for devices that are going to be found

for device in system.devices:
print(device.name)
print('Device Name: {0}, Product Category: {1}, Product Type: {2} Serial Number: {3}'.format(
device.name, device.product_category, device.product_type, device.dev_serial_num))
print('')
if device.dev_serial_num == serial_nr1:
device_dict['module1'] = device
print('I/O Module 1 with serial nr {0} assigned as {1}'.format(serial_nr1, device_dict['module1'].name))
print('')

test_cases_user_input = input("Type the case numbers in this format. eg: 1,2,3 .... 17 \n")
test_cases_user_input = test_cases_user_input.split(',')
# For each test case, we print all the lines
for i in range(0,len(test_cases_user_input)):
case_num = int(test_cases_user_input[i])
lines_port = get_lines_forSpecificCase(case_num)
print(get_lines_forSpecificCase(case_num))

 

Regards,

Murak ALmuairki,

Message 4 of 7
(14,865 Views)

Hi,

I have a similar problem using digital output to control a stepper motor in python.

 

System:

Windows 7, Python 3.7, NI USB-6009

 

The code:

import nidaqmx
import time
from nidaqmx.constants import (
    LineGrouping)

with nidaqmx.Task() as task:
	task.do_channels.add_do_chan('Dev1/port1/line0:3')
	task.start()
	while True:
		task.write([8,0,0,0])
		time.sleep(.002)
		task.write([0,8,0,0])
		time.sleep(.002)
		task.write([0,0,8,0])
		time.sleep(.002)
		task.write([0,0,0,8])
		time.sleep(.002)

 When running the code, the stepper motor will vibrate (presumably meaning that the writing to digital output works), but it will not rotate like I want it to. Any suggestions to fix this problem?

 

For reference, here is a version of the code in matlab that works like it is supposed to on the same computer/system:

 

clear all
close all
clc
pt=2/100;

s=daq.createSession('ni')
%%
addDigitalChannel(s,'Dev1','Port1/Line0','OutputOnly');
addDigitalChannel(s,'Dev1','Port1/Line1','OutputOnly');
addDigitalChannel(s,'Dev1','Port1/Line2','OutputOnly');
addDigitalChannel(s,'Dev1','Port1/Line3','OutputOnly');

n=0
while(n<100)
outputSingleScan(s,[1 0 0 0]);
pause(pt)
outputSingleScan(s,[0 1 0 0]);
pause(pt)
outputSingleScan(s,[0 0 1 0]);
pause(pt)
outputSingleScan(s,[0 0 0 1]);
pause(pt)
n=n+1
str='loop'
end

clear all
close all

0 Kudos
Message 5 of 7
(14,712 Views)

Thank you, this was very helpful to me.  For your stepper you might want to try using 8,2,4,1 in the write statement.  You have to do the bit field yourself.:

 

import nidaqmx
import time
from nidaqmx.constants import (
    LineGrouping)

with nidaqmx.Task() as task:
	task.do_channels.add_do_chan('Dev1/port1/line0:3')
	task.start()
	while True:
		task.write([8])
		time.sleep(.002)
		task.write([4])
		time.sleep(.002)
		task.write([2])
		time.sleep(.002)
		task.write([1])
		time.sleep(.002)

 

0 Kudos
Message 6 of 7
(14,530 Views)

I have the same error message WITH the sowftware controlled version ... any ideas ?

 

the exact error message is:

 

1 Channel 1 Sample Write:
Traceback (most recent call last):
File "ao_voltage_sw_timed.py", line 8, in <module>
print(task.write(1.0))
File "C:\Users\od_19\AppData\Local\Programs\Python\Python38\lib\site-packages\nidaqmx-0.5.7-py3.8.egg\nidaqmx\task.py", line 1169, in write
channels_to_write = self.channels
File "C:\Users\od_19\AppData\Local\Programs\Python\Python38\lib\site-packages\nidaqmx-0.5.7-py3.8.egg\nidaqmx\task.py", line 167, in channels
return Channel._factory(
File "C:\Users\od_19\AppData\Local\Programs\Python\Python38\lib\site-packages\nidaqmx-0.5.7-py3.8.egg\nidaqmx\_task_modules\channels\channel.py", line 118, in _factory
check_for_error(error_code)
File "C:\Users\od_19\AppData\Local\Programs\Python\Python38\lib\site-packages\nidaqmx-0.5.7-py3.8.egg\nidaqmx\errors.py", line 127, in check_for_error
raise DaqError(error_buffer.value.decode("utf-8"), error_code)
nidaqmx.errors.DaqError: Requested value is not a supported value for this property. The property value may be invalid because it conflicts with another property.
Property: DAQmx_AO_Max
Requested Value: 10.0
Maximum Value: 5.0
Minimum Value: 0.0
Channel Name: Dev1/ao0

Task Name: _unnamedTask<0>

Status Code: -200077

0 Kudos
Message 7 of 7
(11,404 Views)