- Edited
Hi All,
I am trying to document and understand the behavior of the sampler and the zotino dac functions. The idea here is to be able to take data for long periods of time without errors. (Think of a clock operating for 1000 hours). We need to be able to measure, do something, measure etc. So the simplest version of this is change a voltage, measure with sampler and repeat. For now, sampling is turned off because just changing a voltage a few hundred times causes what appear to me to be random slack errors.
Relevant functions/classes simplified for readibility
`
from artiq.experiment import *
import numpy as np
from function_library2 import Sample_Set_Voltage
class Activation_Control(EnvExperiment):
"""Test Class"""
def build(self):
self.setattr_device("core")
@kernel
def run(self):
for i in range(400):
self.measure.take_data(actual_samples,0, voltage=V)
# delay(25*us)
#self.core.wait_until_mu(now_mu())
print('done')
`
In another folder called
`
class Sample_Set_Voltage(HasEnvironment):
"""Sample 4 channels and set voltages"""
def build(self):
self.delay= 100*us
self.setattr_device("core")
self.setattr_device("sampler0")
self.setattr_device("zotino0")
self.setattr_device("core_dma")
# self.zotino0.init()
# self.sampler0.init()
@kernel
def take_data(self,samples,channel,voltage):
self.core.reset()
self.zotino0.init()
self.sampler0.init()
self.core.break_realtime()
delay(self.delay)
# self.record()
#%% Prep Stuff
n_channels = 4
smp = [0.0]*n_channels
channel_names = channel_names = ["sampler0_chan5", "sampler0_chan6",
"sampler0_chan7", "sampler0_chan8"]
timestamps_mu = 'Time (Machine Units)'
for i in range(n_channels):
chan_data = np.full(samples, np.nan)
self.set_dataset(channel_names[i], chan_data, broadcast=True)
self.sampler0.set_gain_mu(7-i, 0)
tstamp_data_mu = np.full(samples,self.core.get_rtio_counter_mu())
self.set_dataset(timestamps_mu, tstamp_data_mu, broadcast=True)
#%% Take Data
pulses_handle = self.core_dma.get_handle("ramp")
self.core.break_realtime()
for n in range(samples):
self.zotino0.write_dac(channel, voltage)
# delay(5*us) #loops over number of samples do be taken
# self.sampler0.sample(smp) #runs sampler and saves to list
current_time = self.core.get_rtio_counter_mu()
for i in range(n_channels):
self.mutate_dataset(channel_names[i], n, smp[i])
self.mutate_dataset(timestamps_mu, n, current_time)
delay(self.delay)
# self.core.wait_until_mu(now_mu())
`

What is interesting here is that I am getting a sampler underflow error despite not calling the sampler
`
root:Terminating with exception (RTIOOverflow: RTIO underflow at 1031760933091536 mu, channel 0x000c:spi_sampler0_pgia, slack -18120712 mu)
Core Device Traceback:
Traceback (most recent call first):
File "libksupport/src/rtio_csr.rs", line 71, column 10, in (Rust function)
<unknown>
^
File "/home/grpartiq/ARTIQ/artiq-master/repository/Experiments/Activation_Control_v5.py", line 152, in ?? (RA=+0x160)
self.measure.take_data(samples=1,channel=0, voltage=0)
File "<artiq>/coredevice/spi2.py", line 228, in ... artiq.coredevice.spi2.SPIMaster.write<artiq.coredevice.spi2.SPIMaster>(...) (RA=+0x4c4)
rtio_output((self.channel << 8) | SPI_DATA_ADDR, data)
File "<artiq>/coredevice/sampler.py", line 98, in ... artiq.coredevice.sampler.Sampler.set_gain_mu<artiq.coredevice.sampler.Sampler>(...) (inlined)
self.bus_pgia.write(gains << 16)
File "/home/grpartiq/ARTIQ/artiq-master/repository/Experiments/function_library2.py", line 137, in ... function_library2.Sample_Set_Voltage.take_data<function_library2.Sample_Set_Voltage>(...) (inlined)
self.sampler0.set_gain_mu(7-i, 0)
artiq.coredevice.exceptions.RTIOOverflow(0): RTIO underflow at 1031760933091536 mu, channel 0x000c:spi_sampler0_pgia, slack -18120712 mu
End of Core Device Traceback
Traceback (most recent call last):
File "/nix/store/fcs9ly81kipbm1z012704kw01zbbfpfd-python3-3.12.9-env/lib/python3.12/site-packages/artiq/master/worker_impl.py", line 378, in main
exp_inst.run()
File "/nix/store/fcs9ly81kipbm1z012704kw01zbbfpfd-python3-3.12.9-env/lib/python3.12/site-packages/artiq/language/core.py", line 54, in run_on_core
return getattr(self, arg).run(run_on_core, ((self,) + k_args), k_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/nix/store/fcs9ly81kipbm1z012704kw01zbbfpfd-python3-3.12.9-env/lib/python3.12/site-packages/artiq/coredevice/core.py", line 177, in run
self._run_compiled(kernel_library, embedding_map, symbolizer, demangler)
File "/nix/store/fcs9ly81kipbm1z012704kw01zbbfpfd-python3-3.12.9-env/lib/python3.12/site-packages/artiq/coredevice/core.py", line 166, in run_compiled
self.comm.serve(embedding_map, symbolizer, demangler)
File "/nix/store/fcs9ly81kipbm1z012704kw01zbbfpfd-python3-3.12.9-env/lib/python3.12/site-packages/artiq/coredevice/comm_kernel.py", line 739, in serve
self.serve_exception(embedding_map, symbolizer, demangler)
File "/nix/store/fcs9ly81kipbm1z012704kw01zbbfpfd-python3-3.12.9-env/lib/python3.12/site-packages/artiq/coredevice/comm_kernel.py", line 721, in _serve_exception
raise python_exn
artiq.coredevice.exceptions.RTIOOverflow: RTIO underflow at 1031760933091536 mu, channel 0x000c:spi_sampler0_pgia, slack -18120712 mu
`
Note this error does NOT exist when running " for i in range(100):" or something suitably smaller. How can I extend this range out to millions of points if needed? I tried playing with different time delays and/or # self.core.wait_until_mu(now_mu()) . However, these commands made no difference, the controller just jumps into a bad spot and it seems like there is no way to predict it. The slack was good over several/many cycles before suddenly failing.