Digital I/O

cancel
Showing results for 
Search instead for 
Did you mean: 

Trouble with DIO !

Hello everyone !

I've just bought a NI-9401 for some stuff I'm working on. I'm using Python with this device and I'm having trouble. I spent the last 3 days searching everywhere online and I couldn't seem to find any answers (I'm fairly new to both Python and NI btw).

 

So here is the thing : I want to test the device by transfering some floats from a digital output to a digital input.

 

Here is my code so far :

 

import nidaqmx as ni
import numpy as np
import matplotlib.pyplot as plt
from nidaqmx.constants import (LineGrouping)

## Emission ##
fe = 44100
f = 440
T = 0.05
t = np.linspace(0, 0.05, fe*0.05)
sig_E = np.sin(f*2*np.pi*t)

plt.figure()
plt.subplot(211)
plt.plot(t, sig_E)
plt.title("Signal Emis")
plt.tight_layout()

with ni.Task() as task:
    task.do_channels.add_do_chan("cDAQ1Mod1/port0/line0", line_grouping=LineGrouping.CHAN_FOR_ALL_LINES)
    task.write(sig_E)

## Reception ##

with ni.Task() as task:
    task.di_channels.add_di_chan("cDAQ1Mod1/port0/line4", line_grouping=LineGrouping.CHAN_FOR_ALL_LINES)
    sig_R = task.read(number_of_samples_per_channel=len(t))
    plt.subplot(212)
    plt.plot(t,sig_R)
    plt.title("Signal Recu")
    plt.tight_layout()
    plt.show()

So it's 5 seconds of a sine at 440 Hz and I want to send it from the DO to the DI (linked with a cable). But the error message I get is that the "write" function can only send boolean samples and obviously I want to send floats.

 

So how can I send my sine through the digital output (and read it from the digital input)? What are the appropriate functions ?

 

Thank you in advance for your help.

Best regards.

0 Kudos
Message 1 of 6
(3,787 Views)

Digital = 2 values (on and off).  If you are using a single channel, then you need an analog input and output.  Or, you can convert your value into a 8 bit number and write to the entire port and read it back.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 2 of 6
(3,760 Views)

Wait, are you saying that this card (NI-9401) can only send and read boolean samples ???

Message 3 of 6
(3,757 Views)

@dommi wrote:

Wait, are you saying that this card (NI-9401) can only send and read boolean samples ???


That is the definition of "Digital".


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 4 of 6
(3,749 Views)

Thank you for your answers ! I still might be able to use this card. So now that I know that it can only send en recieve booleans, I tried to send à chirp, made of booleans values, from a DO to a DI. But I can't make it work. Here is my code so far : I create à square signal, with linear frequency modulation, from 220Hz to 2200 Hz, for about 0.02 second, with a sample rate of 40kHz. Then I convert the values of my signals into booleans,  whih should make it good for the DIO channels.

 

 

import nidaqmx as ni
import numpy as np
import matplotlib.pyplot as plt
from nidaqmx.constants import (LineGrouping)
from scipy import signal

## Generation ##
fe = 40000                                                                   # sample rate
T  = 0.02                                                                     # duration
t = np.linspace(0, T, int(fe*T))                                              # time vector
f1 = 220                                                                      # freq min
f2 = 10*f1                                                                    # freq max
f  = np.linspace(f1,f2,len(t))                                                # freq vector
sig_E = signal.square(f*2*np.pi*t)                                            # chirp

for i in range(0,len(sig_E)):
    if sig_E[i]>0:
        sig_E[i]=True
    else:
        sig_E[i]=False
sig_E = [bool(sig_E[i]) for i in range(len(sig_E))]                             # float2bool

plt.figure()
plt.subplot(211)
plt.plot(t, sig_E)
plt.title("Signal Emis")
plt.tight_layout()

## Emission ##
with ni.Task() as task:
    cho = task.do_channels.add_do_chan("cDAQ1Mod1/port0/line0", line_grouping=LineGrouping.CHAN_FOR_ALL_LINES)
    task.timing.cfg_samp_clk_timing(fe)
    print(task.timing.samp_clk_rate)
    task.write(sig_E, auto_start=True)

