Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

python nidaqmx stream_writers nidaqmx.errors.DaqError: Attempted to write a sample beyond the final sample generated.

 

I am using a NI DAQ 6341 to control an RFIC and assist with analog calibration of on-chip components. I am programming in Python -- I'm new to Python and NI hardware, and a hardware engineer, so there's been quite a bit of a learning curve. (I'm not using labVIEW -- it didn't look any easier to implement than this). 

NI-Max version 16.0

 

 

One of the requirements is to load the firmware via an SPI-like interface to the RFIC digital inputs. I've done this by loading a 9-column csv file, mapping the csv to bit positions for Port0, saved as an np array, and then stream out digital data via Port0.

 

The script runs fine, but the problem is that it takes a long time to write the 130k samples (about 10 min). 

 

Previously I had encountered errors as well with sending too much data to stream_writer, and the extra data would just be truncated. So I am breaking the samples into smaller segments.

 

To try to make it run faster, I have tried to use the hardware buffer and 500 kS/s sample rate on the GPIO and use (by uncommenting from the code below) 

  task.timing.cfg_samp_clk_timing(500000)

However this results in an error, where it seems the first chunk of data (960 samples) writes but an error occurs on the next segment. (Ignore the 0 to 960 -- it's the python array indexes and sample[960] doesn't get written the first pass).

 

DOChannel(name=Dev1/port0/line7...)
Writing data from 0 to 960
Writing data from 960 to 1920
Traceback (most recent call last):
File "<stdin>", line 14, in <module>
File "C:\Users\Rodney\AppData\Local\Programs\Python\Python36-32\lib\site-packages\nidaqmx\stream_writers.py", line 1237, in write_many_sample_port_uint32
self._handle, data, data.shape[1], auto_start, timeout)
File "C:\Users\Rodney\AppData\Local\Programs\Python\Python36-32\lib\site-packages\nidaqmx\_task_modules\write_functions.py", line 187, in _write_digital_u_32
check_for_error(error_code)
File "C:\Users\Rodney\AppData\Local\Programs\Python\Python36-32\lib\site-packages\nidaqmx\errors.py", line 123, in check_for_error
raise DaqError(error_buffer.value.decode("utf-8"), error_code)
nidaqmx.errors.DaqError: Attempted to write a sample beyond the final sample generated. The generation has stopped, therefore the sample specified by the combination of position and offset will never be available.

Specify a position and offset which selects a sample up to, but not beyond, the final sample generated. The final sample generated can be determined by querying the total samples generated after a generation has stopped.
Attempted to Write Sample: 1920
Property: DAQmx_Write_RelativeTo
Corresponding Value: DAQmx_Val_CurrWritePos
Property: DAQmx_Write_Offset
Corresponding Value: 0

Task Name: _unnamedTask<58F>

Status Code: -200288

 

I'm not sure how to fix this error --- presumably by setting some property for the task? (Setting properties has been confusing in general for me).

 

Also, Is it possible to simply send the original large array, and have the stream_writer write as much as the HW buffer can hold, reload the buffer, and continue until the end?

 

It also seems that I could only set the hardware buffer to 500 kS/s, irrespectively of the value in the cfg_samp_clk_timing.

 

Here's the relevant parts of the script:

Load csv:

###########################################################################
# Import python libs
###########################################################################
import math
import numpy as np
import nidaqmx.system
from nidaqmx.constants import LineGrouping
import nidaqmx.stream_writers
import datetime
import time
sim_data = np.genfromtxt('./data/ctrl_data_20170731_board2_001_scan_high.csv',delimiter=',') data_length = math.floor(getattr(sim_data,'size') / 9) data_out = np.ndarray( shape=(1,data_length), dtype="uint32" ) for load_step in range(0, data_length): bus_val = sim_data[load_step][0]* 32*core1_ena + \ sim_data[load_step][0]* 16*core0_ena + \ sim_data[load_step][1]*128*core1_ena + \ sim_data[load_step][1]* 64*core0_ena + \ sim_data[load_step][4]* 4 + \ sim_data[load_step][3]* 8 + \ sim_data[load_step][2]* 2*core1_ena + \ sim_data[load_step][2]* 1*core0_ena data_out[0][load_step] = bus_val

 

 Stream out data:

############################################################################
# Write data to port0 buffer with 500 kS/s rate
############################################################################

data_size = 960
num_bursts = math.ceil(data_length/data_size)
data_start = 0
samples_written = 0
samples_burst = 0

tstart=time.clock()
with nidaqmx.Task() as task:
  task.do_channels.add_do_chan(    "Dev1/port0/line7:0", line_grouping=LineGrouping.CHAN_FOR_ALL_LINES)
  # use following line for high speed write
  task.timing.cfg_samp_clk_timing(500000)
  my_stream = nidaqmx._task_modules.out_stream.OutStream(task)
  #my_stream.output_buf_size = 203000
  my_multi_channel_do_writer = nidaqmx.stream_writers.DigitalMultiChannelWriter(my_stream, auto_start=True)
  for burst_step in range(0, num_bursts):
    data_stop = min(data_length, data_start+data_size)
    data_size_actual = data_stop - data_start
    data_burst =  np.ndarray( shape=(1,data_size_actual), dtype="uint32" )
    data_burst[0][0:data_size_actual] = data_out[0][data_start:data_stop]
    print( 'Writing data from ' + str(data_start) + ' to ' + str(data_stop))
    samples_burst = my_multi_channel_do_writer.write_many_sample_port_uint32( data_burst, timeout=600.0 )
    time.sleep(0.1)
    data_start = data_start + data_size
    samples_written = samples_written + samples_burst

tstop=time.clock()
print( 'Loading took ' + str(tstop-tstart) + ' seconds.'  )

0 Kudos
Message 1 of 4
(5,461 Views)

This is the LabVIEW board, so I don't understand what you hope to achieve by posting Python.

 

https://forums.ni.com/t5/Multifunction-DAQ/bd-p/250   is where you need to post.

 

 

0 Kudos
Message 2 of 4
(5,442 Views)

I just used the same forum that had similar questions to mine, from search results.

 

I've asked a moderator to move the post.

 

Thanks.

0 Kudos
Message 3 of 4
(5,436 Views)

NI hardware works easiest with NI software.

There tend to be examples around for you to look at.

 

Since you have decided to go on your own path with Python,

I would suggest looking at the VB.NET examples which would have installed if you have VB.NET installed.  You should be able to do a custom re-install of NI-DAQmx and have it install the examples.

 

 

 

0 Kudos
Message 4 of 4
(5,424 Views)