I want to simulate an encoder and I want to finely control distance and speed.
I have written a 4bit long pattern to the digital lines and I want to clock it out at some sample rate.
If my sample rate is too high I get an error while waiting for task done:
nidaqmx.errors.DaqError: Onboard device memory underflow. Because of system and/or bus-bandwidth limitations, the driver could not write data to the device fast enough to keep up with the device output rate.
Reduce your sample rate. If your data transfer method is interrupts, try using DMA or USB Bulk. You can also reduce the number of programs your computer is executing concurrently.
Task Name: tach_out2
I should be writting everything to the board ahead of start, but some how it seems the driver is leaving the data in memory to be fetched at start, any thoughts on how I can push the data down to onboard?
cpm = 48609
# __
#__| |__|
# __ _
#_| |__|
#1 0 2 3
#__ __
# |__| |
# __ _
#_| |__|
#2 3 1 0
fwd_bits = [0, 1, 3, 2]
rev_bits = [2, 3, 1, 0]
i=0
for i,d in enumerate(pattern):
do_task = mx.Task(f'tach_out{i}')
do_task.do_channels.add_do_chan(dev + "/port0")
do_task.timing.cfg_samp_clk_timing(d.speed * cpm, sample_mode=AcquisitionType.FINITE, samps_per_chan=d.distance * cpm)
do_task.out_stream.regen_mode = RegenerationMode.ALLOW_REGENERATION
do_task.out_stream.output_buf_size=len(fwd_bits)
do_task.out_stream.offset=0
print(do_task.out_stream.output_onbrd_buf_size)
do_task.write(rev_bits if d.rev else fwd_bits, auto_start=False)
time.sleep(.1)
do_task.start()
print(f"{d.speed}m/s, {d.distance}, {'rev' if d.rev else 'fdw'} {d.distance/d.speed}")
while not do_task.is_task_done():
print(do_task.out_stream.curr_write_pos/(d.distance * cpm))
time.sleep(.1)
do_task.stop()
do_task.close()