## Reception ##
with ni.Task() as task:
    chi = task.di_channels.add_di_chan("cDAQ1Mod1/port0/line4", line_grouping=LineGrouping.CHAN_FOR_ALL_LINES)
    task.timing.cfg_samp_clk_timing(fe)
    sig_R = task.read(number_of_samples_per_channel = len(sig_E))
    sig_R = [int(sig_R[i]) for i in range(len(sig_R))]                          # bool2int

plt.subplot(212)
plt.plot(t,sig_R)
plt.title("Signal Recu")
plt.tight_layout()

plt.show()

But It doesn't work. My plot shows the signal sent through the DO, but when it comes to the recieved signal by the DI, it's not what I've sent.

I read somewhere on the NI website that to be able to use both DI and DO, I need to use 2 ports. But When I try to create the DI channel by writting "port1/line4" (since I have "port0/line1" for the DO), I have an error message saying that this channel doesn't exist on this hardware. Weird because in the user manual, it's specified that I have to use 2 ports.

 

Thanks in advance for your answer !

 

0 Kudos
Message 5 of 6
(3,634 Views)

Thank you for your answers ! I still might be able to use this card. So now that I know that it can only send en recieve booleans, I tried to send à chirp, made of booleans values, from a DO to a DI. But I can't make it work. Here is my code so far : I create à square signal, with linear frequency modulation, from 220Hz to 2200 Hz, for about 0.02 second, with a sample rate of 40kHz. Then I convert the values of my signals into booleans,  whih should make it good for the DIO channels.

 

 

import nidaqmx as ni
import numpy as np
import matplotlib.pyplot as plt
from nidaqmx.constants import (LineGrouping)
from scipy import signal

## Generation ##
fe = 40000                                                                   # sample rate
T  = 0.02                                                                     # duration
t = np.linspace(0, T, int(fe*T))                                              # time vector
f1 = 220                                                                      # freq min
f2 = 10*f1                                                                    # freq max
f  = np.linspace(f1,f2,len(t))                                                # freq vector
sig_E = signal.square(f*2*np.pi*t)                                            # chirp

for i in range(0,len(sig_E)):
    if sig_E[i]>0:
        sig_E[i]=True
    else:
        sig_E[i]=False
sig_E = [bool(sig_E[i]) for i in range(len(sig_E))]                             # float2bool

plt.figure()
plt.subplot(211)
plt.plot(t, sig_E)
plt.title("Signal Emis")
plt.tight_layout()

## Emission ##
with ni.Task() as task:
    cho = task.do_channels.add_do_chan("cDAQ1Mod1/port0/line0", line_grouping=LineGrouping.CHAN_FOR_ALL_LINES)
    task.timing.cfg_samp_clk_timing(fe)
    print(task.timing.samp_clk_rate)
    task.write(sig_E, auto_start=True)

## Reception ##
with ni.Task() as task:
    chi = task.di_channels.add_di_chan("cDAQ1Mod1/port0/line4", line_grouping=LineGrouping.CHAN_FOR_ALL_LINES)
    task.timing.cfg_samp_clk_timing(fe)
    sig_R = task.read(number_of_samples_per_channel = len(sig_E))
    sig_R = [int(sig_R[i]) for i in range(len(sig_R))]                          # bool2int

plt.subplot(212)
plt.plot(t,sig_R)
plt.title("Signal Recu")
plt.tight_layout()

plt.show()

But It doesn't work. My plot shows the signal sent through the DO, but when it comes to the recieved signal by the DI, it's not what I've sent.

I read somewhere on the NI website that to be able to use both DI and DO, I need to use 2 ports. But When I try to create the DI channel by writting "port1/line4" (since I have "port0/line1" for the DO), I have an error message saying that this channel doesn't exist on this hardware. Weird because in the user manual, it's specified that I have to use 2 ports.

 

Thanks in advance for your answer !

 

0 Kudos
Message 6 of 6
(3,632 Views)