09-30-2020 07:21 PM
Hi,
I am trying to run the multiple analog outputs and inputs simultaneously using the following python codes. But it looks that the reader is delayed and show error with "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_StartTrig_Type
Requested Value: DAQmx_Val_AnlgEdge
Possible Values: DAQmx_Val_DigEdge, DAQmx_Val_None
Task Name: _unnamedTask<1>
Status Code: -200077"
I believe there is something wrong with trigger, but haven't found a solution yet.
Help is much appreciated,
With kind regards,
Ho
import nidaqmx
import numpy as np
import matplotlib.pyplot as plt
import time
from nidaqmx import constants
from nidaqmx.constants import Edge, Slope
from nidaqmx.stream_readers import AnalogMultiChannelReader
from nidaqmx.stream_writers import AnalogMultiChannelWriter
from nidaqmx.stream_readers import AnalogSingleChannelReader
outputX=np.linspace(10,-10,25000)
outputY=np.linspace(5,-10,25000)
X=np.zeros(25000)
outputData = np.append(outputX,outputY)
outputData=np.append(outputData,outputY)
outputData = outputData.reshape((3,len(outputX)))
inputData=np.zeros(25000*3)
inputData = inputData.reshape((3,25000))
#outputData = np.transpose(outputData)
print(outputData.shape)
print(inputData.shape)
#ao_chan_x=t1.ao_channels.add_ao_voltage_chan("cDAQ1Mod1/ao0")
#ao_chan_y=t1.ao_channels.add_ao_voltage_chan("cDAQ1Mod1/ao1")
#outputChannels = ao_chan_x + "," + ao_chan_y
writingrate1=25000
#while True:
with nidaqmx.Task() as writeTask, nidaqmx.Task() as readTask:
writeTask.ao_channels.add_ao_voltage_chan('cDAQ1Mod1/ao0:2')
readTask.ai_channels.add_ai_voltage_chan('cDAQ1Mod4/ai0:2')
writeTask.timing.cfg_samp_clk_timing(rate=writingrate1,
#source='/cDAQ1/ai/SampleClock',
sample_mode=nidaqmx.constants.AcquisitionType.FINITE, # dont use continuous
samps_per_chan=X.size)
readTask.timing.cfg_samp_clk_timing(rate=writingrate1,
#source='/cDAQ1/ao/SampleClock',
active_edge=nidaqmx.constants.Edge.RISING,
sample_mode=nidaqmx.constants.AcquisitionType.FINITE,
samps_per_chan=X.size)
writeTask.triggers.start_trigger.cfg_anlg_edge_start_trig( trigger_source='/cDAQ1/ai/StartTrigger', trigger_slope=Slope.RISING) # Setting the trigger on the analog input
reader = AnalogMultiChannelReader(readTask.in_stream)
writer = AnalogMultiChannelWriter(writeTask.out_stream)
print("The channels linked to WriteTask are: ")
for i in writeTask.ao_channels:
print(i)
writer.write_many_sample(outputData)
writeTask.start()
reader.read_many_sample(inputData)
#reader.read_many_sample(inputData)
#readTask.start()
#writeTask.start()
writeTask.wait_until_done()
readTask.wait_until_done()
#readTask.start()
print("Done with data")
#print(inputData)
#x=np.linspace(0,25000,25000)
plt.plot(inputData[0])
plt.show()
10-01-2020 11:47 AM
Many devices don't support analog triggering for AI tasks. I don't know of ANY that support analog triggering for AO tasks, not directly at least.
I don't know the Python API into DAQmx, but I can offer up a few ideas.
- see this thread where I helped talk through an *indirect* method to provide analog triggering for AO. All the code parts are LabVIEW though.
- if some kind of analog start condition is a key to this app, you need to (try to) configure the AI task for analog triggering
- the timing config looks a little confused with the read and write tasks configured to use each other's sample clocks. This strikes me as a circular definition where both tasks will get stuck waiting for the other to generate its sample clock, but neither one can because they're both stuck waiting for the other task to start.
- similarly, the internal signal '/cDAQ1/ai/StartTrigger' is a digital trigger signal *result* that asserts when the ai task's start trigger criteria are satisfied. It isn't available for analog triggering evaluation. Plus, the AO task can't (directly) use an analog trigger anyway.
It *would* be feasible to configure that signal as a *digital* start trigger for the AO task. But you'll also have to resolve the circularly defined timing config.
- finally, since you seem to want AI and AO to sample at the same rate and start at the same time, there's a simpler overall approach.
-Kevin P
10-01-2020 05:15 PM
import nidaqmx
import numpy as np
import matplotlib.pyplot as plt
import time
from nidaqmx import constants
from nidaqmx.constants import Edge, Slope
from nidaqmx.stream_readers import AnalogMultiChannelReader
from nidaqmx.stream_writers import AnalogMultiChannelWriter
from nidaqmx.stream_readers import AnalogSingleChannelReader
outputX=np.linspace(10,-10,25000)
outputY=np.linspace(5,-10,25000)
X=np.zeros(25000)
outputData = np.append(outputX,outputY)
outputData=np.append(outputData,outputY)
outputData = outputData.reshape((3,len(outputX)))
inputData=np.zeros(25000*3)
inputData = inputData.reshape((3,25000))
#outputData = np.transpose(outputData)
print(outputData.shape)
print(inputData.shape)
#ao_chan_x=t1.ao_channels.add_ao_voltage_chan("cDAQ1Mod1/ao0")
#ao_chan_y=t1.ao_channels.add_ao_voltage_chan("cDAQ1Mod1/ao1")
#outputChannels = ao_chan_x + "," + ao_chan_y
writingrate1=25000
#while True:
with nidaqmx.Task() as writeTask, nidaqmx.Task() as readTask:
writeTask.ao_channels.add_ao_voltage_chan('cDAQ1Mod1/ao0:2')
readTask.ai_channels.add_ai_voltage_chan('cDAQ1Mod4/ai0:2')
writeTask.timing.cfg_samp_clk_timing(rate=writingrate1,
#source='/cDAQ1/ai/SampleClock',
sample_mode=nidaqmx.constants.AcquisitionType.FINITE, # dont use continuous
samps_per_chan=X.size)
readTask.timing.cfg_samp_clk_timing(rate=writingrate1,
#source='/cDAQ1/ao/SampleClock',
active_edge=nidaqmx.constants.Edge.RISING,
sample_mode=nidaqmx.constants.AcquisitionType.FINITE,
samps_per_chan=X.size)
#readTask.triggers.start_trigger.cfg_anlg_edge_start_trig(trigger_source='Voltage')
writeTask.triggers.start_trigger.cfg_dig_edge_start_trig( trigger_source='/cDAQ1/ai/StartTrigger') # Setting the trigger on the analog input
reader = AnalogMultiChannelReader(readTask.in_stream)
writer = AnalogMultiChannelWriter(writeTask.out_stream)
print("The channels linked to WriteTask are: ")
for i in writeTask.ao_channels:
print(i)
writer.write_many_sample(outputData)
writeTask.start()
readTask.start()
reader.read_many_sample(inputData)
#reader.read_many_sample(inputData)
#readTask.start()
#writeTask.start()
writeTask.wait_until_done()
readTask.wait_until_done()
#readTask.start()
print("Done with data")
#print(inputData)
#x=np.linspace(0,25000,25000)
plt.plot(inputData[0])
plt.show()
Hi Kevin,
Thanks a lot for your prompt reply.
I do can run the codes without any error following your valuable suggestions. However, when I directly connected the ai and ao channels, the reading data from ai doesn't match the writing data in ao. With NImx software, I can get the reading and writing simultaneously. I believe there is still some delay between reading and writing. Now I am using NI9264 (ao) and NI9205 (ai) incorporated in NI cDAQ9174. You are right that the ai has analog triggering while ao doesn't.
for the analog triggering of ai, i use the code:
readTask.triggers.start_trigger.cfg_anlg_edge_start_trig(trigger_source='Voltage')
and it gives me an error:nidaqmx.errors.DaqError:
An attempt has been made to use an invalid analog trigger source.
Ensure that the trigger source you specify matches the name of the virtual channel in the task or matches the name of a non-scannable terminal that the device can use as an analog trigger source.
Property: DAQmx_AnlgEdge_StartTrig_Src
Corresponding Value: Voltage
Valid Choices: cDAQ1Mod4/ai0
Device: cDAQ1
Task Name: _unnamedTask<1>
Status Code: -200265
Here is the triggering setting of ai:
and here is the ao
And I believe ai and ao use the same sample clock which I don't need to set it up manually, isn't it?
Thanks!
Ho
10-05-2020 07:14 AM
The trigger error message is telling you that you need to identify a physical AI channel on the device as the analog trigger source, namely "cDAQ1Mod4/ai0"
AO and AI don't quite exactly use the same sample clock, but they both derive their sample clocks from a common master timebase. To share the same sample clock you should UN-comment the part of the timing config for the AO task where it used to designate:
source='/cDAQ1/ai/SampleClock'
One difference is that the AI task's sample clock signal won't start pulsing until after the AI task has started acquisition. In this case, that won't be until after the analog triggering conditions have been met. When you configure this way, you won't need the AO task to be triggered any more. The shared sample clock alone will accomplish the same thing timing-wise.
-Kevin P